aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-08-15 12:48:05 +0200
committerLars Knoll <lars.knoll@digia.com>2013-08-15 15:28:37 +0200
commit7b2c9178b93fc31779c05553dcc48930d66342e2 (patch)
tree939b3247eeac5a1c480c80ce7bffda23980940bf
parentab44ecae18bba8aa09c6c12c37aca8f6df454cdc (diff)
Ported lookups to use the compiled data infrastructure
Change-Id: Idf75cd51087ea825f22aabda59661be461fd3b86 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qv4compileddata.cpp23
-rw-r--r--src/qml/compiler/qv4compileddata_p.h20
-rw-r--r--src/qml/compiler/qv4compiler.cpp37
-rw-r--r--src/qml/compiler/qv4compiler_p.h8
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp68
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h5
-rw-r--r--src/qml/compiler/qv4isel_p.h3
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4function.cpp1
-rw-r--r--src/qml/jsruntime/qv4function_p.h3
-rw-r--r--src/qml/jsruntime/qv4script.cpp2
11 files changed, 98 insertions, 76 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index a1a355b10f..c4d75090f8 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -43,6 +43,7 @@
#include "qv4jsir_p.h"
#include <private/qv4engine_p.h>
#include <private/qv4function_p.h>
+#include <private/qv4lookup_p.h>
namespace QV4 {
@@ -57,6 +58,7 @@ CompilationUnit::~CompilationUnit()
{
free(data);
free(runtimeStrings);
+ delete [] runtimeLookups;
}
QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
@@ -67,6 +69,27 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
for (int i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i)->qString());
+ if (data->lookupTableSize) {
+ runtimeLookups = new QV4::Lookup[data->lookupTableSize];
+ const CompiledData::Lookup *compiledLookups = data->lookupTable();
+ for (uint i = 0; i < data->lookupTableSize; ++i) {
+ QV4::Lookup *l = runtimeLookups + i;
+
+ if (compiledLookups[i].type_and_flags == CompiledData::Lookup::Type_Getter)
+ l->getter = QV4::Lookup::getterGeneric;
+ else if (compiledLookups[i].type_and_flags == CompiledData::Lookup::Type_Setter)
+ l->setter = QV4::Lookup::setterGeneric;
+ else if (compiledLookups[i].type_and_flags == CompiledData::Lookup::Type_GlobalGetter)
+ l->globalGetter = QV4::Lookup::globalGetterGeneric;
+
+ for (int i = 0; i < QV4::Lookup::Size; ++i)
+ l->classList[i] = 0;
+ l->level = -1;
+ l->index = UINT_MAX;
+ l->name = runtimeStrings[compiledLookups[i].nameIndex];
+ }
+ }
+
return linkBackendToEngine(engine);
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index c9d552036d..de5c82beed 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -64,6 +64,7 @@ namespace CompiledData {
struct String;
struct Function;
+struct Lookup;
static const char magic_str[] = "qv4cdata";
@@ -82,6 +83,8 @@ struct Unit
uint offsetToStringTable;
uint functionTableSize;
uint offsetToFunctionTable;
+ uint lookupTableSize;
+ uint offsetToLookupTable;
uint indexOfRootFunction;
quint32 sourceFileIndex;
@@ -97,6 +100,8 @@ struct Unit
return reinterpret_cast<const Function*>(reinterpret_cast<const char *>(this) + offset);
}
+ const Lookup *lookupTable() const { return reinterpret_cast<const Lookup*>(reinterpret_cast<const char *>(this) + offsetToLookupTable); }
+
static int calculateSize(uint nStrings, uint nFunctions) { return (sizeof(Unit) + (nStrings + nFunctions) * sizeof(uint) + 7) & ~7; }
};
@@ -150,6 +155,19 @@ struct String
}
};
+struct Lookup
+{
+ enum Type {
+ Type_Getter = 0x0,
+ Type_Setter = 0x1,
+ Type_GlobalGetter = 2
+ };
+
+ quint32 type_and_flags;
+ quint32 nameIndex;
+
+ static int calculateSize() { return sizeof(Lookup); }
+};
// Qml data structures
@@ -240,6 +258,7 @@ struct CompilationUnit
: refCount(0)
, data(0)
, runtimeStrings(0)
+ , runtimeLookups(0)
{}
virtual ~CompilationUnit();
@@ -252,6 +271,7 @@ struct CompilationUnit
QString fileName() const { return data->stringAt(data->sourceFileIndex)->qString(); }
QV4::String **runtimeStrings; // Array
+ QV4::Lookup *runtimeLookups;
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 07687cca17..135c8679f1 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -67,6 +67,33 @@ int QV4::Compiler::JSUnitGenerator::getStringId(const QString &string) const
return stringToId.value(string);
}
+uint QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name)
+{
+ CompiledData::Lookup l;
+ l.type_and_flags = CompiledData::Lookup::Type_Getter;
+ l.nameIndex = registerString(name);
+ lookups << l;
+ return lookups.size() - 1;
+}
+
+uint QV4::Compiler::JSUnitGenerator::registerSetterLookup(const QString &name)
+{
+ CompiledData::Lookup l;
+ l.type_and_flags = CompiledData::Lookup::Type_Setter;
+ l.nameIndex = registerString(name);
+ lookups << l;
+ return lookups.size() - 1;
+}
+
+uint QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(const QString &name)
+{
+ CompiledData::Lookup l;
+ l.type_and_flags = CompiledData::Lookup::Type_GlobalGetter;
+ l.nameIndex = registerString(name);
+ lookups << l;
+ return lookups.size() - 1;
+}
+
QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
{
registerString(irModule->fileName);
@@ -87,7 +114,9 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
functionDataSize += QV4::CompiledData::Function::calculateSize(f);
}
- char *data = (char *)malloc(unitSize + functionDataSize + stringDataSize);
+ const uint lookupDataSize = CompiledData::Lookup::calculateSize() * lookups.count();
+
+ char *data = (char *)malloc(unitSize + functionDataSize + stringDataSize + lookupDataSize);
QV4::CompiledData::Unit *unit = (QV4::CompiledData::Unit*)data;
memcpy(unit->magic, QV4::CompiledData::magic_str, sizeof(unit->magic));
@@ -98,6 +127,8 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
unit->offsetToStringTable = sizeof(QV4::CompiledData::Unit);
unit->functionTableSize = irModule->functions.size();
unit->offsetToFunctionTable = unit->offsetToStringTable + unit->stringTableSize * sizeof(uint);
+ unit->lookupTableSize = lookups.count();
+ unit->offsetToLookupTable = unitSize + stringDataSize + functionDataSize;
unit->sourceFileIndex = getStringId(irModule->fileName);
// write strings and string table
@@ -134,6 +165,10 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit()
f += QV4::CompiledData::Function::calculateSize(function);
}
+ CompiledData::Lookup *lookupsToWrite = (CompiledData::Lookup*)(data + unit->offsetToLookupTable);
+ foreach (const CompiledData::Lookup &l, lookups)
+ *lookupsToWrite++ = l;
+
return unit;
}
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index 661bcd1093..e7385a0174 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -50,6 +50,7 @@ namespace QV4 {
namespace CompiledData {
struct Unit;
+struct Lookup;
}
namespace Compiler {
@@ -62,13 +63,18 @@ struct JSUnitGenerator {
int registerString(const QString &str);
int getStringId(const QString &string) const;
+ uint registerGetterLookup(const QString &name);
+ uint registerSetterLookup(const QString &name);
+ uint registerGlobalGetterLookup(const QString &name);
+
QV4::CompiledData::Unit *generateUnit();
void writeFunction(char *f, int index, QQmlJS::V4IR::Function *irFunction);
QHash<QString, int> stringToId;
QStringList strings;
- QHash<QQmlJS::V4IR::Function *, uint> functionOffsets;
int stringDataSize;
+ QHash<QQmlJS::V4IR::Function *, uint> functionOffsets;
+ QList<CompiledData::Lookup> lookups;
};
}
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index cfc2247b20..8b3025b5f5 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -695,7 +695,6 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
QSet<V4IR::BasicBlock*> reentryBlocks;
qSwap(_function, function);
qSwap(_vmFunction, vmFunction);
- qSwap(_lookups, lookups);
qSwap(_reentryBlocks, reentryBlocks);
Assembler* oldAssembler = _as;
_as = new Assembler(this, _function, _vmFunction, engine());
@@ -759,16 +758,10 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
JSC::MacroAssemblerCodeRef codeRef =_as->link(_vmFunction);
codeRefs[_function] = codeRef;
- if (_lookups.size()) {
- _vmFunction->lookups = new Lookup[_lookups.size()];
- memcpy(_vmFunction->lookups, _lookups.constData(), _lookups.size()*sizeof(Lookup));
- }
-
UnwindHelper::registerFunction(_vmFunction);
qSwap(_vmFunction, vmFunction);
qSwap(_function, function);
- qSwap(_lookups, lookups);
qSwap(_reentryBlocks, reentryBlocks);
qSwap(_locals, locals);
delete _as;
@@ -793,8 +786,7 @@ void InstructionSelection::callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *
int argc = prepareVariableArguments(args);
if (useFastLookups && func->global) {
- QV4::String *s = identifier(*func->id);
- uint index = addGlobalLookup(s);
+ uint index = registerGlobalGetterLookup(*func->id);
generateFunctionCall(Assembler::Void, __qmljs_call_global_lookup,
Assembler::ContextRegister, Assembler::PointerToValue(result),
Assembler::TrustedImm32(index),
@@ -1073,8 +1065,7 @@ void InstructionSelection::loadRegexp(V4IR::RegExp *sourceRegexp, V4IR::Temp *ta
void InstructionSelection::getActivationProperty(const V4IR::Name *name, V4IR::Temp *temp)
{
if (useFastLookups && name->global) {
- String *propertyName = identifier(*name->id);
- uint index = addGlobalLookup(propertyName);
+ uint index = registerGlobalGetterLookup(*name->id);
generateLookupCall(index, offsetof(QV4::Lookup, globalGetter), Assembler::ContextRegister, Assembler::PointerToValue(temp));
return;
}
@@ -1097,8 +1088,7 @@ void InstructionSelection::initClosure(V4IR::Closure *closure, V4IR::Temp *targe
void InstructionSelection::getProperty(V4IR::Temp *base, const QString &name, V4IR::Temp *target)
{
if (useFastLookups) {
- QV4::String *s = identifier(name);
- uint index = addLookup(s);
+ uint index = registerGetterLookup(name);
generateLookupCall(index, offsetof(QV4::Lookup, getter), Assembler::PointerToValue(target),
Assembler::Reference(base));
} else {
@@ -1110,8 +1100,7 @@ void InstructionSelection::getProperty(V4IR::Temp *base, const QString &name, V4
void InstructionSelection::setProperty(V4IR::Temp *source, V4IR::Temp *targetBase, const QString &targetName)
{
if (useFastLookups) {
- QV4::String *s = identifier(targetName);
- uint index = addSetterLookup(s);
+ uint index = registerSetterLookup(targetName);
generateLookupCall(index, offsetof(QV4::Lookup, setter), Assembler::Reference(targetBase), Assembler::Reference(source));
} else {
generateFunctionCall(Assembler::Void, __qmljs_set_property, Assembler::ContextRegister,
@@ -1260,8 +1249,7 @@ void InstructionSelection::callProperty(V4IR::Temp *base, const QString &name,
int argc = prepareVariableArguments(args);
if (useFastLookups) {
- QV4::String *s = identifier(name);
- uint index = addLookup(s);
+ uint index = registerGetterLookup(name);
generateFunctionCall(Assembler::Void, __qmljs_call_property_lookup,
Assembler::ContextRegister, Assembler::PointerToValue(result),
Assembler::Reference(base), Assembler::TrustedImm32(index),
@@ -1307,9 +1295,7 @@ void InstructionSelection::constructActivationProperty(V4IR::Name *func, V4IR::E
if (useFastLookups && func->global) {
int argc = prepareVariableArguments(args);
- QV4::String *s = identifier(*func->id);
-
- uint index = addGlobalLookup(s);
+ uint index = registerGlobalGetterLookup(*func->id);
generateFunctionCall(Assembler::Void, __qmljs_construct_global_lookup,
Assembler::ContextRegister, Assembler::PointerToValue(result),
Assembler::TrustedImm32(index),
@@ -1472,45 +1458,3 @@ void InstructionSelection::callRuntimeMethodImp(V4IR::Temp *result, const char*
Assembler::TrustedImm32(argc));
}
-
-uint InstructionSelection::addLookup(QV4::String *name)
-{
- uint index = (uint)_lookups.size();
- QV4::Lookup l;
- l.getter = Lookup::getterGeneric;
- for (int i = 0; i < Lookup::Size; ++i)
- l.classList[i] = 0;
- l.level = -1;
- l.index = UINT_MAX;
- l.name = name;
- _lookups.append(l);
- return index;
-}
-
-uint InstructionSelection::addSetterLookup(QV4::String *name)
-{
- uint index = (uint)_lookups.size();
- QV4::Lookup l;
- l.setter = Lookup::setterGeneric;
- for (int i = 0; i < Lookup::Size; ++i)
- l.classList[i] = 0;
- l.level = -1;
- l.index = UINT_MAX;
- l.name = name;
- _lookups.append(l);
- return index;
-}
-
-uint InstructionSelection::addGlobalLookup(QV4::String *name)
-{
- uint index = (uint)_lookups.size();
- QV4::Lookup l;
- l.globalGetter = Lookup::globalGetterGeneric;
- for (int i = 0; i < Lookup::Size; ++i)
- l.classList[i] = 0;
- l.level = -1;
- l.index = UINT_MAX;
- l.name = name;
- _lookups.append(l);
- return index;
-}
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index b67386dacc..517a50f570 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -923,10 +923,6 @@ private:
#define callRuntimeMethod(result, function, ...) \
callRuntimeMethodImp(result, isel_stringIfy(function), function, __VA_ARGS__)
- uint addLookup(QV4::String *name);
- uint addSetterLookup(QV4::String *name);
- uint addGlobalLookup(QV4::String *name);
-
template <typename Arg1, typename Arg2>
void generateLookupCall(uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
{
@@ -950,7 +946,6 @@ private:
V4IR::BasicBlock *_block;
V4IR::Function* _function;
QV4::Function* _vmFunction;
- QVector<QV4::Lookup> _lookups;
Assembler* _as;
QSet<V4IR::BasicBlock*> _reentryBlocks;
int _locals;
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index 1e1d72d0ec..24ad5812f0 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -70,6 +70,9 @@ public:
void setUseFastLookups(bool b) { useFastLookups = b; }
int stringId(const QString &str) { return jsUnitGenerator.registerString(str); }
+ uint registerGetterLookup(const QString &str) { return jsUnitGenerator.registerGetterLookup(str); }
+ uint registerSetterLookup(const QString &str) { return jsUnitGenerator.registerSetterLookup(str); }
+ uint registerGlobalGetterLookup(const QString &str) { return jsUnitGenerator.registerGlobalGetterLookup(str); }
protected:
QV4::Function *createFunctionMapping(QV4::Function *outer, V4IR::Function *irFunction);
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index f6ba986a27..57d559b3ff 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -175,7 +175,7 @@ void CallContext::initCallContext(ExecutionContext *parentContext, FunctionObjec
activation = 0;
if (function->function) {
- lookups = function->function->lookups;
+ lookups = function->function->compilationUnit->runtimeLookups;
runtimeStrings = function->function->compilationUnit->runtimeStrings;
}
@@ -223,7 +223,7 @@ void CallContext::initQmlContext(ExecutionContext *parentContext, Object *qml, F
activation = qml;
- lookups = function->function->lookups;
+ lookups = function->function->compilationUnit->runtimeLookups;
runtimeStrings = function->function->compilationUnit->runtimeStrings;
locals = (Value *)(this + 1);
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 58d2cdd275..24ea1fbb32 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -58,7 +58,6 @@ Function::~Function()
Q_ASSERT(!refCount);
delete[] codeData;
- delete[] lookups;
foreach (Function *f, nestedFunctions)
f->deref();
if (compilationUnit)
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 34e570fed0..eacd7d1d7a 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -102,8 +102,6 @@ struct Function {
QVector<String *> identifiers;
QVector<Function *> nestedFunctions;
- Lookup *lookups;
-
QVector<LineNumberMapping> lineNumberMappings;
ExecutionEngine *engine;
@@ -116,7 +114,6 @@ struct Function {
, code(0)
, codeData(0)
, codeSize(0)
- , lookups(0)
, engine(engine)
{}
~Function();
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 59b52c395b..70ab3d4d1d 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -205,7 +205,7 @@ Value Script::run()
String **oldRuntimeStrings = scope->runtimeStrings;
scope->strictMode = vmFunction->isStrict();
- scope->lookups = vmFunction->lookups;
+ scope->lookups = vmFunction->compilationUnit->runtimeLookups;
scope->runtimeStrings = vmFunction->compilationUnit->runtimeStrings;
QV4::Value result;