aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhjk <hjk@theqtcompany.com>2015-07-06 09:46:08 +0200
committerhjk <hjk@theqtcompany.com>2015-07-07 08:08:08 +0000
commitd48ac14fba52d4f4eac0b73c07b59ef56c50b259 (patch)
treeeaab28eb1dc175bf542dc7f21d82de072e2849cb
parent1587c171d6c2929d15e4626b4fead0ac070314f7 (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.cpp4
-rw-r--r--src/plugins/debugger/debuggerengine.cpp9
-rw-r--r--src/plugins/debugger/debuggerengine.h8
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp4
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp4
-rw-r--r--src/plugins/debugger/pdb/pdbengine.cpp13
-rw-r--r--src/plugins/debugger/watchdata.cpp3
-rw-r--r--src/plugins/debugger/watchdata.h1
-rw-r--r--src/plugins/debugger/watchhandler.cpp45
-rw-r--r--src/plugins/debugger/watchhandler.h4
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 &params)
{
m_pendingBreakpointRequests = 0;
- watchHandler()->notifyUpdateStarted();
+ watchHandler()->notifyUpdateStarted(params.partialVariables());
DebuggerCommand cmd("showData");
watchHandler()->appendFormatRequests(&cmd);
@@ -4716,7 +4716,6 @@ void GdbEngine::doUpdateLocals(const UpdateParameters &params)
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 &params)
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.