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 <lars.knoll@digia.com>
This commit is contained in:
Simon Hausmann 2013-08-14 15:44:53 +02:00
parent 5f3ef18bf8
commit 0d1e37e9f5
8 changed files with 46 additions and 13 deletions

View 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;
}
}

View 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

View 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);
}

View 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);

View 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);

View 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;
}

View 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); }

View 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)