Move codeRef out of QV4::Function
authorSimon Hausmann <simon.hausmann@digia.com>
Wed, 14 Aug 2013 18:06:03 +0000 (20:06 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 15 Aug 2013 08:35:40 +0000 (10:35 +0200)
Change-Id: I65700b9cc4907aaa28623a95204e88f87fccfd49
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/compiler/qv4compileddata_p.h
src/qml/compiler/qv4compiler.cpp
src/qml/compiler/qv4compiler_p.h
src/qml/compiler/qv4isel_masm.cpp
src/qml/compiler/qv4isel_masm_p.h
src/qml/jsruntime/qv4function_p.h
src/qml/jsruntime/qv4unwindhelper_p-dw2.h

index 859f4f4..70e9d90 100644 (file)
@@ -45,6 +45,7 @@
 #include <QVector>
 #include <QStringList>
 #include <private/qv4value_def_p.h>
+#include <private/qv4executableallocator_p.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -108,6 +109,7 @@ struct Function
     };
 
     QV4::Value (*code)(ExecutionContext *, const uchar *);
+    quint32 index; // in CompilationUnit's function table
     quint32 nameIndex;
     quint32 sourceFileIndex;
     qint64 flags;
@@ -248,6 +250,7 @@ struct CompilationUnit
 
     QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
 
+    virtual QV4::ExecutableAllocator::ChunkOfPages *chunkForFunction(int /*functionIndex*/) { return 0; }
 
     // ### runtime data
     // pointer to qml data for QML unit
index fcc6c19..61d2d94 100644 (file)
@@ -124,25 +124,22 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
         functionTable[i] = functionOffsets.value(irModule->functions.at(i));
 
     char *f = data + unitSize + stringDataSize;
-    writeFunction(f, irModule->rootFunction);
-    f += QV4::CompiledData::Function::calculateSize(irModule->rootFunction);
-    unit->indexOfRootFunction = 0;
-
     for (uint i = 0; i < irModule->functions.size(); ++i) {
         QQmlJS::V4IR::Function *function = irModule->functions.at(i);
         if (function == irModule->rootFunction)
-            continue;
+            unit->indexOfRootFunction = i;
 
-        writeFunction(f, function);
+        writeFunction(f, i, function);
         f += QV4::CompiledData::Function::calculateSize(function);
     }
 
     return unit;
 }
 
-void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QQmlJS::V4IR::Function *irFunction)
+void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, int index, QQmlJS::V4IR::Function *irFunction)
 {
     QV4::CompiledData::Function *function = (QV4::CompiledData::Function *)f;
+    function->index = index;
     function->nameIndex = getStringId(*irFunction->name);
     function->sourceFileIndex = getStringId(irFunction->sourceFile);
     function->flags = 0;
index b111693..661bcd1 100644 (file)
@@ -63,7 +63,7 @@ struct JSUnitGenerator {
     int getStringId(const QString &string) const;
 
     QV4::CompiledData::Unit *generateUnit();
-    void writeFunction(char *f, QQmlJS::V4IR::Function *irFunction);
+    void writeFunction(char *f, int index, QQmlJS::V4IR::Function *irFunction);
 
     QHash<QString, int> stringToId;
     QStringList strings;
index 32c69ae..3abe419 100644 (file)
@@ -87,6 +87,16 @@ QV4::Function *CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
     return rootRuntimeFunction;
 }
 
+QV4::ExecutableAllocator::ChunkOfPages *CompilationUnit::chunkForFunction(int functionIndex)
+{
+    if (functionIndex < 0 || functionIndex >= codeRefs.count())
+        return 0;
+    JSC::ExecutableMemoryHandle *handle = codeRefs[functionIndex].executableMemory();
+    if (!handle)
+        return 0;
+    return handle->chunk();
+}
+
 namespace {
 class ConvertTemps: protected V4IR::StmtVisitor, protected V4IR::ExprVisitor
 {
@@ -546,7 +556,7 @@ void Assembler::recordLineNumber(int lineNumber)
 }
 
 
-void Assembler::link(QV4::Function *vmFunc)
+JSC::MacroAssemblerCodeRef Assembler::link(QV4::Function *vmFunc)
 {
     Label endOfCode = label();
 #if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
@@ -604,6 +614,8 @@ void Assembler::link(QV4::Function *vmFunc)
     UnwindHelper::writeARMUnwindInfo(linkBuffer.debugAddress(), linkBuffer.offsetOf(endOfCode));
 #endif
 
+    JSC::MacroAssemblerCodeRef codeRef;
+
     static bool showCode = !qgetenv("SHOW_CODE").isNull();
     if (showCode) {
 #if OS(LINUX) && !defined(Q_OS_ANDROID)
@@ -632,7 +644,7 @@ void Assembler::link(QV4::Function *vmFunc)
             name.prepend("IR::Function(0x");
             name.append(")");
         }
-        vmFunc->codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
+        codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
 
         WTF::setDataFile(stderr);
 #if (OS(LINUX) && !defined(Q_OS_ANDROID)) || OS(MAC_OS_X)
@@ -649,10 +661,11 @@ void Assembler::link(QV4::Function *vmFunc)
 #  endif
 #endif
     } else {
-        vmFunc->codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
+        codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
     }
 
-    vmFunc->code = (Value (*)(QV4::ExecutionContext *, const uchar *)) vmFunc->codeRef.code().executableAddress();
+    vmFunc->code = (Value (*)(QV4::ExecutionContext *, const uchar *)) codeRef.code().executableAddress();
+    return codeRef;
 }
 
 InstructionSelection::InstructionSelection(QV4::ExecutionEngine *engine, V4IR::Module *module)
@@ -738,7 +751,8 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
         }
     }
 
-    _as->link(_vmFunction);
+    JSC::MacroAssemblerCodeRef codeRef =_as->link(_vmFunction);
+    codeRefs[_function] = codeRef;
 
     if (_lookups.size()) {
         _vmFunction->lookups = new Lookup[_lookups.size()];
@@ -760,8 +774,12 @@ QV4::CompiledData::CompilationUnit *InstructionSelection::backendCompileStep()
 {
     compilationUnit->data = jsUnitGenerator.generateUnit();
     compilationUnit->runtimeFunctions.reserve(jsUnitGenerator.irModule->functions.size());
-    foreach (V4IR::Function *irFunction, jsUnitGenerator.irModule->functions)
+    compilationUnit->codeRefs.resize(jsUnitGenerator.irModule->functions.size());
+    int i = 0;
+    foreach (V4IR::Function *irFunction, jsUnitGenerator.irModule->functions) {
         compilationUnit->runtimeFunctions << _irToVM[irFunction];
+        compilationUnit->codeRefs[i++] = codeRefs[irFunction];
+    }
     return compilationUnit;
 }
 
index bf3d405..8c55f41 100644 (file)
@@ -52,6 +52,7 @@
 #include <config.h>
 #include <wtf/Vector.h>
 #include <assembler/MacroAssembler.h>
+#include <assembler/MacroAssemblerCodeRef.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -62,9 +63,12 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit
 {
     virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine);
 
+    virtual QV4::ExecutableAllocator::ChunkOfPages *chunkForFunction(int functionIndex);
+
     // Coderef + execution engine
 
     QList<QV4::Function *> runtimeFunctions;
+    QVector<JSC::MacroAssemblerCodeRef> codeRefs;
 };
 
 class Assembler : public JSC::MacroAssembler
@@ -755,7 +759,7 @@ public:
         return Jump();
     }
 
-    void link(QV4::Function *vmFunc);
+    JSC::MacroAssemblerCodeRef link(QV4::Function *vmFunc);
 
     void recordLineNumber(int lineNumber);
 
@@ -931,6 +935,7 @@ private:
     int _locals;
 
     CompilationUnit *compilationUnit;
+    QHash<V4IR::Function*, JSC::MacroAssemblerCodeRef> codeRefs;
 };
 
 class Q_QML_EXPORT ISelFactory: public EvalISelFactory
index 5f6ad65..4484331 100644 (file)
@@ -48,7 +48,6 @@
 #include <QtCore/qurl.h>
 
 #include <config.h>
-#include <assembler/MacroAssemblerCodeRef.h>
 #include "qv4value_def_p.h"
 #include <private/qv4compileddata_p.h>
 
@@ -95,7 +94,6 @@ struct Function {
     CompiledData::CompilationUnit *compilationUnit;
     Value (*code)(ExecutionContext *, const uchar *);
     const uchar *codeData;
-    JSC::MacroAssemblerCodeRef codeRef;
     quint32 codeSize;
 
     QVector<String *> formals;
index 57615f0..3a6204f 100644 (file)
@@ -48,6 +48,7 @@
 #include <wtf/Platform.h>
 #include <wtf/PageAllocation.h>
 #include <ExecutableAllocator.h>
+#include <private/qv4isel_masm_p.h>
 
 #include <QMap>
 #include <QMutex>
@@ -126,13 +127,12 @@ UnwindInfo::~UnwindInfo()
 
 static void ensureUnwindInfo(Function *f)
 {
-    if (!f->codeRef)
+    if (!f->code)
         return; // Not a JIT generated function
 
-    JSC::ExecutableMemoryHandle *handle = f->codeRef.executableMemory();
-    if (!handle)
+    ExecutableAllocator::ChunkOfPages *chunk = f->compilationUnit->chunkForFunction(f->compiledFunction->index);
+    if (!chunk)
         return;
-    ExecutableAllocator::ChunkOfPages *chunk = handle->chunk();
 
     // Already registered?
     if (chunk->unwindInfo)