Get rid of the functions list in QV4::ExecutionEngine
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 16 Aug 2013 16:35:29 +0000 (18:35 +0200)
committerLars Knoll <lars.knoll@digia.com>
Fri, 16 Aug 2013 17:22:24 +0000 (19:22 +0200)
Change-Id: I97067dbb2819936a1b2029c9f63f0627cb6b8bd2
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/compiler/qv4compileddata.cpp
src/qml/compiler/qv4compileddata_p.h
src/qml/compiler/qv4isel_masm.cpp
src/qml/compiler/qv4isel_masm_p.h
src/qml/jsruntime/qv4debugging.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4function.cpp

index 59c6a9b..7f02509 100644 (file)
 #include <private/qv4function_p.h>
 #include <private/qv4lookup_p.h>
 #include <private/qv4regexpobject_p.h>
+#include <private/qv4unwindhelper_p.h>
 
 namespace QV4 {
 
 namespace CompiledData {
 
+namespace {
+    bool functionSortHelper(QV4::Function *lhs, QV4::Function *rhs)
+    {
+        return reinterpret_cast<quintptr>(lhs->code) < reinterpret_cast<quintptr>(rhs->code);
+    }
+}
+
 CompilationUnit::~CompilationUnit()
 {
     engine->compilationUnits.erase(engine->compilationUnits.find(this));
@@ -121,7 +129,13 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
         }
     }
 
-    return linkBackendToEngine(engine);
+    QV4::Function *entry = linkBackendToEngine(engine);
+
+    runtimeFunctionsSortedByAddress.resize(runtimeFunctions.size());
+    memcpy(runtimeFunctionsSortedByAddress.data(), runtimeFunctions.data(), runtimeFunctions.size() * sizeof(QV4::Function*));
+    qSort(runtimeFunctionsSortedByAddress.begin(), runtimeFunctionsSortedByAddress.end(), functionSortHelper);
+
+    return entry;
 }
 
 void CompilationUnit::markObjects()
@@ -130,6 +144,8 @@ void CompilationUnit::markObjects()
         runtimeStrings[i]->mark();
     for (int i = 0; i < data->regexpTableSize; ++i)
         runtimeRegularExpressions[i].mark();
+    for (int i = 0; i < runtimeFunctions.count(); ++i)
+        runtimeFunctions[i]->mark();
 }
 
 }
index 611d916..379766f 100644 (file)
@@ -328,7 +328,8 @@ struct CompilationUnit
     QV4::Lookup *runtimeLookups;
     QV4::Value *runtimeRegularExpressions;
     QV4::InternalClass **runtimeClasses;
-    QList<QV4::Function *> runtimeFunctions;
+    QVector<QV4::Function *> runtimeFunctions;
+    QVector<QV4::Function *> runtimeFunctionsSortedByAddress;
 
     QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
 
index a998e8b..e0b79ac 100644 (file)
@@ -64,6 +64,11 @@ using namespace QQmlJS;
 using namespace QQmlJS::MASM;
 using namespace QV4;
 
+CompilationUnit::~CompilationUnit()
+{
+    UnwindHelper::deregisterFunctions(runtimeFunctions);
+}
+
 QV4::Function *CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
 {
     QV4::Function *rootRuntimeFunction = 0;
@@ -78,14 +83,14 @@ QV4::Function *CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
                               (Value (*)(QV4::ExecutionContext *, const uchar *)) codeRefs[i].code().executableAddress(),
                               codeRefs[i].size());
 
-        UnwindHelper::registerFunction(runtimeFunction);
-
         if (compiledFunction == compiledRootFunction) {
             assert(!rootRuntimeFunction);
             rootRuntimeFunction = runtimeFunction;
         }
     }
 
+    UnwindHelper::registerFunctions(runtimeFunctions);
+
     return rootRuntimeFunction;
 }
 
index 3cde647..4461f16 100644 (file)
@@ -63,6 +63,8 @@ class InstructionSelection;
 
 struct CompilationUnit : public QV4::CompiledData::CompilationUnit
 {
+    virtual ~CompilationUnit();
+
     virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine);
 
     virtual QV4::ExecutableAllocator::ChunkOfPages *chunkForFunction(int functionIndex);
index 3bb0311..5534305 100644 (file)
@@ -185,9 +185,11 @@ void Debugger::pauseAndWait()
 
 void Debugger::applyPendingBreakPoints()
 {
-    foreach (Function *function, _engine->functions) {
-        m_pendingBreakPointsToAdd.applyToFunction(function, /*removeBreakPoints*/false);
-        m_pendingBreakPointsToRemove.applyToFunction(function, /*removeBreakPoints*/true);
+    foreach (QV4::CompiledData::CompilationUnit *unit, _engine->compilationUnits) {
+        foreach (Function *function, unit->runtimeFunctions) {
+            m_pendingBreakPointsToAdd.applyToFunction(function, /*removeBreakPoints*/false);
+            m_pendingBreakPointsToRemove.applyToFunction(function, /*removeBreakPoints*/true);
+        }
     }
 
     for (BreakPoints::ConstIterator it = m_pendingBreakPointsToAdd.constBegin(),
index 764f3fa..36ab994 100644 (file)
@@ -87,7 +87,6 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
     , debugger(0)
     , globalObject(0)
     , globalCode(0)
-    , functionsNeedSort(false)
     , m_engineId(engineSerial.fetchAndAddOrdered(1))
     , regExpCache(0)
     , m_multiplyWrappedQObjects(0)
@@ -279,7 +278,6 @@ ExecutionEngine::~ExecutionEngine()
     delete identifierTable;
     delete bumperPointerAllocator;
     delete regExpCache;
-    UnwindHelper::deregisterFunctions(functions);
     delete regExpAllocator;
     delete executableAllocator;
 }
@@ -379,8 +377,6 @@ ExecutionContext *ExecutionEngine::pushGlobalContext()
 Function *ExecutionEngine::newFunction(const QString &name)
 {
     Function *f = new Function(this, newIdentifier(name));
-    functions.append(f);
-    functionsNeedSort = true;
     return f;
 }
 
@@ -732,9 +728,6 @@ void ExecutionEngine::markObjects()
         c = c->parent;
     }
 
-    for (int i = 0; i < functions.size(); ++i)
-        functions.at(i)->mark();
-
     id_length->mark();
     id_prototype->mark();
     id_constructor->mark();
@@ -796,11 +789,6 @@ void ExecutionEngine::markObjects()
 }
 
 namespace {
-    bool functionSortHelper(Function *lhs, Function *rhs)
-    {
-        return reinterpret_cast<quintptr>(lhs->code) < reinterpret_cast<quintptr>(rhs->code);
-    }
-
     struct FindHelper
     {
         bool operator()(Function *function, quintptr pc)
@@ -818,15 +806,15 @@ namespace {
 
 Function *ExecutionEngine::functionForProgramCounter(quintptr pc) const
 {
-    if (functionsNeedSort) {
-        qSort(functions.begin(), functions.end(), functionSortHelper);
-        functionsNeedSort = false;
+    for (QSet<QV4::CompiledData::CompilationUnit*>::ConstIterator unitIt = compilationUnits.constBegin(), unitEnd = compilationUnits.constEnd();
+         unitIt != unitEnd; ++unitIt) {
+        const QVector<Function*> &functions = (*unitIt)->runtimeFunctionsSortedByAddress;
+        QVector<Function*>::ConstIterator it = qBinaryFind(functions.constBegin(),
+                                                           functions.constEnd(),
+                                                           pc, FindHelper());
+        if (it != functions.constEnd())
+            return *it;
     }
-
-    QVector<Function*>::ConstIterator it = qBinaryFind(functions.constBegin(), functions.constEnd(),
-            pc, FindHelper());
-    if (it != functions.constEnd())
-        return *it;
     return 0;
 }
 
index 6a7442d..3dfc070 100644 (file)
@@ -201,9 +201,6 @@ struct Q_QML_EXPORT ExecutionEngine
     String *id_uintMax;
     String *id_name;
 
-    mutable QVector<Function *> functions;
-    mutable bool functionsNeedSort;
-
     QSet<CompiledData::CompilationUnit*> compilationUnits;
 
     quint32 m_engineId;
index c96935d..87db585 100644 (file)
@@ -53,8 +53,6 @@ using namespace QV4;
 
 Function::~Function()
 {
-    engine->functions.remove(engine->functions.indexOf(this));
-    UnwindHelper::deregisterFunction(this); // ### move to masm compilation unit
 }
 
 void Function::init(CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Value (*codePtr)(ExecutionContext *, const uchar *),