From 9029fdcaa69d498c9607d794df41cbcbf1d1c767 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 22 May 2020 13:02:17 +0200 Subject: JIT: Don't pass the heap object in the return value register We have two variants for call destination results: Ignore or store in accumulator. The accumulator may be the same as the return value register. Therefore, when side stepping this mechanism and leaving the result in the return value register, we should have realized that we have to save/load the accumulator. We didn't and left the accumulator clobbered. A further fix actually clears the accumulator proactively after each call with Ignore if it is the same as the return value register. Now we don't get our result anymore in this case. To fix this, just use the accumulator register, declare that we do so, and save/load it around the call. Change-Id: I65fe4f7430ebfc419863b329bcd66a95875e5ffb Reviewed-by: Lars Knoll --- src/qml/jit/qv4baselineassembler.cpp | 2 +- src/qml/jit/qv4baselinejit.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp index 73e396890e..3a46500423 100644 --- a/src/qml/jit/qv4baselineassembler.cpp +++ b/src/qml/jit/qv4baselineassembler.cpp @@ -920,7 +920,7 @@ void BaselineAssembler::loadValue(ReturnedValue value) void BaselineAssembler::storeHeapObject(int reg) { - pasm()->storeHeapObject(PlatformAssembler::ReturnValueRegisterValue, regAddr(reg)); + pasm()->storeHeapObject(PlatformAssembler::AccumulatorRegisterValue, regAddr(reg)); } void BaselineAssembler::loadImport(int index) diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp index 51cd15099d..ff48c734db 100644 --- a/src/qml/jit/qv4baselinejit.cpp +++ b/src/qml/jit/qv4baselinejit.cpp @@ -567,10 +567,12 @@ void BaselineJIT::generate_SetException() { as->setException(); } void BaselineJIT::generate_CreateCallContext() { + as->saveAccumulatorInFrame(); as->prepareCallWithArgCount(1); as->passCppFrameAsArg(0); - BASELINEJIT_GENERATE_RUNTIME_CALL(ExecutionContext::newCallContext, CallResultDestination::Ignore); // keeps result in return value register + BASELINEJIT_GENERATE_RUNTIME_CALL(ExecutionContext::newCallContext, CallResultDestination::InAccumulator); as->storeHeapObject(CallData::Context); + as->loadAccumulatorFromFrame(); } void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); } @@ -582,9 +584,10 @@ void BaselineJIT::generate_PushWithContext() as->prepareCallWithArgCount(2); as->passJSSlotAsArg(0, 1); as->passEngineAsArg(0); - BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createWithContext, CallResultDestination::Ignore); // keeps result in return value register + BASELINEJIT_GENERATE_RUNTIME_CALL(Runtime::method_createWithContext, CallResultDestination::InAccumulator); as->checkException(); as->storeHeapObject(CallData::Context); + as->loadAccumulatorFromFrame(); } void BaselineJIT::generate_PushBlockContext(int index) -- cgit v1.2.3