diff options
| author | Simon Hausmann <simon.hausmann@digia.com> | 2013-08-15 10:36:41 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-08-15 13:56:07 +0200 |
| commit | 4b0765da3e2842612ed5464bb750505f0d355b87 (patch) | |
| tree | dc19ee6b99956619337280ce1db3c1c230cf74be /src | |
| parent | 2aee966baa76f55d9061ed22af7bb0abe4f3541e (diff) | |
Prepare MASM for better runtime string handling
Keep the run-time functions as-is by taking String pointers and use a little
bit of inline assembly to resolve the string ids to string pointers, by
adding a runtimeStrings array pointer next to the lookups in the context
(similar mechanism).
Change-Id: Ib5a70bdf47fef7c447d646ccfe03f3dc30d39f20
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 8 | ||||
| -rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 4 | ||||
| -rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 16 | ||||
| -rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 23 | ||||
| -rw-r--r-- | src/qml/compiler/qv4isel_p.h | 4 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 7 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 2 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 11 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4runtime_p.h | 3 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 7 |
10 files changed, 57 insertions, 28 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 2a39f6237d..a1a355b10f 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -56,16 +56,16 @@ int Function::calculateSize(QQmlJS::V4IR::Function *f) CompilationUnit::~CompilationUnit() { free(data); - free(runtimeIdentifiers); + free(runtimeStrings); } QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine) { - assert(!runtimeIdentifiers); + assert(!runtimeStrings); assert(data); - runtimeIdentifiers = (QV4::String**)malloc(data->stringTableSize * sizeof(QV4::String*)); + runtimeStrings = (QV4::String**)malloc(data->stringTableSize * sizeof(QV4::String*)); for (int i = 0; i < data->stringTableSize; ++i) - runtimeIdentifiers[i] = engine->newIdentifier(data->stringAt(i)->qString()); + runtimeStrings[i] = engine->newIdentifier(data->stringAt(i)->qString()); return linkBackendToEngine(engine); } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index c70fa6986f..c9d552036d 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -239,7 +239,7 @@ struct CompilationUnit CompilationUnit() : refCount(0) , data(0) - , runtimeIdentifiers(0) + , runtimeStrings(0) {} virtual ~CompilationUnit(); @@ -251,7 +251,7 @@ struct CompilationUnit QString fileName() const { return data->stringAt(data->sourceFileIndex)->qString(); } - QV4::String **runtimeIdentifiers; // Array + QV4::String **runtimeStrings; // Array QV4::Function *linkToEngine(QV4::ExecutionEngine *engine); diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index 29f2343d34..248dc78e52 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -208,8 +208,8 @@ const int Assembler::calleeSavedRegisterCount = sizeof(calleeSavedRegisters) / s const Assembler::VoidType Assembler::Void; -Assembler::Assembler(V4IR::Function* function, QV4::Function *vmFunction, QV4::ExecutionEngine *engine) - : _function(function), _vmFunction(vmFunction), _engine(engine), _nextBlock(0) +Assembler::Assembler(InstructionSelection *isel, V4IR::Function* function, QV4::Function *vmFunction, QV4::ExecutionEngine *engine) + : _function(function), _vmFunction(vmFunction), _isel(isel), _engine(engine), _nextBlock(0) { } @@ -281,6 +281,13 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID reg, V4IR::Temp *t) return Pointer(reg, offset); } +Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &string) +{ + loadPtr(Address(Assembler::ContextRegister, offsetof(QV4::ExecutionContext, runtimeStrings)), reg); + const int id = _isel->stringId(string); + return Pointer(reg, id * sizeof(QV4::String*)); +} + template <typename Result, typename Source> void Assembler::copyValue(Result result, Source source) { @@ -691,7 +698,7 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi qSwap(_lookups, lookups); qSwap(_reentryBlocks, reentryBlocks); Assembler* oldAssembler = _as; - _as = new Assembler(_function, _vmFunction, engine()); + _as = new Assembler(this, _function, _vmFunction, engine()); V4IR::Optimizer opt(_function); opt.run(); @@ -1052,8 +1059,7 @@ void InstructionSelection::loadConst(V4IR::Const *sourceConst, V4IR::Temp *targe void InstructionSelection::loadString(const QString &str, V4IR::Temp *targetTemp) { - int id = stringId(str); - generateFunctionCall(Assembler::Void, __qmljs_resolve_string_as_value, Assembler::ContextRegister, Assembler::PointerToValue(targetTemp), Assembler::TrustedImm32(id)); + generateFunctionCall(Assembler::Void, __qmljs_value_from_string, Assembler::PointerToValue(targetTemp), Assembler::PointerToString(str)); } void InstructionSelection::loadRegexp(V4IR::RegExp *sourceRegexp, V4IR::Temp *targetTemp) diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index 8c55f410fc..b67386dacc 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE namespace QQmlJS { namespace MASM { +class InstructionSelection; + struct CompilationUnit : public QV4::CompiledData::CompilationUnit { virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine); @@ -74,7 +76,7 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit class Assembler : public JSC::MacroAssembler { public: - Assembler(V4IR::Function* function, QV4::Function *vmFunction, QV4::ExecutionEngine *engine); + Assembler(InstructionSelection *isel, V4IR::Function* function, QV4::Function *vmFunction, QV4::ExecutionEngine *engine); #if CPU(X86) #undef VALUE_FITS_IN_REGISTER @@ -258,6 +260,10 @@ public: PointerToValue(V4IR::Temp *value) : value(value) {} V4IR::Temp *value; }; + struct PointerToString { + explicit PointerToString(const QString &string) : string(string) {} + QString string; + }; struct Reference { Reference(V4IR::Temp *value) : value(value) {} V4IR::Temp *value; @@ -287,6 +293,7 @@ public: void addPatch(DataLabelPtr patch, V4IR::BasicBlock *target); Pointer loadTempAddress(RegisterID reg, V4IR::Temp *t); + Pointer loadStringAddress(RegisterID reg, const QString &string); void loadArgumentInRegister(RegisterID source, RegisterID dest) { @@ -312,6 +319,11 @@ public: loadArgumentInRegister(addr, dest); } } + void loadArgumentInRegister(PointerToString temp, RegisterID dest) + { + Pointer addr = loadStringAddress(dest, temp.string); + loadPtr(addr, dest); + } void loadArgumentInRegister(Reference temp, RegisterID dest) { @@ -432,6 +444,14 @@ public: } template <int StackSlot> + void loadArgumentOnStack(PointerToString temp) + { + Pointer ptr = loadStringAddress(ScratchRegister, temp.string); + loadPtr(ptr, ScratchRegister); + poke(ScratchRegister, StackSlot); + } + + template <int StackSlot> void loadArgumentOnStack(Reference temp) { assert (temp.value); @@ -780,6 +800,7 @@ private: V4IR::BasicBlock *_nextBlock; QV4::ExecutionEngine *_engine; + InstructionSelection *_isel; struct CodeLineNumerMapping { diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index ef0cd06969..1e1d72d0ec 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -69,14 +69,14 @@ public: void setUseFastLookups(bool b) { useFastLookups = b; } + int stringId(const QString &str) { return jsUnitGenerator.registerString(str); } + 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; } - int stringId(const QString &str) { return jsUnitGenerator.registerString(str); } - private: QV4::ExecutionEngine *_engine; protected: diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 633ad2e067..f6ba986a27 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -138,6 +138,7 @@ void WithContext::initWithContext(ExecutionContext *p, Object *with) thisObject = p->thisObject; outer = p; lookups = p->lookups; + runtimeStrings = p->runtimeStrings; withObject = with; } @@ -149,6 +150,7 @@ void CatchContext::initCatchContext(ExecutionContext *p, String *exceptionVarNam thisObject = p->thisObject; outer = p; lookups = p->lookups; + runtimeStrings = p->runtimeStrings; this->exceptionVarName = exceptionVarName; this->exceptionValue = exceptionValue; @@ -172,8 +174,10 @@ void CallContext::initCallContext(ExecutionContext *parentContext, FunctionObjec activation = 0; - if (function->function) + if (function->function) { lookups = function->function->lookups; + runtimeStrings = function->function->compilationUnit->runtimeStrings; + } uint argc = argumentCount; @@ -220,6 +224,7 @@ void CallContext::initQmlContext(ExecutionContext *parentContext, Object *qml, F activation = qml; lookups = function->function->lookups; + runtimeStrings = function->function->compilationUnit->runtimeStrings; locals = (Value *)(this + 1); if (function->varCount) diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index dfe02bdcc8..3bae120098 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -94,6 +94,7 @@ struct Q_QML_EXPORT ExecutionContext ExecutionContext *parent; ExecutionContext *outer; Lookup *lookups; + String **runtimeStrings; ExecutionContext *next; // used in the GC struct EvalCode @@ -115,6 +116,7 @@ struct Q_QML_EXPORT ExecutionContext parent = parentContext; outer = 0; lookups = 0; + runtimeStrings = 0; currentEvalCode = 0; interpreterInstructionPointer = 0; } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 210a6c4085..8dcf65a0da 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1221,16 +1221,9 @@ void __qmljs_decrement(Value *result, const Value &value) } } -String *__qmljs_resolve_string(ExecutionContext *ctx, int stringId) +void __qmljs_value_from_string(Value *result, String *string) { - QV4::CallContext *callCtx = ctx->asCallContext(); - QV4::Function *fun = callCtx ? callCtx->function->function : ctx->engine->globalCode; - return fun->compilationUnit->runtimeIdentifiers[stringId]; -} - -void __qmljs_resolve_string_as_value(ExecutionContext *ctx, Value *result, int stringId) -{ - *result = Value::fromString(__qmljs_resolve_string(ctx, stringId)); + *result = Value::fromString(string); } } // namespace QV4 diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index 6cac1118b6..31ee819b84 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -126,8 +126,7 @@ void __qmljs_builtin_define_array(QV4::ExecutionContext *ctx, QV4::Value *array, void __qmljs_builtin_define_getter_setter(QV4::ExecutionContext *ctx, const QV4::Value &object, QV4::String *name, const QV4::Value *getter, const QV4::Value *setter); void __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value *args, QV4::InternalClass *klass); -QV4::String *__qmljs_resolve_string(QV4::ExecutionContext *ctx, int stringId); -void __qmljs_resolve_string_as_value(QV4::ExecutionContext *ctx, QV4::Value *result, int stringId); +void __qmljs_value_from_string(QV4::Value *result, QV4::String *string); // constructors void __qmljs_init_closure(QV4::ExecutionContext *ctx, QV4::Value *result, QV4::Function *clos); diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 448d63860d..59b52c395b 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -201,17 +201,20 @@ Value Script::run() TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction); bool strict = scope->strictMode; - Lookup *lookups = scope->lookups; + Lookup *oldLookups = scope->lookups; + String **oldRuntimeStrings = scope->runtimeStrings; scope->strictMode = vmFunction->isStrict(); scope->lookups = vmFunction->lookups; + scope->runtimeStrings = vmFunction->compilationUnit->runtimeStrings; QV4::Value result; try { result = vmFunction->code(scope, vmFunction->codeData); } catch (Exception &e) { scope->strictMode = strict; - scope->lookups = lookups; + scope->lookups = oldLookups; + scope->runtimeStrings = oldRuntimeStrings; throw; } |
