From: Simon Hausmann Date: Wed, 14 Aug 2013 13:44:53 +0000 (+0200) Subject: Fix writing the function offset table and initialize the pointer to the compiled... X-Git-Tag: upstream/5.2.1~669^2~38 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0d1e37e9f50b644c88578aee82859990e7378caf;p=platform%2Fupstream%2Fqtdeclarative.git Fix writing the function offset table and initialize the pointer to the compiled function in the runtime function Change-Id: I9aed9f394fedc4a4ea334f6ab1b72fe749c64c72 Reviewed-by: Lars Knoll --- diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index ee198c3..1f4ab47 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -42,6 +42,7 @@ #include "qv4compileddata_p.h" #include "qv4jsir_p.h" #include +#include 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; } } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 67ddfb3..fdd5891 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -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(reinterpret_cast(this) + offset); } + const Function *functionAt(int idx) const { + const uint *offsetTable = reinterpret_cast((reinterpret_cast(this)) + offsetToFunctionTable); + const uint offset = offsetTable[idx]; + return reinterpret_cast(reinterpret_cast(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 runtimeFunctions; }; struct MothCompilationUnit : public CompilationUnit diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 6bda115..7164e21 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -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); } diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index dc290c8..ca16080 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -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(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); diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index c2f6604..6aad2cd 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -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); diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index 4436725..6b59b16 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -120,11 +120,7 @@ QV4::CompiledData::CompilationUnit *EvalInstructionSelection::compile() compilationUnit->data = jsUnitGenerator.generateUnit(); - for (QHash::Iterator it = _irToVM.begin(), end = _irToVM.end(); - it != end; ++it) { - compilationUnit->ref(); - (*it)->compilationUnit = compilationUnit; - } + backendCompileStep(); return compilationUnit; } diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index d31d60d..7a049a8 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -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); } diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 99b94ba..f205913 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -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)