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).
|
// 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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user