From 7efa1e60d24fee9b1745c30965949af78f3fb0f3 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Mar 2017 14:26:07 +0100 Subject: Fix running of 32-bit JIT code generated on 64-bit hosts The offsets of members encoded in JIT generated code differ between 32-bit and 64-bit architectures. This patch moves some of the ExecutionEngine members into a separate standard-layout EngineBase class (in line with the same class in commit 2a554434a571dcefd26cf10ef8c5ae8b3b7d66db and subject to merging). By ensuring that the members are stored at pointer intervals, we can translate from host pointer size to target when generating the code. Task-number: QTBUG-58666 Change-Id: I1c38a7da059826848b80fd9972ed073214501386 Reviewed-by: Qt CI Bot Reviewed-by: Lars Knoll --- src/qml/jit/qv4assembler.cpp | 10 +++++----- src/qml/jit/qv4assembler_p.h | 14 ++++++++++---- src/qml/jit/qv4isel_masm.cpp | 4 ++-- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index ad8a5823e2..263f332f33 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -269,7 +269,7 @@ typename Assembler::Pointer Assembler: { int32_t offset = 0; int scope = al->scope; - loadPtr(Address(EngineRegister, qOffsetOf(ExecutionEngine, current)), baseReg); + loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(EngineBase, current))), baseReg); if (scope) { loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, outer)), baseReg); --scope; @@ -298,7 +298,7 @@ typename Assembler::Pointer Assembler: template typename Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &string) { - loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), Assembler::ScratchRegister); + loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), Assembler::ScratchRegister); loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, compilationUnit)), Assembler::ScratchRegister); loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg); const int id = _jsGenerator->registerString(string); @@ -314,7 +314,7 @@ typename Assembler::Address Assembler: template typename Assembler::Address Assembler::loadConstant(const Primitive &v, RegisterID baseReg) { - loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), baseReg); + loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), baseReg); loadPtr(Address(baseReg, qOffsetOf(QV4::Heap::ExecutionContext, constantTable)), baseReg); const int index = _jsGenerator->registerConstant(v.asReturnedValue()); return Address(baseReg, index * sizeof(QV4::Value)); @@ -518,9 +518,9 @@ void Assembler::returnFromFunction(IR::Ret *s, RegisterInfo const int locals = stackLayout().calculateJSStackFrameSize(); subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister); - loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); + loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister); loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, engine)), JITTargetPlatform::ScratchRegister); - storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop))); + storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop)))); leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave); ret(); diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 720c522e1d..0a27ab02cf 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -713,6 +713,12 @@ public: using JITTargetPlatform::platformFinishEnteringStandardStackFrame; using JITTargetPlatform::platformLeaveStandardStackFrame; + static qint32 targetStructureOffset(qint32 hostOffset) + { + Q_ASSERT(hostOffset % QT_POINTER_SIZE == 0); + return (hostOffset * RegisterSize) / QT_POINTER_SIZE; + } + using RegisterSizeDependentOps = RegisterSizeDependentAssembler, MacroAssembler, JITTargetPlatform, RegisterSize>; struct LookupCall { @@ -1249,7 +1255,7 @@ public: const RegisterInformation &fpRegistersToSave); void checkException() { - load32(Address(EngineRegister, qOffsetOf(QV4::ExecutionEngine, hasException)), ScratchRegister); + load32(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, hasException))), ScratchRegister); Jump exceptionThrown = branch32(RelationalCondition::NotEqual, ScratchRegister, TrustedImm32(0)); if (catchBlock) addPatch(catchBlock, exceptionThrown); @@ -1317,7 +1323,7 @@ public: // IMPORTANT! See generateLookupCall in qv4isel_masm_p.h for details! // load the table from the context - loadPtr(Address(EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), ScratchRegister); + loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), ScratchRegister); loadPtr(Address(ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, lookups)), lookupCall.addr.base); // pre-calculate the indirect address for the lookupCall table: @@ -1616,9 +1622,9 @@ public: const int locals = _stackLayout->calculateJSStackFrameSize(); if (locals <= 0) return; - loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(ExecutionEngine, jsStackTop)), JITTargetPlatform::LocalsRegister); + loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))), JITTargetPlatform::LocalsRegister); RegisterSizeDependentOps::initializeLocalVariables(this, locals); - storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, qOffsetOf(ExecutionEngine, jsStackTop))); + storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop)))); } Label exceptionReturnLabel; diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 69d6951bb9..3cbed3ce56 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -132,7 +132,7 @@ void InstructionSelection::run(int functionIndex) for (IR::Stmt *s : _block->statements()) { if (s->location.isValid()) { if (int(s->location.startLine) != lastLine) { - _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); + _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister); Address lineAddr(JITTargetPlatform::ScratchRegister, qOffsetOf(QV4::ExecutionContext::Data, lineNumber)); _as->store32(TrustedImm32(s->location.startLine), lineAddr); lastLine = s->location.startLine; @@ -447,7 +447,7 @@ void InstructionSelection::callValue(IR::Expr *value, IR::ExprList template void InstructionSelection::loadThisObject(IR::Expr *temp) { - _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister); + _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister); _as->loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, callData)), JITTargetPlatform::ScratchRegister); _as->copyValue(temp, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(CallData, thisObject))); } -- cgit v1.2.3