diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64Relocations.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64Relocations.cpp index 89e270123..70efc57a2 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64Relocations.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64Relocations.cpp @@ -57,7 +57,7 @@ Arm64JITCore::NamedSymbolLiteralPair Arm64JITCore::InsertNamedSymbolLiteral(FEXC return Lit; } -void Arm64JITCore::PlaceNamedSymbolLiteral(NamedSymbolLiteralPair& Lit) { +void Arm64JITCore::PlaceNamedSymbolLiteral(NamedSymbolLiteralPair Lit) { // Offset is the offset from the entrypoint of the block auto CurrentCursor = GetCursorAddress(); switch (Lit.MoveABI.Header.Type) { diff --git a/FEXCore/Source/Interface/Core/JIT/JIT.cpp b/FEXCore/Source/Interface/Core/JIT/JIT.cpp index b31ee39e8..3d0b70262 100644 --- a/FEXCore/Source/Interface/Core/JIT/JIT.cpp +++ b/FEXCore/Source/Interface/Core/JIT/JIT.cpp @@ -1001,9 +1001,7 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, uint64_t Size // Add the JitCodeTail Align(alignof(JITCodeTail)); - auto JITBlockTailLocation = GetCursorAddress(); - auto JITBlockTail = GetCursorAddress(); - CursorIncrement(sizeof(JITCodeTail)); + const auto JITBlockTailLocation = GetCursorAddress(); // Entries that live after the JITCodeTail. // These entries correlate JIT code regions with guest RIP regions. @@ -1021,23 +1019,27 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, uint64_t Size // FEXCore::Utils::vl64 GuestRIPOffset; // }; - auto JITRIPEntriesBegin = GetCursorAddress(); - // Put the block's RIP entry in the tail. // This will be used for RIP reconstruction in the future. - // TODO: This needs to be a data RIP relocation once code caching works. - // Current relocation code doesn't support this feature yet. - JITBlockTail->RIP = Entry; - JITBlockTail->GuestSize = Size; - JITBlockTail->SingleInst = SingleInst; - JITBlockTail->SpinLockFutex = 0; + JITCodeTail JITBlockTail { + .RIP = Entry, + .GuestSize = Size, + .SpinLockFutex = 0, + .SingleInst = SingleInst, + }; + // Delay tail write until all fields are initialized + CursorIncrement(sizeof(JITBlockTail)); + + const auto JITRIPEntriesBegin = GetCursorAddress(); auto JITRIPEntriesLocation = JITRIPEntriesBegin; + SetCursorOffset(JITRIPEntriesLocation - CodeData.BlockBegin); + { // Store the RIP entries. - JITBlockTail->NumberOfRIPEntries = DebugData->GuestOpcodes.size(); - JITBlockTail->OffsetToRIPEntries = JITRIPEntriesBegin - JITBlockTailLocation; + JITBlockTail.NumberOfRIPEntries = DebugData->GuestOpcodes.size(); + JITBlockTail.OffsetToRIPEntries = JITRIPEntriesBegin - JITBlockTailLocation; uintptr_t CurrentRIPOffset = 0; uint64_t CurrentPCOffset = 0; @@ -1060,7 +1062,15 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, uint64_t Size CodeData.Size = GetCursorAddress() - CodeData.BlockBegin; - JITBlockTail->Size = CodeData.Size; + // Finalize block tail data + JITBlockTail.Size = CodeData.Size; + { + auto PrevCur = GetCursorOffset(); + memcpy(JITBlockTailLocation, &JITBlockTail, sizeof(JITBlockTail)); + SetCursorOffset(JITBlockTailLocation - CodeData.BlockBegin + offsetof(JITCodeTail, RIP)); + PlaceNamedSymbolLiteral(InsertGuestRIPLiteral(JITBlockTail.RIP)); + SetCursorOffset(PrevCur); + } // Migrate the compile output from temporary storage to the actual CodeBuffer. // This can block progress in other compiling threads, so the duration of the lock should be as small as possible. diff --git a/FEXCore/Source/Interface/Core/JIT/JITClass.h b/FEXCore/Source/Interface/Core/JIT/JITClass.h index d1193e976..fd5fc3a22 100644 --- a/FEXCore/Source/Interface/Core/JIT/JITClass.h +++ b/FEXCore/Source/Interface/Core/JIT/JITClass.h @@ -587,7 +587,7 @@ private: * * @param Lit - Which literal to place */ - void PlaceNamedSymbolLiteral(NamedSymbolLiteralPair& Lit); + void PlaceNamedSymbolLiteral(NamedSymbolLiteralPair Lit); fextl::vector Relocations;