aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-08-15 10:36:41 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-08-15 13:56:07 +0200
commit4b0765da3e2842612ed5464bb750505f0d355b87 (patch)
treedc19ee6b99956619337280ce1db3c1c230cf74be /src
parent2aee966baa76f55d9061ed22af7bb0abe4f3541e (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.cpp8
-rw-r--r--src/qml/compiler/qv4compileddata_p.h4
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp16
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h23
-rw-r--r--src/qml/compiler/qv4isel_p.h4
-rw-r--r--src/qml/jsruntime/qv4context.cpp7
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp11
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h3
-rw-r--r--src/qml/jsruntime/qv4script.cpp7
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;
}