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:
@@ -74,12 +74,12 @@ QmlInspectorAgent::QmlInspectorAgent(QmlEngine *engine, QmlDebugConnection *conn
|
||||
, m_engineClient(0)
|
||||
, m_engineQueryId(0)
|
||||
, m_rootContextQueryId(0)
|
||||
, m_objectToSelect(WatchData::InvalidId)
|
||||
, m_objectToSelect(WatchItem::InvalidId)
|
||||
, m_masterEngine(engine)
|
||||
, m_toolsClient(0)
|
||||
, m_targetToSync(NoTarget)
|
||||
, m_debugIdToSelect(WatchData::InvalidId)
|
||||
, m_currentSelectedDebugId(WatchData::InvalidId)
|
||||
, m_debugIdToSelect(WatchItem::InvalidId)
|
||||
, m_currentSelectedDebugId(WatchItem::InvalidId)
|
||||
, m_toolsClientConnected(false)
|
||||
, m_inspectorToolsContext("Debugger.QmlInspector")
|
||||
, m_selectAction(new QAction(this))
|
||||
@@ -87,7 +87,7 @@ QmlInspectorAgent::QmlInspectorAgent(QmlEngine *engine, QmlDebugConnection *conn
|
||||
, m_showAppOnTopAction(action(ShowAppOnTop))
|
||||
, m_engineClientConnected(false)
|
||||
{
|
||||
m_debugIdToIname.insert(WatchData::InvalidId, QByteArray("inspect"));
|
||||
m_debugIdToIname.insert(WatchItem::InvalidId, QByteArray("inspect"));
|
||||
connect(action(ShowQmlObjectTree),
|
||||
&Utils::SavedAction::valueChanged, this, &QmlInspectorAgent::updateState);
|
||||
m_delayQueryTimer.setSingleShot(true);
|
||||
@@ -173,13 +173,13 @@ quint32 QmlInspectorAgent::queryExpressionResult(int debugId,
|
||||
m_engine.debugId());
|
||||
}
|
||||
|
||||
void QmlInspectorAgent::assignValue(const WatchData *data,
|
||||
void QmlInspectorAgent::assignValue(const WatchItem *data,
|
||||
const QString &expr, const QVariant &valueV)
|
||||
{
|
||||
qCDebug(qmlInspectorLog)
|
||||
<< __FUNCTION__ << '(' << data->id << ')' << data->iname;
|
||||
|
||||
if (data->id != WatchData::InvalidId) {
|
||||
if (data->id != WatchItem::InvalidId) {
|
||||
QString val(valueV.toString());
|
||||
if (valueV.type() == QVariant::String) {
|
||||
val = val.replace(QLatin1Char('\"'), QLatin1String("\\\""));
|
||||
@@ -195,17 +195,17 @@ static int parentIdForIname(const QByteArray &iname)
|
||||
// Extract the parent id
|
||||
int lastIndex = iname.lastIndexOf('.');
|
||||
int secondLastIndex = iname.lastIndexOf('.', lastIndex - 1);
|
||||
int parentId = WatchData::InvalidId;
|
||||
if (secondLastIndex != WatchData::InvalidId)
|
||||
int parentId = WatchItem::InvalidId;
|
||||
if (secondLastIndex != WatchItem::InvalidId)
|
||||
parentId = iname.mid(secondLastIndex + 1, lastIndex - secondLastIndex - 1).toInt();
|
||||
return parentId;
|
||||
}
|
||||
|
||||
void QmlInspectorAgent::updateWatchData(const WatchData &data)
|
||||
void QmlInspectorAgent::updateWatchData(const WatchItem &data)
|
||||
{
|
||||
qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << data.id << ')';
|
||||
|
||||
if (data.id != WatchData::InvalidId && !m_fetchDataIds.contains(data.id)) {
|
||||
if (data.id != WatchItem::InvalidId && !m_fetchDataIds.contains(data.id)) {
|
||||
// objects
|
||||
m_fetchDataIds << data.id;
|
||||
fetchObject(data.id);
|
||||
@@ -216,7 +216,7 @@ void QmlInspectorAgent::watchDataSelected(qint64 id)
|
||||
{
|
||||
qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << id << ')';
|
||||
|
||||
if (id != WatchData::InvalidId) {
|
||||
if (id != WatchItem::InvalidId) {
|
||||
QTC_ASSERT(m_debugIdLocations.keys().contains(id), return);
|
||||
jumpToObjectDefinitionInEditor(m_debugIdLocations.value(id), id);
|
||||
if (m_toolsClient)
|
||||
@@ -278,7 +278,7 @@ ObjectReference QmlInspectorAgent::objectForId(int objectDebugId) const
|
||||
}
|
||||
}
|
||||
// TODO: Set correct parentId
|
||||
return ObjectReference(objectDebugId, WatchData::InvalidId,
|
||||
return ObjectReference(objectDebugId, WatchItem::InvalidId,
|
||||
FileReference(QUrl::fromLocalFile(file), line, column));
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ void QmlInspectorAgent::addObjectWatch(int objectDebugId)
|
||||
{
|
||||
qCDebug(qmlInspectorLog) << __FUNCTION__ << '(' << objectDebugId << ')';
|
||||
|
||||
if (objectDebugId == WatchData::InvalidId)
|
||||
if (objectDebugId == WatchItem::InvalidId)
|
||||
return;
|
||||
|
||||
if (!isConnected() || !boolSetting(ShowQmlObjectTree))
|
||||
@@ -470,7 +470,7 @@ void QmlInspectorAgent::verifyAndInsertObjectInTree(const ObjectReference &objec
|
||||
|
||||
// Find out the correct position in the tree
|
||||
// Objects are inserted to the tree if they satisfy one of the two conditions.
|
||||
// Condition 1: Object is a root object i.e. parentId == WatchData::InvalidId.
|
||||
// Condition 1: Object is a root object i.e. parentId == WatchItem::InvalidId.
|
||||
// Condition 2: Object has an expanded parent i.e. siblings are known.
|
||||
// If the two conditions are not met then we push the object to a stack and recursively
|
||||
// fetch parents till we find a previously expanded parent.
|
||||
@@ -480,7 +480,7 @@ void QmlInspectorAgent::verifyAndInsertObjectInTree(const ObjectReference &objec
|
||||
const int objectDebugId = object.debugId();
|
||||
if (m_debugIdToIname.contains(parentId)) {
|
||||
QByteArray parentIname = m_debugIdToIname.value(parentId);
|
||||
if (parentId != WatchData::InvalidId && !handler->isExpandedIName(parentIname)) {
|
||||
if (parentId != WatchItem::InvalidId && !handler->isExpandedIName(parentIname)) {
|
||||
m_objectStack.push(object);
|
||||
handler->fetchMore(parentIname);
|
||||
return; // recursive
|
||||
@@ -535,7 +535,7 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
|
||||
<< timeElapsed.elapsed() << " ms";
|
||||
|
||||
if (object.debugId() == m_debugIdToSelect) {
|
||||
m_debugIdToSelect = WatchData::InvalidId;
|
||||
m_debugIdToSelect = WatchItem::InvalidId;
|
||||
selectObject(object, m_targetToSync);
|
||||
}
|
||||
|
||||
@@ -544,7 +544,7 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object)
|
||||
QByteArray iname = m_debugIdToIname.value(m_objectToSelect);
|
||||
qCDebug(qmlInspectorLog) << " selecting" << iname << "in tree";
|
||||
m_qmlEngine->watchHandler()->setCurrentItem(iname);
|
||||
m_objectToSelect = WatchData::InvalidId;
|
||||
m_objectToSelect = WatchItem::InvalidId;
|
||||
}
|
||||
m_qmlEngine->watchHandler()->updateWatchersWindow();
|
||||
m_qmlEngine->watchHandler()->reexpandItems();
|
||||
@@ -613,7 +613,9 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj,
|
||||
return;
|
||||
|
||||
// object
|
||||
auto objWatch = new WatchItem(objIname, name);
|
||||
auto objWatch = new WatchItem;
|
||||
objWatch->iname = objIname;
|
||||
objWatch->name = name;
|
||||
objWatch->id = objDebugId;
|
||||
objWatch->exp = name.toLatin1();
|
||||
objWatch->type = obj.className().toLatin1();
|
||||
@@ -643,7 +645,9 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj,
|
||||
// properties
|
||||
if (append && obj.properties().count()) {
|
||||
QByteArray iname = objIname + ".[properties]";
|
||||
auto propertiesWatch = new WatchItem(iname, tr("Properties"));
|
||||
auto propertiesWatch = new WatchItem;
|
||||
propertiesWatch->iname = iname;
|
||||
propertiesWatch->name = tr("Properties");
|
||||
propertiesWatch->id = objDebugId;
|
||||
propertiesWatch->value = _("list");
|
||||
propertiesWatch->wantsChildren = true;
|
||||
@@ -653,7 +657,9 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj,
|
||||
const QString propertyName = property.name();
|
||||
if (propertyName.isEmpty())
|
||||
continue;
|
||||
auto propertyWatch = new WatchItem(buildIName(iname, propertyName), propertyName);
|
||||
auto propertyWatch = new WatchItem;
|
||||
propertyWatch->iname = buildIName(iname, propertyName);
|
||||
propertyWatch->name = propertyName;
|
||||
propertyWatch->id = objDebugId;
|
||||
propertyWatch->exp = propertyName.toLatin1();
|
||||
propertyWatch->type = property.valueTypeName().toLatin1();
|
||||
@@ -700,7 +706,7 @@ void QmlInspectorAgent::clearObjectTree()
|
||||
m_debugIdHash.clear();
|
||||
m_debugIdHash.reserve(old_count + 1);
|
||||
m_debugIdToIname.clear();
|
||||
m_debugIdToIname.insert(WatchData::InvalidId, QByteArray("inspect"));
|
||||
m_debugIdToIname.insert(WatchItem::InvalidId, QByteArray("inspect"));
|
||||
m_objectStack.clear();
|
||||
m_objectWatches.clear();
|
||||
}
|
||||
@@ -870,7 +876,7 @@ void QmlInspectorAgent::jumpToObjectDefinitionInEditor(
|
||||
const QString fileName = m_masterEngine->toFileInProject(objSource.url());
|
||||
|
||||
Core::EditorManager::openEditorAt(fileName, objSource.lineNumber());
|
||||
if (debugId != WatchData::InvalidId && debugId != m_currentSelectedDebugId) {
|
||||
if (debugId != WatchItem::InvalidId && debugId != m_currentSelectedDebugId) {
|
||||
m_currentSelectedDebugId = debugId;
|
||||
m_currentSelectedDebugName = displayName(debugId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user