diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-11-27 14:21:44 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-11-30 09:17:28 +0000 |
commit | 6f9e578ce8d7b27a5160f70600e0bbe878ed7947 (patch) | |
tree | c90d0f5beac40ef6f082a85544b70d3cdc158bd0 /src/qml/jit | |
parent | 0b64810ada26ea1e7d19342f05f97e870ed1db1b (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.cpp | 36 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4jit.cpp | 64 |
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) |