From 7b2c9178b93fc31779c05553dcc48930d66342e2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 15 Aug 2013 12:48:05 +0200 Subject: Ported lookups to use the compiled data infrastructure Change-Id: Idf75cd51087ea825f22aabda59661be461fd3b86 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4compileddata.cpp | 23 ++++++++++++ src/qml/compiler/qv4compileddata_p.h | 20 +++++++++++ src/qml/compiler/qv4compiler.cpp | 37 +++++++++++++++++++- src/qml/compiler/qv4compiler_p.h | 8 ++++- src/qml/compiler/qv4isel_masm.cpp | 68 ++++-------------------------------- src/qml/compiler/qv4isel_masm_p.h | 5 --- src/qml/compiler/qv4isel_p.h | 3 ++ src/qml/jsruntime/qv4context.cpp | 4 +-- src/qml/jsruntime/qv4function.cpp | 1 - src/qml/jsruntime/qv4function_p.h | 3 -- src/qml/jsruntime/qv4script.cpp | 2 +- 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 #include +#include 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(reinterpret_cast(this) + offset); } + const Lookup *lookupTable() const { return reinterpret_cast(reinterpret_cast(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 stringToId; QStringList strings; - QHash functionOffsets; int stringDataSize; + QHash functionOffsets; + QList 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 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 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 _lookups; Assembler* _as; QSet _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 identifiers; QVector nestedFunctions; - Lookup *lookups; - QVector 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; -- cgit v1.2.3