Fix writing the function offset table and initialize the pointer to the compiled...
authorSimon Hausmann <simon.hausmann@digia.com>
Wed, 14 Aug 2013 13:44:53 +0000 (15:44 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 15 Aug 2013 07:08:44 +0000 (09:08 +0200)
Change-Id: I9aed9f394fedc4a4ea334f6ab1b72fe749c64c72
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/compiler/qv4compileddata.cpp
src/qml/compiler/qv4compileddata_p.h
src/qml/compiler/qv4compiler.cpp
src/qml/compiler/qv4isel_masm.cpp
src/qml/compiler/qv4isel_masm_p.h
src/qml/compiler/qv4isel_p.cpp
src/qml/compiler/qv4isel_p.h
src/qml/jsruntime/qv4function_p.h

index ee198c3..1f4ab47 100644 (file)
@@ -42,6 +42,7 @@
 #include "qv4compileddata_p.h"
 #include "qv4jsir_p.h"
 #include <private/qv4engine_p.h>
+#include <private/qv4function_p.h>
 
 namespace QV4 {
 
@@ -72,7 +73,25 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
 // ### Move to masm
 QV4::Function *MasmCompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
 {
-    return rootFunction;
+    QV4::Function *rootRuntimeFunction = 0;
+
+    const CompiledData::Function *compiledRootFunction = data->functionAt(data->indexOfRootFunction);
+
+    for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
+        QV4::Function *runtimeFunction = runtimeFunctions.at(i);
+        const CompiledData::Function *compiledFunction = data->functionAt(i);
+
+        runtimeFunction->compilationUnit = this;
+        runtimeFunction->compilationUnit->ref();
+        runtimeFunction->compiledFunction = compiledFunction;
+
+        if (compiledFunction == compiledRootFunction) {
+            assert(!rootRuntimeFunction);
+            rootRuntimeFunction = runtimeFunction;
+        }
+    }
+
+    return rootRuntimeFunction;
 }
 
 }
index 67ddfb3..fdd5891 100644 (file)
@@ -62,6 +62,7 @@ struct ExecutionContext;
 namespace CompiledData {
 
 struct String;
+struct Function;
 
 static const char magic_str[] = "qv4cdata";
 
@@ -88,6 +89,12 @@ struct Unit
         return reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
     }
 
+    const Function *functionAt(int idx) const {
+        const uint *offsetTable = reinterpret_cast<const uint*>((reinterpret_cast<const char *>(this)) + offsetToFunctionTable);
+        const uint offset = offsetTable[idx];
+        return reinterpret_cast<const Function*>(reinterpret_cast<const char *>(this) + offset);
+    }
+
     static int calculateSize(uint nStrings, uint nFunctions) { return (sizeof(Unit) + (nStrings + nFunctions) * sizeof(uint) + 7) & ~7; }
 };
 
@@ -251,8 +258,7 @@ struct MasmCompilationUnit : public CompilationUnit
 
     // Coderef + execution engine
 
-    // ### remove
-    QV4::Function *rootFunction;
+    QList<QV4::Function *> runtimeFunctions;
 };
 
 struct MothCompilationUnit : public CompilationUnit
index 6bda115..7164e21 100644 (file)
@@ -118,11 +118,12 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
         string += QV4::CompiledData::String::calculateSize(qstr);
     }
 
-    // pointer to the entry function
-    uint *functionTable = (uint *)data + unit->offsetToFunctionTable;
+    uint *functionTable = (uint *)(data + unit->offsetToFunctionTable);
+    for (uint i = 0; i < irModule->functions.size(); ++i)
+        functionTable[i] = functionOffsets.value(irModule->functions.at(i));
+
     char *f = data + unitSize + stringDataSize;
     writeFunction(f, irModule->rootFunction);
-    ++functionTable;
     f += QV4::CompiledData::Function::calculateSize(irModule->rootFunction);
     unit->indexOfRootFunction = 0;
 
@@ -132,7 +133,6 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
             continue;
 
         writeFunction(f, function);
-        ++functionTable;
         f += QV4::CompiledData::Function::calculateSize(function);
     }
 
index dc290c8..ca16080 100644 (file)
@@ -642,7 +642,6 @@ InstructionSelection::InstructionSelection(QV4::ExecutionEngine *engine, V4IR::M
 {
     QV4::CompiledData::MasmCompilationUnit *masmUnit = new QV4::CompiledData::MasmCompilationUnit;
     compilationUnit = masmUnit;
-    masmUnit->rootFunction = _irToVM[module->rootFunction];
 }
 
 InstructionSelection::~InstructionSelection()
@@ -735,6 +734,14 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
     _as = oldAssembler;
 }
 
+void InstructionSelection::backendCompileStep()
+{
+    QV4::CompiledData::MasmCompilationUnit *masmUnit = static_cast<QV4::CompiledData::MasmCompilationUnit*>(compilationUnit);
+    masmUnit->runtimeFunctions.reserve(jsUnitGenerator.irModule->functions.size());
+    foreach (V4IR::Function *irFunction, jsUnitGenerator.irModule->functions)
+        masmUnit->runtimeFunctions << _irToVM[irFunction];
+}
+
 void InstructionSelection::callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result)
 {
     int argc = prepareVariableArguments(args);
index c2f6604..6aad2cd 100644 (file)
@@ -787,6 +787,8 @@ public:
     virtual void run(QV4::Function *vmFunction, V4IR::Function *function);
 
 protected:
+    virtual void backendCompileStep();
+
     virtual void callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *args, V4IR::Temp *result);
     virtual void callBuiltinTypeofMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result);
     virtual void callBuiltinTypeofSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result);
index 4436725..6b59b16 100644 (file)
@@ -120,11 +120,7 @@ QV4::CompiledData::CompilationUnit *EvalInstructionSelection::compile()
 
     compilationUnit->data = jsUnitGenerator.generateUnit();
 
-    for (QHash<V4IR::Function *, QV4::Function *>::Iterator it = _irToVM.begin(), end = _irToVM.end();
-         it != end; ++it) {
-        compilationUnit->ref();
-        (*it)->compilationUnit = compilationUnit;
-    }
+    backendCompileStep();
 
     return compilationUnit;
 }
index d31d60d..7a049a8 100644 (file)
@@ -73,6 +73,7 @@ protected:
     QV4::Function *createFunctionMapping(QV4::Function *outer, V4IR::Function *irFunction);
     QV4::ExecutionEngine *engine() const { return _engine; }
     virtual void run(QV4::Function *vmFunction, V4IR::Function *function) = 0;
+    virtual void backendCompileStep() {}
 
     int stringId(const QString &str) { return jsUnitGenerator.registerString(str); }
 
index 99b94ba..f205913 100644 (file)
@@ -91,6 +91,7 @@ struct Function {
     int refCount;
     String *name;
 
+    const CompiledData::Function *compiledFunction;
     CompiledData::CompilationUnit *compilationUnit;
     Value (*code)(ExecutionContext *, const uchar *);
     const uchar *codeData;
@@ -119,6 +120,7 @@ struct Function {
     Function(ExecutionEngine *engine, String *name)
         : refCount(0)
         , name(name)
+        , compiledFunction(0)
         , compilationUnit(0)
         , code(0)
         , codeData(0)