Debugger: Revert parts of the 'arrayIndex' optimization

The parent's address is not always the base address of the array
data, but often a wrapper like QVector, so the correct computation
of the item's address is more involved, removing the benefits of
the optimization.

Change-Id: Iecb19799addc1502649fefbad0953b77947f4193
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2016-06-03 15:58:19 +02:00
parent b50e9e546f
commit 023b78545f
2 changed files with 78 additions and 68 deletions

View File

@@ -325,8 +325,11 @@ QString decodeItemHelper(const double &t)
return QString::number(t, 'g', 16); return QString::number(t, 'g', 16);
} }
class ArrayDataDecoder
{
public:
template <class T> template <class T>
void decodeArrayHelper(WatchItem *item, const QByteArray &rawData, int size, const QByteArray &childType) void decodeArrayHelper(int childSize)
{ {
const QByteArray ba = QByteArray::fromHex(rawData); const QByteArray ba = QByteArray::fromHex(rawData);
const T *p = (const T *) ba.data(); const T *p = (const T *) ba.data();
@@ -334,46 +337,49 @@ void decodeArrayHelper(WatchItem *item, const QByteArray &rawData, int size, con
WatchItem *child = new WatchItem; WatchItem *child = new WatchItem;
child->arrayIndex = i; child->arrayIndex = i;
child->value = decodeItemHelper(p[i]); child->value = decodeItemHelper(p[i]);
child->size = size; child->size = childSize;
child->type = childType; child->type = childType;
child->address = addrbase + i * addrstep;
child->valueEditable = true;
child->setAllUnneeded(); child->setAllUnneeded();
item->appendChild(child); item->appendChild(child);
} }
} }
static void decodeArrayData(WatchItem *item, const QByteArray &rawData, void decode()
const DebuggerEncoding &encoding, const QByteArray &childType)
{ {
if (addrstep == 0)
addrstep = encoding.size;
switch (encoding.type) { switch (encoding.type) {
case DebuggerEncoding::HexEncodedSignedInteger: case DebuggerEncoding::HexEncodedSignedInteger:
switch (encoding.size) { switch (encoding.size) {
case 1: case 1:
return decodeArrayHelper<signed char>(item, rawData, encoding.size, childType); return decodeArrayHelper<signed char>(encoding.size);
case 2: case 2:
return decodeArrayHelper<short>(item, rawData, encoding.size, childType); return decodeArrayHelper<short>(encoding.size);
case 4: case 4:
return decodeArrayHelper<int>(item, rawData, encoding.size, childType); return decodeArrayHelper<int>(encoding.size);
case 8: case 8:
return decodeArrayHelper<qint64>(item, rawData, encoding.size, childType); return decodeArrayHelper<qint64>(encoding.size);
} }
case DebuggerEncoding::HexEncodedUnsignedInteger: case DebuggerEncoding::HexEncodedUnsignedInteger:
switch (encoding.size) { switch (encoding.size) {
case 1: case 1:
return decodeArrayHelper<uchar>(item, rawData, encoding.size, childType); return decodeArrayHelper<uchar>(encoding.size);
case 2: case 2:
return decodeArrayHelper<ushort>(item, rawData, encoding.size, childType); return decodeArrayHelper<ushort>(encoding.size);
case 4: case 4:
return decodeArrayHelper<uint>(item, rawData, encoding.size, childType); return decodeArrayHelper<uint>(encoding.size);
case 8: case 8:
return decodeArrayHelper<quint64>(item, rawData, encoding.size, childType); return decodeArrayHelper<quint64>(encoding.size);
} }
break; break;
case DebuggerEncoding::HexEncodedFloat: case DebuggerEncoding::HexEncodedFloat:
switch (encoding.size) { switch (encoding.size) {
case 4: case 4:
return decodeArrayHelper<float>(item, rawData, encoding.size, childType); return decodeArrayHelper<float>(encoding.size);
case 8: case 8:
return decodeArrayHelper<double>(item, rawData, encoding.size, childType); return decodeArrayHelper<double>(encoding.size);
} }
default: default:
break; break;
@@ -381,6 +387,14 @@ static void decodeArrayData(WatchItem *item, const QByteArray &rawData,
qDebug() << "ENCODING ERROR: " << encoding.toString(); qDebug() << "ENCODING ERROR: " << encoding.toString();
} }
WatchItem *item;
QByteArray rawData;
QByteArray childType;
DebuggerEncoding encoding;
quint64 addrbase;
quint64 addrstep;
};
static bool sortByName(const Utils::TreeItem *a, const Utils::TreeItem *b) static bool sortByName(const Utils::TreeItem *a, const Utils::TreeItem *b)
{ {
auto aa = static_cast<const WatchItem *>(a); auto aa = static_cast<const WatchItem *>(a);
@@ -474,9 +488,14 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
mi = input["arraydata"]; mi = input["arraydata"];
if (mi.isValid()) { if (mi.isValid()) {
DebuggerEncoding encoding(input["arrayencoding"].data()); ArrayDataDecoder decoder;
QByteArray childType = input["childtype"].data(); decoder.item = this;
decodeArrayData(this, mi.data(), encoding, childType); decoder.rawData = mi.data();
decoder.childType = input["childtype"].data();
decoder.addrbase = input["addrbase"].toAddress();
decoder.addrstep = input["addrstep"].toAddress();
decoder.encoding = DebuggerEncoding(input["arrayencoding"].data());
decoder.decode();
} else { } else {
const GdbMi children = input["children"]; const GdbMi children = input["children"];
if (children.isValid()) { if (children.isValid()) {
@@ -511,7 +530,8 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
child->iname = this->iname + '.' + nn; child->iname = this->iname + '.' + nn;
if (addressStep) { if (addressStep) {
child->address = addressBase + i * addressStep; child->address = addressBase + i * addressStep;
child->exp = "*(" + gdbQuoteTypes(child->type) + "*)" + child->hexAddress(); child->exp = "*(" + gdbQuoteTypes(child->type) + "*)0x"
+ QByteArray::number(child->address, 16);
} }
QByteArray key = subinput["key"].data(); QByteArray key = subinput["key"].data();
if (!key.isEmpty()) if (!key.isEmpty())
@@ -582,8 +602,8 @@ QString WatchItem::toToolTip() const
} }
formatToolTipRow(str, tr("Value"), val); formatToolTipRow(str, tr("Value"), val);
} }
if (realAddress()) if (address)
formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(realAddress())); formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(address));
if (origaddr) if (origaddr)
formatToolTipRow(str, tr("Pointer Address"), formatToolTipAddress(origaddr)); formatToolTipRow(str, tr("Pointer Address"), formatToolTipAddress(origaddr));
if (arrayIndex >= 0) if (arrayIndex >= 0)
@@ -619,15 +639,6 @@ bool WatchItem::isInspect() const
return iname.startsWith("inspect."); return iname.startsWith("inspect.");
} }
quint64 WatchItem::realAddress() const
{
if (arrayIndex >= 0) {
if (const WatchItem *p = parentItem())
return p->address + arrayIndex * size;
}
return address;
}
QByteArray WatchItem::internalName() const QByteArray WatchItem::internalName() const
{ {
if (arrayIndex >= 0) { if (arrayIndex >= 0) {
@@ -648,7 +659,7 @@ QString WatchItem::expression() const
{ {
if (!exp.isEmpty()) if (!exp.isEmpty())
return QString::fromLatin1(exp); return QString::fromLatin1(exp);
if (quint64 addr = realAddress()) { if (quint64 addr = address) {
if (!type.isEmpty()) if (!type.isEmpty())
return QString::fromLatin1("*(%1*)0x%2").arg(QLatin1String(type)).arg(addr, 0, 16); return QString::fromLatin1("*(%1*)0x%2").arg(QLatin1String(type)).arg(addr, 0, 16);
} }

View File

@@ -53,7 +53,6 @@ public:
QString expression() const; QString expression() const;
QString realName() const; QString realName() const;
quint64 realAddress() const;
QByteArray internalName() const; QByteArray internalName() const;
QString toToolTip() const; QString toToolTip() const;