aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-11-27 14:21:44 +0100
committerLars Knoll <lars.knoll@qt.io>2017-11-30 09:17:28 +0000
commit6f9e578ce8d7b27a5160f70600e0bbe878ed7947 (patch)
treec90d0f5beac40ef6f082a85544b70d3cdc158bd0 /src/qml/jit
parent0b64810ada26ea1e7d19342f05f97e870ed1db1b (diff)
JIT: Inline load(Scoped)Local and store(Scoped)Local instructions
Generate inline code for loading and storing (scoped) locals in the JIT. Change-Id: I6eb72126a0a2c6012bf6e73df245c9301bd4c48d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jit')
-rw-r--r--src/qml/jit/qv4assembler.cpp36
-rw-r--r--src/qml/jit/qv4assembler_p.h2
-rw-r--r--src/qml/jit/qv4jit.cpp64
3 files changed, 35 insertions, 67 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index ee1f1e8673..b0470ed89d 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -660,11 +660,11 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
void copyReg(Address src, Address dst)
{
- loadReg(src, ScratchRegister);
+ load64(src, ScratchRegister);
store64(ScratchRegister, dst);
}
- void loadReg(Address addr, RegisterID dest = AccumulatorRegister)
+ void loadPointerFromValue(Address addr, RegisterID dest = AccumulatorRegister)
{
load64(addr, dest);
}
@@ -878,11 +878,9 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
storeDouble(FPScratchRegister, dest);
}
- void loadReg(Address addr)
+ void loadPointerFromValue(Address addr, RegisterID dest = AccumulatorRegisterValue)
{
- load32(addr, AccumulatorRegisterValue);
- addr.offset += 4;
- load32(addr, AccumulatorRegisterTag);
+ load32(addr, dest);
}
void loadAccumulator(Address src)
@@ -1281,7 +1279,7 @@ void Assembler::copyConst(int constIndex, int destReg)
void Assembler::loadReg(int reg)
{
- pasm()->loadReg(regAddr(reg));
+ pasm()->loadAccumulator(regAddr(reg));
}
void Assembler::storeReg(int reg)
@@ -1289,6 +1287,30 @@ void Assembler::storeReg(int reg)
pasm()->storeAccumulator(regAddr(reg));
}
+void Assembler::loadLocal(int index, int level)
+{
+ Heap::CallContext ctx;
+ Q_UNUSED(ctx)
+ pasm()->loadPointerFromValue(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
+ while (level) {
+ pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
+ --level;
+ }
+ pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
+}
+
+void Assembler::storeLocal(int index, int level)
+{
+ Heap::CallContext ctx;
+ Q_UNUSED(ctx)
+ pasm()->loadPtr(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
+ while (level) {
+ pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
+ --level;
+ }
+ pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
+}
+
void Assembler::loadString(int stringId)
{
pasm()->loadString(stringId);
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index eafe27c8bb..5cd64096b1 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -91,6 +91,8 @@ public:
void copyConst(int constIndex, int destReg);
void loadReg(int reg);
void storeReg(int reg);
+ void loadLocal(int index, int level = 0);
+ void storeLocal(int index, int level = 0);
void loadString(int stringId);
void loadValue(ReturnedValue value);
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index 3de03e5327..42ee1ff5df 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -172,82 +172,26 @@ void BaselineJIT::generate_MoveReg(int srcReg, int destReg)
as->storeReg(destReg);
}
-static ReturnedValue loadLocalHelper(const Value &context, int index)
-{
- auto cc = static_cast<Heap::CallContext *>(context.m());
- return cc->locals[uint(index)].asReturnedValue();
-}
-
void BaselineJIT::generate_LoadLocal(int index)
{
- as->prepareCallWithArgCount(2);
- as->passInt32AsArg(index, 1);
- as->passRegAsArg(CallData::Context, 0);
- JIT_GENERATE_RUNTIME_CALL(loadLocalHelper, Assembler::ResultInAccumulator);
-}
-
-static void storeLocalHelper(ExecutionEngine *engine, const Value &context, int index, const Value &acc)
-{
- auto cc = static_cast<Heap::CallContext *>(context.m());
- QV4::WriteBarrier::write(engine, cc, cc->locals.values + index, acc);
+ as->loadLocal(index);
}
void BaselineJIT::generate_StoreLocal(int index)
{
as->checkException();
- as->prepareCallWithArgCount(4);
- STORE_ACC();
- as->passAccumulatorAsArg(3);
- as->passInt32AsArg(index, 2);
- as->passRegAsArg(CallData::Context, 1);
- as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(storeLocalHelper, Assembler::IgnoreResult);
-}
-
-static inline Heap::CallContext *getScope(Value *stack, int level)
-{
- Heap::ExecutionContext *scope = static_cast<ExecutionContext &>(stack[CallData::Context]).d();
- while (level > 0) {
- --level;
- scope = scope->outer;
- }
- Q_ASSERT(scope);
- return static_cast<Heap::CallContext *>(scope);
-}
-
-static ReturnedValue loadScopedLocalHelper(Value *stack, int scope, int index)
-{
- auto cc = getScope(stack, scope);
- return cc->locals[uint(index)].asReturnedValue();
+ as->storeLocal(index);
}
void BaselineJIT::generate_LoadScopedLocal(int scope, int index)
{
- as->prepareCallWithArgCount(3);
- as->passInt32AsArg(index, 2);
- as->passInt32AsArg(scope, 1);
- as->passRegAsArg(0, 0);
- JIT_GENERATE_RUNTIME_CALL(loadScopedLocalHelper, Assembler::ResultInAccumulator);
-}
-
-static void storeScopedLocalHelper(ExecutionEngine *engine, Value *stack, int scope, int index,
- const Value &acc)
-{
- auto cc = getScope(stack, scope);
- QV4::WriteBarrier::write(engine, cc, cc->locals.values + index, acc);
+ as->loadLocal(index, scope);
}
void BaselineJIT::generate_StoreScopedLocal(int scope, int index)
{
as->checkException();
- as->prepareCallWithArgCount(5);
- STORE_ACC();
- as->passAccumulatorAsArg(4);
- as->passInt32AsArg(index, 3);
- as->passInt32AsArg(scope, 2);
- as->passRegAsArg(0, 1);
- as->passEngineAsArg(0);
- JIT_GENERATE_RUNTIME_CALL(storeScopedLocalHelper, Assembler::IgnoreResult);
+ as->storeLocal(index, scope);
}
void BaselineJIT::generate_LoadRuntimeString(int stringId)