forked from qt-creator/qt-creator
Cdb: Optimize dump of std container
Cache container member offsets. Task-number: QTCREATORBUG-16710 Change-Id: I47c471eae355e1f1220fe22ad1cdd0cb67d430a1 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -101,25 +101,22 @@ static inline std::string fixInnerType(const std::string &type,
|
||||
// Return size from an STL vector (last/first iterators).
|
||||
static inline int msvcStdVectorSize(const SymbolGroupValue &v)
|
||||
{
|
||||
// MSVC2012 has 2 base classes, MSVC2010 1, MSVC2008 none
|
||||
if (const SymbolGroupValue myFirstPtrV = SymbolGroupValue::findMember(v, "_Myfirst")) {
|
||||
if (const SymbolGroupValue myLastPtrV = myFirstPtrV.parent()["_Mylast"]) {
|
||||
const ULONG64 firstPtr = myFirstPtrV.pointerValue();
|
||||
const ULONG64 lastPtr = myLastPtrV.pointerValue();
|
||||
const ULONG64 firstPtr = v.readPointerValueFromAncestor("_Myfirst");
|
||||
const ULONG64 lastPtr = v.readPointerValueFromAncestor("_Mylast");
|
||||
if (!firstPtr || lastPtr < firstPtr)
|
||||
return -1;
|
||||
const std::vector<std::string> innerTypes = v.innerTypes();
|
||||
if (innerTypes.empty())
|
||||
return -1;
|
||||
const std::string innerType = fixInnerType(SymbolGroupValue::stripPointerType(innerTypes[0]), v);
|
||||
const size_t size = SymbolGroupValue::sizeOf(innerType.c_str());
|
||||
if (size == 0)
|
||||
return -1;
|
||||
if (lastPtr == firstPtr)
|
||||
return 0;
|
||||
// Subtract the pointers: We need to do the pointer arithmetics ourselves
|
||||
// as we get char *pointers.
|
||||
const std::string innerType = fixInnerType(SymbolGroupValue::stripPointerType(myFirstPtrV.type()), v);
|
||||
const size_t size = SymbolGroupValue::sizeOf(innerType.c_str());
|
||||
if (size == 0)
|
||||
return -1;
|
||||
return static_cast<int>((lastPtr - firstPtr) / size);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return size of container or -1
|
||||
@@ -193,10 +190,12 @@ int containerSize(KnownType kt, const SymbolGroupValue &v)
|
||||
case KT_StdMap:
|
||||
case KT_StdMultiMap:
|
||||
case KT_StdValArray:
|
||||
case KT_StdList:
|
||||
if (const SymbolGroupValue size = SymbolGroupValue::findMember(v, "_Mysize"))
|
||||
return size.intValue();
|
||||
case KT_StdList: {
|
||||
const int size = v.readIntegerFromAncestor("_Mysize");
|
||||
if (size >= 0)
|
||||
return size;
|
||||
break;
|
||||
}
|
||||
case KT_StdStack:
|
||||
if (const SymbolGroupValue deque = v[unsigned(0)])
|
||||
return containerSize(KT_StdDeque, deque);
|
||||
|
@@ -154,6 +154,15 @@ int SymbolGroupValue::readIntegerFromAncestor(const std::string &name, int defau
|
||||
return readPODFromAncestor<int>(name, defaultValue);
|
||||
}
|
||||
|
||||
ULONG64 SymbolGroupValue::offsetOfChild(const SymbolGroupValue &child) const
|
||||
{
|
||||
const ULONG64 base = isPointerType(type()) ? pointerValue() : address();
|
||||
const ULONG64 childAddress = child.address();
|
||||
if (base == 0 || childAddress == 0)
|
||||
return 0;
|
||||
return childAddress - base;
|
||||
}
|
||||
|
||||
LONG64 SymbolGroupValue::offsetOfAncestor(const std::string &name) const
|
||||
{
|
||||
return infoOfAncestor(name).offset;
|
||||
@@ -204,7 +213,7 @@ SymbolAncestorInfo SymbolGroupValue::infoOfAncestor(const std::string &name) con
|
||||
continue;
|
||||
info = child.infoOfAncestor(name);
|
||||
if (info.isValid()) {
|
||||
info.offset += offsetOfAncestor(child.name());
|
||||
info.offset += offsetOfChild(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -71,6 +71,7 @@ public:
|
||||
SymbolGroupValue operator[](const char *name) const;
|
||||
SymbolGroupValue operator[](unsigned) const;
|
||||
unsigned childCount() const;
|
||||
ULONG64 offsetOfChild(const SymbolGroupValue &child) const;
|
||||
SymbolGroupValue parent() const;
|
||||
// take address and cast to desired (pointer) type
|
||||
SymbolGroupValue typeCast(const char *type) const;
|
||||
|
Reference in New Issue
Block a user