#include <QVector>
#include <QStringList>
#include <private/qv4value_def_p.h>
+#include <private/qv4executableallocator_p.h>
QT_BEGIN_NAMESPACE
};
QV4::Value (*code)(ExecutionContext *, const uchar *);
+ quint32 index; // in CompilationUnit's function table
quint32 nameIndex;
quint32 sourceFileIndex;
qint64 flags;
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
+ virtual QV4::ExecutableAllocator::ChunkOfPages *chunkForFunction(int /*functionIndex*/) { return 0; }
// ### runtime data
// pointer to qml data for QML unit
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;
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;
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
{
}
-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)
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)
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)
# 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)
}
}
- _as->link(_vmFunction);
+ JSC::MacroAssemblerCodeRef codeRef =_as->link(_vmFunction);
+ codeRefs[_function] = codeRef;
if (_lookups.size()) {
_vmFunction->lookups = new Lookup[_lookups.size()];
{
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;
}
#include <config.h>
#include <wtf/Vector.h>
#include <assembler/MacroAssembler.h>
+#include <assembler/MacroAssemblerCodeRef.h>
QT_BEGIN_NAMESPACE
{
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
return Jump();
}
- void link(QV4::Function *vmFunc);
+ JSC::MacroAssemblerCodeRef link(QV4::Function *vmFunc);
void recordLineNumber(int lineNumber);
int _locals;
CompilationUnit *compilationUnit;
+ QHash<V4IR::Function*, JSC::MacroAssemblerCodeRef> codeRefs;
};
class Q_QML_EXPORT ISelFactory: public EvalISelFactory
#include <QtCore/qurl.h>
#include <config.h>
-#include <assembler/MacroAssemblerCodeRef.h>
#include "qv4value_def_p.h"
#include <private/qv4compileddata_p.h>
CompiledData::CompilationUnit *compilationUnit;
Value (*code)(ExecutionContext *, const uchar *);
const uchar *codeData;
- JSC::MacroAssemblerCodeRef codeRef;
quint32 codeSize;
QVector<String *> formals;
#include <wtf/Platform.h>
#include <wtf/PageAllocation.h>
#include <ExecutableAllocator.h>
+#include <private/qv4isel_masm_p.h>
#include <QMap>
#include <QMutex>
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)