forked from qt-creator/qt-creator
Debugger: Work on WatchModel performance
Don't instantiate repeating boilerplate item data in some cases (such as large arrays). This makes it necessary to access parent WatchItems in a lot more cases than before and needs another separation of WatchItem/WatchModel code to keep the dumper autotests in a functional state. For a plain std::vector<int> with 1 mio items this reduces extraction time from more than 2 minutes to about 3 seconds. Change-Id: I175c5f6ee90434a6e85342d8bb71bd10a04dd271 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com> Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
@@ -33,10 +33,11 @@
|
||||
|
||||
#include "debuggerprotocol.h"
|
||||
|
||||
#include <utils/treemodel.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QMetaType>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace Debugger {
|
||||
@@ -44,20 +45,35 @@ namespace Internal {
|
||||
|
||||
class GdbMi;
|
||||
|
||||
class WatchData
|
||||
class WatchItem : public Utils::TreeItem
|
||||
{
|
||||
public:
|
||||
WatchData();
|
||||
WatchItem();
|
||||
|
||||
void parse(const GdbMi &input);
|
||||
|
||||
bool isLocal() const;
|
||||
bool isWatcher() const;
|
||||
bool isInspect() const;
|
||||
|
||||
QString expression() const;
|
||||
QString realName() const;
|
||||
quint64 realAddress() const;
|
||||
QByteArray internalName() const;
|
||||
QString toToolTip() const;
|
||||
|
||||
QVariant editValue() const;
|
||||
int editType() const;
|
||||
|
||||
WatchItem *findItem(const QByteArray &iname);
|
||||
WatchItem *parentItem() const;
|
||||
|
||||
enum State
|
||||
{
|
||||
HasChildrenNeeded = 1,
|
||||
ValueNeeded = 2,
|
||||
ChildrenNeeded = 8,
|
||||
|
||||
InitialState = ValueNeeded
|
||||
| ChildrenNeeded
|
||||
| HasChildrenNeeded
|
||||
InitialState = ValueNeeded | ChildrenNeeded
|
||||
};
|
||||
|
||||
static const qint64 InvalidId = -1;
|
||||
@@ -73,20 +89,14 @@ public:
|
||||
void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); }
|
||||
void setHasChildren(bool c) { wantsChildren = c; if (!c) setChildrenUnneeded(); }
|
||||
|
||||
bool isLocal() const { return iname.startsWith("local."); }
|
||||
bool isWatcher() const { return iname.startsWith("watch."); }
|
||||
bool isInspect() const { return iname.startsWith("inspect."); }
|
||||
bool isValid() const { return !iname.isEmpty(); }
|
||||
bool isVTablePointer() const;
|
||||
|
||||
bool isAncestorOf(const QByteArray &childIName) const;
|
||||
|
||||
void setError(const QString &);
|
||||
void setValue(const QString &);
|
||||
void setType(const QByteArray &, bool guessChildrenFromType = true);
|
||||
|
||||
QString toString() const;
|
||||
QString toToolTip() const;
|
||||
|
||||
static QString msgNotInScope();
|
||||
static QString shadowedName(const QString &name, int seen);
|
||||
@@ -94,11 +104,6 @@ public:
|
||||
|
||||
QByteArray hexAddress() const;
|
||||
|
||||
// Protocol interaction.
|
||||
void updateValue(const GdbMi &item);
|
||||
void updateChildCount(const GdbMi &mi);
|
||||
void updateType(const GdbMi &item);
|
||||
|
||||
public:
|
||||
qint64 id; // Token for the engine for internal mapping
|
||||
qint32 state; // 'needed' flags;
|
||||
@@ -116,35 +121,18 @@ public:
|
||||
uint bitpos; // Position within bit fields
|
||||
uint bitsize; // Size in case of bit fields
|
||||
int elided; // Full size if value was cut off, -1 if cut on unknown size, 0 otherwise
|
||||
int arrayIndex; // -1 if not an array member
|
||||
bool wantsChildren;
|
||||
bool valueEnabled; // Value will be enabled or not
|
||||
bool valueEditable; // Value will be editable
|
||||
bool outdated; // \internal item is to be removed.
|
||||
|
||||
private:
|
||||
void parseHelper(const GdbMi &input);
|
||||
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchHandler)
|
||||
};
|
||||
|
||||
void decodeArrayData(std::function<void(const WatchData &)> itemHandler,
|
||||
const WatchData &tmplate,
|
||||
const QByteArray &rawData,
|
||||
const DebuggerEncoding &encoding);
|
||||
|
||||
void readNumericVector(std::vector<double> *,
|
||||
const QByteArray &rawData,
|
||||
const DebuggerEncoding &encoding);
|
||||
|
||||
void parseChildrenData(const WatchData &parent, const GdbMi &child,
|
||||
std::function<void(const WatchData &)> itemHandler,
|
||||
std::function<void(const WatchData &, const GdbMi &)> childHandler,
|
||||
std::function<void(const WatchData &, const QByteArray &, const DebuggerEncoding &)> arrayDecoder);
|
||||
|
||||
void parseWatchData(const WatchData &parent, const GdbMi &child,
|
||||
QList<WatchData> *insertions);
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
Q_DECLARE_METATYPE(Debugger::Internal::WatchData)
|
||||
|
||||
|
||||
#endif // DEBUGGER_WATCHDATA_H
|
||||
|
||||
Reference in New Issue
Block a user