diff --git a/Source/Core/Common/Src/x64Emitter.h b/Source/Core/Common/Src/x64Emitter.h index b05b0812c8..316101380e 100644 --- a/Source/Core/Common/Src/x64Emitter.h +++ b/Source/Core/Common/Src/x64Emitter.h @@ -687,6 +687,11 @@ public: region_size = 0; } + bool IsInCodeSpace(u8 *ptr) + { + return ptr >= region && ptr < region + region_size; + } + // Cannot currently be undone. Will write protect the entire code region. // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). void WriteProtect() diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp index b9e1539352..6a936da136 100644 --- a/Source/Core/Core/Src/MemTools.cpp +++ b/Source/Core/Core/Src/MemTools.cpp @@ -63,10 +63,8 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0]; if (accessType == 8) //Rule out DEP { - if(PowerPC::state == PowerPC::CPU_POWERDOWN) // Access violation during - // violent shutdown is fine - return EXCEPTION_CONTINUE_EXECUTION; - + if (PowerPC::state == PowerPC::CPU_POWERDOWN) + return EXCEPTION_CONTINUE_SEARCH; MessageBox(0, _T("Tried to execute code that's not marked executable. This is likely a JIT bug.\n"), 0, 0); return EXCEPTION_CONTINUE_SEARCH; } @@ -75,7 +73,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) PVOID codeAddr = pPtrs->ExceptionRecord->ExceptionAddress; unsigned char *codePtr = (unsigned char*)codeAddr; - if (!jit.IsInJitCode(codePtr)) { + if (!jit.IsInCodeSpace(codePtr)) { // Let's not prevent debugging. return (DWORD)EXCEPTION_CONTINUE_SEARCH; } @@ -91,8 +89,9 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) u64 memspaceTop = memspaceBottom + 0x40000000; #endif if (badAddress < memspaceBottom || badAddress >= memspaceTop) { - PanicAlert("Exception handler - access outside memory space. %08x%08x", - badAddress >> 32, badAddress); + return (DWORD)EXCEPTION_CONTINUE_SEARCH; + //PanicAlert("Exception handler - access outside memory space. %08x%08x", + // badAddress >> 32, badAddress); } u32 emAddress = (u32)(badAddress - memspaceBottom); @@ -199,7 +198,7 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) #else u8 *fault_instruction_ptr = (u8 *)CREG_EIP(ctx); #endif - if (!jit.IsInJitCode((const u8 *)fault_instruction_ptr)) { + if (!jit.IsInCodeSpace((const u8 *)fault_instruction_ptr)) { // Let's not prevent debugging. return; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index ff27283b82..87ebd695e1 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -179,7 +179,7 @@ namespace CPUCompare } jo.optimizeStack = true; - jo.enableBlocklink = true; // Speed boost, but not 100% safe + jo.enableBlocklink = false; // Speed boost, but not 100% safe #ifdef _M_X64 jo.enableFastMem = Core::GetStartupParameter().bUseFastMem; #else @@ -437,11 +437,12 @@ namespace CPUCompare gpr.SanityCheck(); fpr.SanityCheck(); - if (js.cancel) break; + if (js.cancel) + break; } b.flags = js.block_flags; - b.codeSize = (u32)(GetCodePtr() - start); + b.codeSize = (u32)(GetCodePtr() - normalEntry); b.originalSize = size; return normalEntry; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 55e06fe4ba..17d6e4fc15 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -63,29 +63,7 @@ public: class Jit64 : public Gen::XCodeBlock { - TrampolineCache trampolines; - GPRRegCache gpr; - FPURegCache fpr; - public: - typedef void (*CompiledCode)(); - - void unknown_instruction(UGeckoInstruction _inst); - - //Code pointers are stored separately, they will be accessed much more frequently - - enum BlockFlag - { - BLOCK_USE_GQR0 = 0x1, - BLOCK_USE_GQR1 = 0x2, - BLOCK_USE_GQR2 = 0x4, - BLOCK_USE_GQR3 = 0x8, - BLOCK_USE_GQR4 = 0x10, - BLOCK_USE_GQR5 = 0x20, - BLOCK_USE_GQR6 = 0x40, - BLOCK_USE_GQR7 = 0x80, - }; - // TODO(ector) - optimize this struct for size struct JitBlock { @@ -109,7 +87,13 @@ public: bool invalid; int flags; }; - +private: + enum BlockFlag + { + BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8, + BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80, + }; + struct JitState { u32 compilerPC; @@ -146,11 +130,40 @@ public: bool fastInterrupts; }; + + TrampolineCache trampolines; + GPRRegCache gpr; + FPURegCache fpr; + + u8 **blockCodePointers; + + std::multimap links_to; + + JitBlock *blocks; + int numBlocks; + +public: + typedef void (*CompiledCode)(); + JitState js; JitOptions jo; + // Initialization, etc + + void Init(); + void Shutdown(); + void PrintStats(); + + // Jit! + + const u8* Jit(u32 emaddress); + const u8* DoJit(u32 emaddress, JitBlock &b); + + // Run! + void EnterFastRun(); + const u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx); // Code Cache @@ -173,18 +186,9 @@ public: void ResetCache(); void DestroyBlock(int blocknum, bool invalidate); bool RangeIntersect(int s1, int e1, int s2, int e2) const; - bool IsInJitCode(const u8 *codePtr); - - const u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx); #define JIT_OPCODE 0 - const u8* Jit(u32 emaddress); - const u8* DoJit(u32 emaddress, JitBlock &b); - - void Init(); - void Shutdown(); - // Utilities for use by opcodes void WriteExit(u32 destination, int exit_num); @@ -214,7 +218,7 @@ public: // OPCODES - + void unknown_instruction(UGeckoInstruction _inst); void Default(UGeckoInstruction _inst); void DoNothing(UGeckoInstruction _inst); void HLEFunction(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp index 73b6175f45..569c2f4d73 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp @@ -147,7 +147,7 @@ const u8 *TrampolineCache::GetWriteTrampoline(const InstructionInfo &info) const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx) { #ifdef _M_X64 - if (!IsInJitCode(codePtr)) + if (!jit.IsInCodeSpace(codePtr)) return 0; // this will become a regular crash real soon after this InstructionInfo info; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp index 2220665667..26a95f7cd7 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp @@ -55,9 +55,7 @@ using namespace Gen; #ifdef OPROFILE_REPORT op_agent_t agent; #endif - static u8 *codeCache; - static u8 *trampolineCache; - u8 *trampolineCodePtr; + #define INVALID_EXIT 0xFFFFFFFF enum @@ -67,13 +65,6 @@ using namespace Gen; int MAX_NUM_BLOCKS = 65536*2; - static u8 **blockCodePointers; - - static std::multimap links_to; - - static Jit64::JitBlock *blocks; - static int numBlocks; - void Jit64::PrintStats() { @@ -233,10 +224,6 @@ using namespace Gen; return blockCodePointers; } - bool Jit64::IsInJitCode(const u8 *codePtr) { - return codePtr >= codeCache && codePtr <= GetCodePtr(); - } - void Jit64::EnterFastRun() { CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; @@ -293,10 +280,6 @@ using namespace Gen; return (CompiledCode)blockCodePointers[blockNumber]; } - int Jit64::GetCodeSize() { - return (int)(GetCodePtr() - codeCache); - } - //Block linker //Make sure to have as many blocks as possible compiled before calling this //It's O(N), so it's fast :) diff --git a/Source/Core/DebuggerWX/Src/JitWindow.cpp b/Source/Core/DebuggerWX/Src/JitWindow.cpp index 4b8de3a64c..81c57e7328 100644 --- a/Source/Core/DebuggerWX/Src/JitWindow.cpp +++ b/Source/Core/DebuggerWX/Src/JitWindow.cpp @@ -141,12 +141,26 @@ void CJitWindow::Compare(u32 em_address) int block_num = jit.GetBlockNumberFromAddress(em_address); if (block_num < 0) { - ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", em_address).c_str())); - x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str())); - return; + for (int i = 0; i < 500; i++) { + block_num = jit.GetBlockNumberFromAddress(em_address - 4 * i); + if (block_num >= 0) + break; + } + if (block_num >= 0) { + Jit64::JitBlock *block = jit.GetBlock(block_num); + if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address)) + block_num = -1; + } + // Do not merge this "if" with the above - block_num changes inside it. + if (block_num < 0) { + ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", em_address).c_str())); + x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str())); + return; + } } Jit64::JitBlock *block = jit.GetBlock(block_num); + // 800031f0 // == Fill in x86 box memset(xDis, 0, 65536);