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:
David Schulz
2016-08-03 14:06:45 +02:00
parent a1876a8509
commit 3016c6c96f
3 changed files with 32 additions and 23 deletions

View File

@@ -101,25 +101,22 @@ static inline std::string fixInnerType(const std::string &type,
// Return size from an STL vector (last/first iterators). // Return size from an STL vector (last/first iterators).
static inline int msvcStdVectorSize(const SymbolGroupValue &v) static inline int msvcStdVectorSize(const SymbolGroupValue &v)
{ {
// MSVC2012 has 2 base classes, MSVC2010 1, MSVC2008 none const ULONG64 firstPtr = v.readPointerValueFromAncestor("_Myfirst");
if (const SymbolGroupValue myFirstPtrV = SymbolGroupValue::findMember(v, "_Myfirst")) { const ULONG64 lastPtr = v.readPointerValueFromAncestor("_Mylast");
if (const SymbolGroupValue myLastPtrV = myFirstPtrV.parent()["_Mylast"]) { if (!firstPtr || lastPtr < firstPtr)
const ULONG64 firstPtr = myFirstPtrV.pointerValue(); return -1;
const ULONG64 lastPtr = myLastPtrV.pointerValue(); const std::vector<std::string> innerTypes = v.innerTypes();
if (!firstPtr || lastPtr < firstPtr) if (innerTypes.empty())
return -1; return -1;
if (lastPtr == firstPtr) const std::string innerType = fixInnerType(SymbolGroupValue::stripPointerType(innerTypes[0]), v);
return 0; const size_t size = SymbolGroupValue::sizeOf(innerType.c_str());
// Subtract the pointers: We need to do the pointer arithmetics ourselves if (size == 0)
// as we get char *pointers. return -1;
const std::string innerType = fixInnerType(SymbolGroupValue::stripPointerType(myFirstPtrV.type()), v); if (lastPtr == firstPtr)
const size_t size = SymbolGroupValue::sizeOf(innerType.c_str()); return 0;
if (size == 0) // Subtract the pointers: We need to do the pointer arithmetics ourselves
return -1; // as we get char *pointers.
return static_cast<int>((lastPtr - firstPtr) / size); return static_cast<int>((lastPtr - firstPtr) / size);
}
}
return -1;
} }
// Return size of container or -1 // Return size of container or -1
@@ -193,10 +190,12 @@ int containerSize(KnownType kt, const SymbolGroupValue &v)
case KT_StdMap: case KT_StdMap:
case KT_StdMultiMap: case KT_StdMultiMap:
case KT_StdValArray: case KT_StdValArray:
case KT_StdList: case KT_StdList: {
if (const SymbolGroupValue size = SymbolGroupValue::findMember(v, "_Mysize")) const int size = v.readIntegerFromAncestor("_Mysize");
return size.intValue(); if (size >= 0)
return size;
break; break;
}
case KT_StdStack: case KT_StdStack:
if (const SymbolGroupValue deque = v[unsigned(0)]) if (const SymbolGroupValue deque = v[unsigned(0)])
return containerSize(KT_StdDeque, deque); return containerSize(KT_StdDeque, deque);

View File

@@ -154,6 +154,15 @@ int SymbolGroupValue::readIntegerFromAncestor(const std::string &name, int defau
return readPODFromAncestor<int>(name, defaultValue); 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 LONG64 SymbolGroupValue::offsetOfAncestor(const std::string &name) const
{ {
return infoOfAncestor(name).offset; return infoOfAncestor(name).offset;
@@ -204,7 +213,7 @@ SymbolAncestorInfo SymbolGroupValue::infoOfAncestor(const std::string &name) con
continue; continue;
info = child.infoOfAncestor(name); info = child.infoOfAncestor(name);
if (info.isValid()) { if (info.isValid()) {
info.offset += offsetOfAncestor(child.name()); info.offset += offsetOfChild(child);
break; break;
} }
} }

View File

@@ -71,6 +71,7 @@ public:
SymbolGroupValue operator[](const char *name) const; SymbolGroupValue operator[](const char *name) const;
SymbolGroupValue operator[](unsigned) const; SymbolGroupValue operator[](unsigned) const;
unsigned childCount() const; unsigned childCount() const;
ULONG64 offsetOfChild(const SymbolGroupValue &child) const;
SymbolGroupValue parent() const; SymbolGroupValue parent() const;
// take address and cast to desired (pointer) type // take address and cast to desired (pointer) type
SymbolGroupValue typeCast(const char *type) const; SymbolGroupValue typeCast(const char *type) const;