From ebb08ee84e8141042ed16dfc5892697ef96077c4 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 30 Nov 2015 12:04:59 +0100 Subject: V4 Debugger: Avoid looking up values in debugger thread To avoid interaction with the engine from the debugger thread we move the value lookup functionality into the data collector, and drop the RefHolder. Also, we define some more debugger jobs to move the work the request handlers do into the GUI thread. Task-number: QTBUG-50481 Change-Id: Id93548dc65133246deac71f73188c715e9dc01e4 Reviewed-by: Simon Hausmann --- .../qml/debugger/qv4debugger/tst_qv4debugger.cpp | 107 ++++++++++++--------- 1 file changed, 61 insertions(+), 46 deletions(-) (limited to 'tests/auto/qml/debugger') diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index fd504c50d3..7398e97326 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -100,16 +100,24 @@ public: typedef QV4DataCollector::Refs Refs; typedef QV4DataCollector::Ref Ref; struct NamedRefs { - QStringList names; QJsonArray refs; + QJsonObject scope; int size() const { - Q_ASSERT(names.size() == refs.size()); - return names.size(); + return scope.size(); } bool contains(const QString &name) const { - return names.contains(name); + return scope.contains(name); + } + + QJsonObject resolveRef(int ref) const { + foreach (const QJsonValue &val, refs) { + QJsonObject obj = val.toObject(); + if (obj.value(QLatin1String("handle")).toInt() == ref) + return obj; + } + return QJsonObject(); } #define DUMP_JSON(x) {\ @@ -119,7 +127,7 @@ public: QJsonObject rawValue(const QString &name) const { Q_ASSERT(contains(name)); - return refs.at(names.indexOf(name)).toObject(); + return scope[name].toObject(); } QJsonValue value(const QString &name) const { @@ -136,7 +144,7 @@ public: return; } - QJsonObject o = refs.at(names.indexOf(name)).toObject(); + QJsonObject o = scope[name].toObject(); QJsonDocument d; d.setObject(o); qDebug() << name << "=" << d.toJson(QJsonDocument::Indented); @@ -202,17 +210,30 @@ public: void captureContextInfo(QV4Debugger *debugger) { for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) { - m_capturedArguments.append(NamedRefs()); - ArgumentCollectJob argumentsJob(debugger->engine(), &collector, - &m_capturedArguments.last().names, i, 0); - debugger->runInEngine(&argumentsJob); - m_capturedArguments.last().refs = collector.flushCollectedRefs(); - - m_capturedLocals.append(NamedRefs()); - LocalCollectJob localsJob(debugger->engine(), &collector, - &m_capturedLocals.last().names, i, 0); - debugger->runInEngine(&localsJob); - m_capturedLocals.last().refs = collector.flushCollectedRefs(); + m_capturedScope.append(NamedRefs()); + ScopeJob job(&collector, i, 0); + debugger->runInEngine(&job); + NamedRefs &refs = m_capturedScope.last(); + refs.refs = job.refs(); + QJsonObject object = job.returnValue(); + object = object.value(QLatin1String("object")).toObject(); + int ref = object.value(QLatin1String("ref")).toInt(); + object = refs.resolveRef(ref); + foreach (const QJsonValue &value, object.value(QLatin1String("properties")).toArray()) { + QJsonObject property = value.toObject(); + QString name = property.value(QLatin1String("name")).toString(); + property.remove(QLatin1String("name")); + if (property.contains(QLatin1String("ref"))) { + int childRef = property.value(QLatin1String("ref")).toInt(); + if (childRef >= 0 && refs.refs.size() > childRef) { + property.remove(QLatin1String("ref")); + property.insert(QLatin1String("properties"), + refs.resolveRef(childRef).value( + QLatin1String("properties")).toArray()); + } + } + refs.scope.insert(name, property); + } } } @@ -229,8 +250,7 @@ public: QList m_statesWhenPaused; QList m_breakPointsToAddWhenPaused; QVector m_stackTrace; - QVector m_capturedArguments; - QVector m_capturedLocals; + QVector m_capturedScope; qint64 m_thrownValue; QV4DataCollector collector; @@ -444,8 +464,8 @@ void tst_qv4debugger::conditionalBreakPoint() QCOMPARE(state.fileName, QString("conditionalBreakPoint")); QCOMPARE(state.lineNumber, 3); - QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1); - const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0); + QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); QCOMPARE(frame0.size(), 2); QVERIFY(frame0.contains("i")); QCOMPARE(frame0.value("i").toInt(), 11); @@ -501,13 +521,13 @@ void tst_qv4debugger::readArguments() debugger()->addBreakPoint("readArguments", 2); evaluateJavaScript(script, "readArguments"); QVERIFY(m_debuggerAgent->m_wasPaused); - QVERIFY(m_debuggerAgent->m_capturedArguments.size() > 1); - const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedArguments.at(0); + QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); QCOMPARE(frame0.size(), 4); QVERIFY(frame0.contains(QStringLiteral("a"))); QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); QCOMPARE(frame0.value(QStringLiteral("a")).toDouble(), 1.0); - QVERIFY(frame0.names.contains("b")); + QVERIFY(frame0.scope.contains("b")); QCOMPARE(frame0.type(QStringLiteral("b")), QStringLiteral("string")); QCOMPARE(frame0.value(QStringLiteral("b")).toString(), QStringLiteral("two")); } @@ -525,9 +545,9 @@ void tst_qv4debugger::readLocals() debugger()->addBreakPoint("readLocals", 3); evaluateJavaScript(script, "readLocals"); QVERIFY(m_debuggerAgent->m_wasPaused); - QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1); - const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0); - QCOMPARE(frame0.size(), 2); + QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); + QCOMPARE(frame0.size(), 4); // locals and parameters QVERIFY(frame0.contains("c")); QCOMPARE(frame0.type("c"), QStringLiteral("number")); QCOMPARE(frame0.value("c").toDouble(), 3.0); @@ -547,9 +567,9 @@ void tst_qv4debugger::readObject() debugger()->addBreakPoint("readObject", 3); evaluateJavaScript(script, "readObject"); QVERIFY(m_debuggerAgent->m_wasPaused); - QVERIFY(m_debuggerAgent->m_capturedLocals.size() > 1); - const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedLocals.at(0); - QCOMPARE(frame0.size(), 1); + QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); + const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); + QCOMPARE(frame0.size(), 2); QVERIFY(frame0.contains("b")); QCOMPARE(frame0.type("b"), QStringLiteral("object")); QJsonObject b = frame0.rawValue("b"); @@ -600,28 +620,23 @@ void tst_qv4debugger::readContextInAllFrames() evaluateJavaScript(script, "readFormalsInAllFrames"); QVERIFY(m_debuggerAgent->m_wasPaused); QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 13); - QCOMPARE(m_debuggerAgent->m_capturedArguments.size(), 13); - QCOMPARE(m_debuggerAgent->m_capturedLocals.size(), 13); + QCOMPARE(m_debuggerAgent->m_capturedScope.size(), 13); for (int i = 0; i < 12; ++i) { - const TestAgent::NamedRefs &args = m_debuggerAgent->m_capturedArguments.at(i); - QCOMPARE(args.size(), 1); - QVERIFY(args.contains("n")); - QCOMPARE(args.type("n"), QStringLiteral("number")); - QCOMPARE(args.value("n").toDouble(), i + 1.0); - - const TestAgent::NamedRefs &locals = m_debuggerAgent->m_capturedLocals.at(i); - QCOMPARE(locals.size(), 1); - QVERIFY(locals.contains("n_1")); + const TestAgent::NamedRefs &scope = m_debuggerAgent->m_capturedScope.at(i); + QCOMPARE(scope.size(), 2); + QVERIFY(scope.contains("n")); + QCOMPARE(scope.type("n"), QStringLiteral("number")); + QCOMPARE(scope.value("n").toDouble(), i + 1.0); + QVERIFY(scope.contains("n_1")); if (i == 0) { - QCOMPARE(locals.type("n_1"), QStringLiteral("undefined")); + QCOMPARE(scope.type("n_1"), QStringLiteral("undefined")); } else { - QCOMPARE(locals.type("n_1"), QStringLiteral("number")); - QCOMPARE(locals.value("n_1").toInt(), i); + QCOMPARE(scope.type("n_1"), QStringLiteral("number")); + QCOMPARE(scope.value("n_1").toInt(), i); } } - QCOMPARE(m_debuggerAgent->m_capturedArguments[12].size(), 0); - QCOMPARE(m_debuggerAgent->m_capturedLocals[12].size(), 0); + QCOMPARE(m_debuggerAgent->m_capturedScope[12].size(), 0); } void tst_qv4debugger::pauseOnThrow() -- cgit v1.2.3