diff options
author | hjk <hjk@theqtcompany.com> | 2015-07-06 09:46:08 +0200 |
---|---|---|
committer | hjk <hjk@theqtcompany.com> | 2015-07-07 08:08:08 +0000 |
commit | d48ac14fba52d4f4eac0b73c07b59ef56c50b259 (patch) | |
tree | eaab28eb1dc175bf542dc7f21d82de072e2849cb | |
parent | 1587c171d6c2929d15e4626b4fead0ac070314f7 (diff) |
Debugger: Simplify removal of outdated L&E items
This removes the need of bookkeeping on the engine side. It's
basically a kind of mark-and-sweep: On update begin mark items
that are expected to change as outdated, while data arrives, undo
that marking, and update end remove all remaining marked items.
Change-Id: I739b84869033d511d5c9a80605c079e87ef4f6a7
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
-rw-r--r-- | src/plugins/debugger/cdb/cdbengine.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.cpp | 9 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.h | 8 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/lldb/lldbengine.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/pdb/pdbengine.cpp | 13 | ||||
-rw-r--r-- | src/plugins/debugger/watchdata.cpp | 3 | ||||
-rw-r--r-- | src/plugins/debugger/watchdata.h | 1 | ||||
-rw-r--r-- | src/plugins/debugger/watchhandler.cpp | 45 | ||||
-rw-r--r-- | src/plugins/debugger/watchhandler.h | 4 |
10 files changed, 54 insertions, 41 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 94747032f0..609db6a0ed 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1340,7 +1340,7 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters) return; } - watchHandler()->notifyUpdateStarted(); + watchHandler()->notifyUpdateStarted(updateParameters.partialVariables()); /* Watchers: Forcibly discard old symbol group as switching from * thread 0/frame 0 -> thread 1/assembly -> thread 0/frame 0 will otherwise re-use it @@ -1775,7 +1775,6 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate) { - watchHandler()->notifyUpdateFinished(); if (response.success) { if (boolSetting(VerboseLog)) showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.extensionReply), LogDebug); @@ -1796,6 +1795,7 @@ void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate) } else { showMessage(QString::fromLatin1(response.errorMessage), LogWarning); } + watchHandler()->notifyUpdateFinished(); } void CdbEngine::handleExpandLocals(const CdbResponse &response) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 94941873eb..f05e90d985 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1944,12 +1944,6 @@ void DebuggerEngine::updateLocalsView(const GdbMi &all) } } - QSet<QByteArray> toDelete; - if (!partial) { - foreach (WatchItem *item, handler->model()->itemsAtLevel<WatchItem *>(2)) - toDelete.insert(item->iname); - } - GdbMi data = all["data"]; foreach (const GdbMi &child, data.children()) { WatchItem *item = new WatchItem(child); @@ -1958,7 +1952,6 @@ void DebuggerEngine::updateLocalsView(const GdbMi &all) item->size = ti.size; handler->insertItem(item); - toDelete.remove(item->iname); } GdbMi ns = all["qtnamespace"]; @@ -1967,8 +1960,6 @@ void DebuggerEngine::updateLocalsView(const GdbMi &all) showMessage(_("FOUND NAMESPACED QT: " + ns.data())); } - handler->purgeOutdatedItems(toDelete); - static int count = 0; showMessage(_("<Rebuild Watchmodel %1 @ %2 >") .arg(++count).arg(LogWindow::logTimeStamp()), LogMiscInput); diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 4a09e07a0a..eea8e4e767 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -120,6 +120,14 @@ class UpdateParameters public: UpdateParameters() {} + QList<QByteArray> partialVariables() const + { + QList<QByteArray> result; + if (!partialVariable.isEmpty()) + result.append(partialVariable); + return result; + } + QByteArray partialVariable; }; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index f5dc8efa93..a23fa5c460 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -4660,7 +4660,7 @@ void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms) { m_pendingBreakpointRequests = 0; - watchHandler()->notifyUpdateStarted(); + watchHandler()->notifyUpdateStarted(params.partialVariables()); DebuggerCommand cmd("showData"); watchHandler()->appendFormatRequests(&cmd); @@ -4716,7 +4716,6 @@ void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms) void GdbEngine::handleStackFrame(const DebuggerResponse &response) { - watchHandler()->notifyUpdateFinished(); if (response.resultClass == ResultDone) { QByteArray out = response.consoleStreamOutput; while (out.endsWith(' ') || out.endsWith('\n')) @@ -4735,6 +4734,7 @@ void GdbEngine::handleStackFrame(const DebuggerResponse &response) } else { showMessage(_("DUMPER FAILED: " + response.toString())); } + watchHandler()->notifyUpdateFinished(); } QString GdbEngine::msgPtraceError(DebuggerStartMode sm) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index f74dd4da0b..4703776192 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -447,8 +447,8 @@ void LldbEngine::handleResponse(const QByteArray &response) foreach (const GdbMi &item, all.children()) { const QByteArray name = item.name(); if (name == "all") { - watchHandler()->notifyUpdateFinished(); updateLocalsView(item); + watchHandler()->notifyUpdateFinished(); } else if (name == "dumpers") { watchHandler()->addDumpers(item); setupInferiorStage2(); @@ -864,7 +864,7 @@ void LldbEngine::doUpdateLocals(const UpdateParameters ¶ms) return; } - watchHandler()->notifyUpdateStarted(); + watchHandler()->notifyUpdateStarted(params.partialVariables()); DebuggerCommand cmd("updateData"); cmd.arg("nativeMixed", isNativeMixedActive()); diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 81b3c375a7..9c5666eed1 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -572,17 +572,10 @@ void PdbEngine::refreshLocals(const GdbMi &vars) WatchHandler *handler = watchHandler(); handler->resetValueCache(); - QSet<QByteArray> toDelete; - foreach (WatchItem *item, handler->model()->itemsAtLevel<WatchItem *>(2)) - toDelete.insert(item->iname); - - foreach (const GdbMi &child, vars.children()) { - WatchItem *item = new WatchItem(child); - handler->insertItem(item); - toDelete.remove(item->iname); - } + foreach (const GdbMi &child, vars.children()) + handler->insertItem(new WatchItem(child)); - handler->purgeOutdatedItems(toDelete); + handler->notifyUpdateFinished(); DebuggerToolTipManager::updateEngine(this); } diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 8a97b7dcc0..9f33111cd8 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -131,7 +131,8 @@ WatchData::WatchData() : elided(0), wantsChildren(false), valueEnabled(true), - valueEditable(true) + valueEditable(true), + outdated(false) { } diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index 5cbf6ef753..dbcdfbaf4d 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -119,6 +119,7 @@ public: bool wantsChildren; bool valueEnabled; // Value will be enabled or not bool valueEditable; // Value will be editable + bool outdated; // \internal item is to be removed. Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchHandler) }; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 74ae071368..61ca2e1d53 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1221,8 +1221,20 @@ void WatchHandler::resetWatchers() loadSessionData(); } -void WatchHandler::notifyUpdateStarted() +void WatchHandler::notifyUpdateStarted(const QList<QByteArray> &inames) { + auto marker = [](TreeItem *it) { static_cast<WatchItem *>(it)->outdated = true; }; + + if (inames.isEmpty()) { + foreach (auto item, m_model->itemsAtLevel<WatchItem *>(2)) + item->walkTree(marker); + } else { + foreach (auto iname, inames) { + if (WatchItem *item = m_model->findItem(iname)) + item->walkTree(marker); + } + } + m_model->m_requestUpdateTimer.start(80); m_model->m_contentsValid = false; updateWatchersWindow(); @@ -1230,23 +1242,30 @@ void WatchHandler::notifyUpdateStarted() void WatchHandler::notifyUpdateFinished() { - m_model->m_contentsValid = true; - updateWatchersWindow(); - m_model->m_requestUpdateTimer.stop(); - emit m_model->updateFinished(); -} + struct OutDatedItemsFinder : public TreeItemVisitor + { + bool preVisit(TreeItem *item) + { + auto watchItem = static_cast<WatchItem *>(item); + if (level() <= 1 || !watchItem->outdated) + return true; + toRemove.append(watchItem); + return false; + } -void WatchHandler::purgeOutdatedItems(const QSet<QByteArray> &inames) -{ - foreach (const QByteArray &iname, inames) { - WatchItem *item = findItem(iname); + QList<WatchItem *> toRemove; + } finder; + + m_model->root()->walkTree(&finder); + + foreach (auto item, finder.toRemove) delete m_model->takeItem(item); - } - m_model->layoutChanged(); - m_model->reexpandItems(); m_model->m_contentsValid = true; updateWatchersWindow(); + m_model->reexpandItems(); + m_model->m_requestUpdateTimer.stop(); + emit m_model->updateFinished(); } void WatchHandler::removeItemByIName(const QByteArray &iname) diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index b823bb9063..aacbc6e0c2 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -197,9 +197,9 @@ public: void removeAllData(bool includeInspectData = false); void resetValueCache(); void resetWatchers(); - void notifyUpdateStarted(); + + void notifyUpdateStarted(const QList<QByteArray> &inames = {}); void notifyUpdateFinished(); - void purgeOutdatedItems(const QSet<QByteArray> &inames); private: WatchModel *m_model; // Owned. |