aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-10-09 08:58:36 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2016-04-11 09:41:57 +0000
commitc810daa67536803905cdb1ba32a3dadfec95aa4c (patch)
treea7392c39dc7a288e8d40c80b5902efbc1366fa17 /src/qml
parent20dbb21f51f44f9b7e75960f8e36aead79c5ab55 (diff)
Start converting Runtime calls to 'vtable' calls
The old code was using absolute addressing for calls into methods of the Runtime. This produces non relocatable code, which is bad for caching. So instead, we'll have a table of function pointers for all runtime methods in the ExecutionEngine, and do the runtime calls through that table. Change-Id: I75c04f699ea11c38f742575f9ce264c0c5ad0c96 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/jit/qv4assembler_p.h22
-rw-r--r--src/qml/jit/qv4isel_masm.cpp5
-rw-r--r--src/qml/jit/qv4isel_masm_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h16
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
7 files changed, 46 insertions, 5 deletions
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index bf10dab446..957e8fc444 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -104,6 +104,12 @@ struct LookupCall {
{}
};
+struct RuntimeCall {
+ JSC::MacroAssembler::Address addr;
+
+ inline RuntimeCall(uint offset);
+};
+
template <typename T>
struct ExceptionCheck {
enum { NeedsCheck = 1 };
@@ -359,6 +365,17 @@ public:
call(lookupCall.addr);
}
+ void callAbsolute(const char *functionName, const RuntimeCall &runtimeCall)
+ {
+ call(runtimeCall.addr);
+ // the code below is to get proper function names in the disassembly
+ CallToLink ctl;
+ ctl.externalFunction = FunctionPtr();
+ ctl.functionName = functionName;
+ ctl.label = label();
+ _callsToLink.append(ctl);
+ }
+
void registerBlock(IR::BasicBlock*, IR::BasicBlock *nextBlock);
IR::BasicBlock *nextBlock() const { return _nextBlock; }
void jumpToBlock(IR::BasicBlock* current, IR::BasicBlock *target);
@@ -1232,6 +1249,11 @@ void Assembler::copyValue(Result result, IR::Expr* source)
}
}
+inline RuntimeCall::RuntimeCall(uint offset)
+ : addr(Assembler::EngineRegister, offset + qOffsetOf(QV4::ExecutionEngine, runtime))
+{
+}
+
template <typename T> inline bool prepareCall(T &, Assembler *)
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index bf658fe689..12635de94b 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -161,7 +161,8 @@ JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
QHash<void*, const char*> functions;
foreach (CallToLink ctl, _callsToLink) {
- linkBuffer.link(ctl.call, ctl.externalFunction);
+ if (ctl.externalFunction.value())
+ linkBuffer.link(ctl.call, ctl.externalFunction);
functions[linkBuffer.locationOf(ctl.label).dataLocation()] = ctl.functionName;
}
@@ -393,7 +394,7 @@ void InstructionSelection::callBuiltinInvalid(IR::Name *func, IR::ExprList *args
if (useFastLookups && func->global) {
uint index = registerGlobalGetterLookup(*func->id);
- generateFunctionCall(result, Runtime::callGlobalLookup,
+ generateRuntimeCall(result, callGlobalLookup,
Assembler::EngineRegister,
Assembler::TrustedImm32(index),
baseAddressForCallData());
diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h
index 366d510072..cdb6a8ada4 100644
--- a/src/qml/jit/qv4isel_masm_p.h
+++ b/src/qml/jit/qv4isel_masm_p.h
@@ -246,6 +246,8 @@ private:
#define generateFunctionCall(t, function, ...) \
_as->generateFunctionCallImp(t, isel_stringIfy(function), function, __VA_ARGS__)
+ #define generateRuntimeCall(t, function, ...) \
+ _as->generateFunctionCallImp(t, "Runtime::" isel_stringIfy(function), RuntimeCall(qOffsetOf(QV4::Runtime, function)), __VA_ARGS__)
int prepareVariableArguments(IR::ExprList* args);
int prepareCallData(IR::ExprList* args, IR::Expr *thisObject);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index f3f40ab9cb..57a5952a6d 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -110,6 +110,8 @@ public:
Value *jsStackLimit;
quintptr cStackLimit;
+ Runtime runtime;
+
WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine.
enum { JSStackLimit = 4*1024*1024 };
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 92971e2298..552e472cef 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -931,7 +931,7 @@ uint Runtime::compareIn(ExecutionEngine *engine, const Value &left, const Value
}
-ReturnedValue Runtime::callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData)
+ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData)
{
Scope scope(engine);
Q_ASSERT(callData->thisObject.isUndefined());
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index d431b9f4c8..d63a813a5a 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -47,9 +47,20 @@ namespace QV4 {
struct NoThrowEngine;
+#define RUNTIME_METHOD(returnvalue, name, args) \
+ typedef returnvalue (*Method_##name)args; \
+ static returnvalue method_##name args; \
+ const Method_##name name
+
+#define INIT_RUNTIME_METHOD(name) \
+ name(method_##name)
+
struct Q_QML_PRIVATE_EXPORT Runtime {
+ Runtime()
+ : INIT_RUNTIME_METHOD(callGlobalLookup)
+ { }
// call
- static ReturnedValue callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData);
+ RUNTIME_METHOD(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData));
static ReturnedValue callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData);
static ReturnedValue callQmlScopeObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData);
static ReturnedValue callQmlContextObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData);
@@ -186,6 +197,9 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
static void setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value);
};
+#undef RUNTIME_METHOD
+#undef INIT_RUNTIME_METHOD
+
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index ecbc243baa..70cf7bcbe0 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -638,7 +638,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::callGlobalLookup(engine, instr.index, callData));
+ STOREVALUE(instr.result, Runtime::method_callGlobalLookup(engine, instr.index, callData));
MOTH_END_INSTR(CallGlobalLookup)
MOTH_BEGIN_INSTR(SetExceptionHandler)