Initial port of moth to the new compile data structures

Change-Id: I2ead40c5c8c9b12b29c48c387ea424838d1f7d9e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Simon Hausmann 2013-08-16 15:57:50 +02:00 committed by Lars Knoll
parent 75cc05fcf4
commit 0d4657cc17
7 changed files with 66 additions and 21 deletions

View File

@ -328,6 +328,7 @@ struct CompilationUnit
QV4::Lookup *runtimeLookups;
QV4::Value *runtimeRegularExpressions;
QV4::InternalClass **runtimeClasses;
QList<QV4::Function *> runtimeFunctions;
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
@ -342,16 +343,6 @@ protected:
virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
};
struct MothCompilationUnit : public CompilationUnit
{
virtual ~MothCompilationUnit() {
// free all bytecode
}
// vector of bytecode
};
}
}

View File

@ -297,8 +297,10 @@ int QV4::Compiler::JSUnitGenerator::writeFunction(char *f, int index, QQmlJS::V4
locals[i] = getStringId(*irFunction->locals.at(i));
// write line number mappings
quint32 *mappingsToWrite = (quint32*)(f + function->lineNumberMappingOffset);
memcpy(mappingsToWrite, lineNumberMapping->constData(), 2 * function->nLineNumberMappingEntries * sizeof(quint32));
if (function->nLineNumberMappingEntries) {
quint32 *mappingsToWrite = (quint32*)(f + function->lineNumberMappingOffset);
memcpy(mappingsToWrite, lineNumberMapping->constData(), 2 * function->nLineNumberMappingEntries * sizeof(quint32));
}
// write inner functions
quint32 *innerFunctions = (quint32 *)(f + function->innerFunctionsOffset);

View File

@ -69,7 +69,6 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit
// Coderef + execution engine
QList<QV4::Function *> runtimeFunctions;
QVector<JSC::MacroAssemblerCodeRef> codeRefs;
};

View File

@ -46,6 +46,7 @@
#include <private/qv4debugging_p.h>
#include <private/qv4function_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4compileddata_p.h>
#undef USE_TYPE_INFO
@ -198,6 +199,7 @@ InstructionSelection::InstructionSelection(QV4::ExecutionEngine *engine, V4IR::M
, _stackSlotAllocator(0)
, _currentStatement(0)
{
compilationUnit = new CompilationUnit;
}
InstructionSelection::~InstructionSelection()
@ -275,8 +277,7 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
// TODO: patch stack size (the push instruction)
patchJumpAddresses();
_vmFunction->code = VME::exec;
_vmFunction->codeData = squeezeCode();
codeRefs.insert(_function, squeezeCode());
if (QV4::Debugging::Debugger *debugger = engine()->debugger)
debugger->setPendingBreakpoints(_vmFunction);
@ -297,6 +298,19 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
delete[] codeStart;
}
QV4::CompiledData::CompilationUnit *InstructionSelection::backendCompileStep()
{
compilationUnit->data = jsUnitGenerator.generateUnit();
compilationUnit->runtimeFunctions.reserve(jsUnitGenerator.irModule->functions.size());
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;
}
void InstructionSelection::callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result)
{
Instruction::CallValue call;
@ -1046,11 +1060,12 @@ void InstructionSelection::patchJumpAddresses()
_addrs.clear();
}
uchar *InstructionSelection::squeezeCode() const
QByteArray InstructionSelection::squeezeCode() const
{
int codeSize = _codeNext - _codeStart;
uchar *squeezed = new uchar[codeSize];
::memcpy(squeezed, _codeStart, codeSize);
QByteArray squeezed;
squeezed.resize(codeSize);
::memcpy(squeezed.data(), _codeStart, codeSize);
return squeezed;
}
@ -1085,3 +1100,28 @@ Instr::Param InstructionSelection::getParam(V4IR::Expr *e) {
return Param();
}
}
QV4::Function *CompilationUnit::linkBackendToEngine(QV4::ExecutionEngine *engine)
{
QV4::Function *rootRuntimeFunction = 0;
const QV4::CompiledData::Function *compiledRootFunction = data->functionAt(data->indexOfRootFunction);
for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
QV4::Function *runtimeFunction = runtimeFunctions.at(i);
const QV4::CompiledData::Function *compiledFunction = data->functionAt(i);
runtimeFunction->init(this, compiledFunction,
&VME::exec, /*size - doesn't matter for moth*/0);
runtimeFunction->codeData = reinterpret_cast<const uchar *>(codeRefs.at(i).constData());
if (compiledFunction == compiledRootFunction) {
assert(!rootRuntimeFunction);
rootRuntimeFunction = runtimeFunction;
}
}
return rootRuntimeFunction;
}

View File

@ -56,6 +56,15 @@ namespace Moth {
class StackSlotAllocator;
struct CompilationUnit : public QV4::CompiledData::CompilationUnit
{
virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine);
QVector<QByteArray> codeRefs;
};
class Q_QML_EXPORT InstructionSelection:
public V4IR::IRDecoder,
public EvalInstructionSelection
@ -67,6 +76,8 @@ public:
virtual void run(QV4::Function *vmFunction, V4IR::Function *function);
protected:
virtual QV4::CompiledData::CompilationUnit *backendCompileStep();
virtual void visitJump(V4IR::Jump *);
virtual void visitCJump(V4IR::CJump *);
virtual void visitRet(V4IR::Ret *);
@ -157,7 +168,7 @@ private:
inline ptrdiff_t addInstruction(const InstrData<Instr> &data);
ptrdiff_t addInstructionHelper(Instr::Type type, Instr &instr);
void patchJumpAddresses();
uchar *squeezeCode() const;
QByteArray squeezeCode() const;
QV4::String *identifier(const QString &s);
@ -175,6 +186,9 @@ private:
StackSlotAllocator *_stackSlotAllocator;
V4IR::Stmt *_currentStatement;
CompilationUnit *compilationUnit;
QHash<V4IR::Function *, QByteArray> codeRefs;
};
class Q_QML_EXPORT ISelFactory: public EvalISelFactory

View File

@ -80,7 +80,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 QV4::CompiledData::CompilationUnit *backendCompileStep() { return 0; }
virtual QV4::CompiledData::CompilationUnit *backendCompileStep() = 0;
private:
QV4::ExecutionEngine *_engine;

View File

@ -57,7 +57,6 @@ Function::~Function()
UnwindHelper::deregisterFunction(this); // ### move to masm compilation unit
Q_ASSERT(!refCount);
delete[] codeData;
foreach (Function *f, nestedFunctions)
f->deref();
if (compilationUnit)