Merge pull request #4531 from lioncash/access
EmuCodeBlock: Make nearcode and farcode protected
This commit is contained in:
commit
cee1f8b6e7
|
@ -246,7 +246,7 @@ void Jit64::Init()
|
||||||
// important: do this *after* generating the global asm routines, because we can't use farcode in
|
// important: do this *after* generating the global asm routines, because we can't use farcode in
|
||||||
// them.
|
// them.
|
||||||
// it'll crash because the farcode functions get cleared on JIT clears.
|
// it'll crash because the farcode functions get cleared on JIT clears.
|
||||||
farcode.Init(jo.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
m_far_code.Init(jo.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
code_block.m_stats = &js.st;
|
code_block.m_stats = &js.st;
|
||||||
|
@ -259,7 +259,7 @@ void Jit64::ClearCache()
|
||||||
{
|
{
|
||||||
blocks.Clear();
|
blocks.Clear();
|
||||||
trampolines.ClearCodeSpace();
|
trampolines.ClearCodeSpace();
|
||||||
farcode.ClearCodeSpace();
|
m_far_code.ClearCodeSpace();
|
||||||
ClearCodeSpace();
|
ClearCodeSpace();
|
||||||
Clear();
|
Clear();
|
||||||
UpdateMemoryOptions();
|
UpdateMemoryOptions();
|
||||||
|
@ -273,7 +273,7 @@ void Jit64::Shutdown()
|
||||||
blocks.Shutdown();
|
blocks.Shutdown();
|
||||||
trampolines.Shutdown();
|
trampolines.Shutdown();
|
||||||
asm_routines.Shutdown();
|
asm_routines.Shutdown();
|
||||||
farcode.Shutdown();
|
m_far_code.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::FallBackToInterpreter(UGeckoInstruction inst)
|
void Jit64::FallBackToInterpreter(UGeckoInstruction inst)
|
||||||
|
@ -542,8 +542,8 @@ void Jit64::Jit(u32 em_address)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAlmostFull() || farcode.IsAlmostFull() || trampolines.IsAlmostFull() || blocks.IsFull() ||
|
if (IsAlmostFull() || m_far_code.IsAlmostFull() || trampolines.IsAlmostFull() ||
|
||||||
SConfig::GetInstance().bJITNoBlockCache)
|
blocks.IsFull() || SConfig::GetInstance().bJITNoBlockCache)
|
||||||
{
|
{
|
||||||
ClearCache();
|
ClearCache();
|
||||||
}
|
}
|
||||||
|
@ -877,12 +877,12 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
if (!js.fastmemLoadStore)
|
if (!js.fastmemLoadStore)
|
||||||
{
|
{
|
||||||
exceptionHandlerAtLoc[js.fastmemLoadStore] = nullptr;
|
m_exception_handler_at_loc[js.fastmemLoadStore] = nullptr;
|
||||||
SetJumpTarget(js.fixupExceptionHandler ? js.exceptionHandler : memException);
|
SetJumpTarget(js.fixupExceptionHandler ? js.exceptionHandler : memException);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exceptionHandlerAtLoc[js.fastmemLoadStore] = GetWritableCodePtr();
|
m_exception_handler_at_loc[js.fastmemLoadStore] = GetWritableCodePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
BitSet32 gprToFlush = BitSet32::AllTrue(32);
|
BitSet32 gprToFlush = BitSet32::AllTrue(32);
|
||||||
|
|
|
@ -72,14 +72,14 @@ void EmuCodeBlock::MemoryExceptionCheck()
|
||||||
|
|
||||||
void EmuCodeBlock::SwitchToFarCode()
|
void EmuCodeBlock::SwitchToFarCode()
|
||||||
{
|
{
|
||||||
nearcode = GetWritableCodePtr();
|
m_near_code = GetWritableCodePtr();
|
||||||
SetCodePtr(farcode.GetWritableCodePtr());
|
SetCodePtr(m_far_code.GetWritableCodePtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuCodeBlock::SwitchToNearCode()
|
void EmuCodeBlock::SwitchToNearCode()
|
||||||
{
|
{
|
||||||
farcode.SetCodePtr(GetWritableCodePtr());
|
m_far_code.SetCodePtr(GetWritableCodePtr());
|
||||||
SetCodePtr(nearcode);
|
SetCodePtr(m_near_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_addr,
|
FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_addr,
|
||||||
|
@ -110,7 +110,7 @@ FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_
|
||||||
if (scratch == reg_addr)
|
if (scratch == reg_addr)
|
||||||
POP(scratch);
|
POP(scratch);
|
||||||
|
|
||||||
return J_CC(CC_Z, farcode.Enabled());
|
return J_CC(CC_Z, m_far_code.Enabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuCodeBlock::UnsafeLoadRegToReg(X64Reg reg_addr, X64Reg reg_value, int accessSize, s32 offset,
|
void EmuCodeBlock::UnsafeLoadRegToReg(X64Reg reg_addr, X64Reg reg_value, int accessSize, s32 offset,
|
||||||
|
@ -344,7 +344,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
||||||
MovInfo mov;
|
MovInfo mov;
|
||||||
bool offsetAddedToAddress =
|
bool offsetAddedToAddress =
|
||||||
UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend, &mov);
|
UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend, &mov);
|
||||||
TrampolineInfo& info = backPatchInfo[mov.address];
|
TrampolineInfo& info = m_back_patch_info[mov.address];
|
||||||
info.pc = jit->js.compilerPC;
|
info.pc = jit->js.compilerPC;
|
||||||
info.nonAtomicSwapStoreSrc = mov.nonAtomicSwapStore ? mov.nonAtomicSwapStoreSrc : INVALID_REG;
|
info.nonAtomicSwapStoreSrc = mov.nonAtomicSwapStore ? mov.nonAtomicSwapStoreSrc : INVALID_REG;
|
||||||
info.start = backpatchStart;
|
info.start = backpatchStart;
|
||||||
|
@ -391,7 +391,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
||||||
{
|
{
|
||||||
FixupBranch slow = CheckIfSafeAddress(R(reg_value), reg_addr, registersInUse);
|
FixupBranch slow = CheckIfSafeAddress(R(reg_value), reg_addr, registersInUse);
|
||||||
UnsafeLoadToReg(reg_value, R(reg_addr), accessSize, 0, signExtend);
|
UnsafeLoadToReg(reg_value, R(reg_addr), accessSize, 0, signExtend);
|
||||||
if (farcode.Enabled())
|
if (m_far_code.Enabled())
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
else
|
else
|
||||||
exit = J(true);
|
exit = J(true);
|
||||||
|
@ -429,7 +429,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
||||||
|
|
||||||
if (fast_check_address)
|
if (fast_check_address)
|
||||||
{
|
{
|
||||||
if (farcode.Enabled())
|
if (m_far_code.Enabled())
|
||||||
{
|
{
|
||||||
exit = J(true);
|
exit = J(true);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
@ -502,7 +502,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
||||||
u8* backpatchStart = GetWritableCodePtr();
|
u8* backpatchStart = GetWritableCodePtr();
|
||||||
MovInfo mov;
|
MovInfo mov;
|
||||||
UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, swap, &mov);
|
UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, swap, &mov);
|
||||||
TrampolineInfo& info = backPatchInfo[mov.address];
|
TrampolineInfo& info = m_back_patch_info[mov.address];
|
||||||
info.pc = jit->js.compilerPC;
|
info.pc = jit->js.compilerPC;
|
||||||
info.nonAtomicSwapStoreSrc = mov.nonAtomicSwapStore ? mov.nonAtomicSwapStoreSrc : INVALID_REG;
|
info.nonAtomicSwapStoreSrc = mov.nonAtomicSwapStore ? mov.nonAtomicSwapStoreSrc : INVALID_REG;
|
||||||
info.start = backpatchStart;
|
info.start = backpatchStart;
|
||||||
|
@ -546,7 +546,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
||||||
{
|
{
|
||||||
FixupBranch slow = CheckIfSafeAddress(reg_value, reg_addr, registersInUse);
|
FixupBranch slow = CheckIfSafeAddress(reg_value, reg_addr, registersInUse);
|
||||||
UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, 0, swap);
|
UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, 0, swap);
|
||||||
if (farcode.Enabled())
|
if (m_far_code.Enabled())
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
else
|
else
|
||||||
exit = J(true);
|
exit = J(true);
|
||||||
|
@ -592,7 +592,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
||||||
|
|
||||||
if (fast_check_address)
|
if (fast_check_address)
|
||||||
{
|
{
|
||||||
if (farcode.Enabled())
|
if (m_far_code.Enabled())
|
||||||
{
|
{
|
||||||
exit = J(true);
|
exit = J(true);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
@ -1142,6 +1142,6 @@ void EmuCodeBlock::SetFPRF(Gen::X64Reg xmm)
|
||||||
|
|
||||||
void EmuCodeBlock::Clear()
|
void EmuCodeBlock::Clear()
|
||||||
{
|
{
|
||||||
backPatchInfo.clear();
|
m_back_patch_info.clear();
|
||||||
exceptionHandlerAtLoc.clear();
|
m_exception_handler_at_loc.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,6 @@ class Mapping;
|
||||||
class EmuCodeBlock : public Gen::X64CodeBlock
|
class EmuCodeBlock : public Gen::X64CodeBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FarCodeCache farcode;
|
|
||||||
u8* nearcode; // Backed up when we switch to far code.
|
|
||||||
|
|
||||||
void MemoryExceptionCheck();
|
void MemoryExceptionCheck();
|
||||||
|
|
||||||
// Simple functions to switch between near and far code emitting
|
// Simple functions to switch between near and far code emitting
|
||||||
|
@ -108,6 +105,9 @@ public:
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unordered_map<u8*, TrampolineInfo> backPatchInfo;
|
FarCodeCache m_far_code;
|
||||||
std::unordered_map<u8*, u8*> exceptionHandlerAtLoc;
|
u8* m_near_code; // Backed up when we switch to far code.
|
||||||
|
|
||||||
|
std::unordered_map<u8*, TrampolineInfo> m_back_patch_info;
|
||||||
|
std::unordered_map<u8*, u8*> m_exception_handler_at_loc;
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,8 +44,8 @@ bool Jitx86Base::BackPatch(u32 emAddress, SContext* ctx)
|
||||||
if (!IsInSpace(codePtr))
|
if (!IsInSpace(codePtr))
|
||||||
return false; // this will become a regular crash real soon after this
|
return false; // this will become a regular crash real soon after this
|
||||||
|
|
||||||
auto it = backPatchInfo.find(codePtr);
|
auto it = m_back_patch_info.find(codePtr);
|
||||||
if (it == backPatchInfo.end())
|
if (it == m_back_patch_info.end())
|
||||||
{
|
{
|
||||||
PanicAlert("BackPatch: no register use entry for address %p", codePtr);
|
PanicAlert("BackPatch: no register use entry for address %p", codePtr);
|
||||||
return false;
|
return false;
|
||||||
|
@ -56,8 +56,8 @@ bool Jitx86Base::BackPatch(u32 emAddress, SContext* ctx)
|
||||||
u8* exceptionHandler = nullptr;
|
u8* exceptionHandler = nullptr;
|
||||||
if (jit->jo.memcheck)
|
if (jit->jo.memcheck)
|
||||||
{
|
{
|
||||||
auto it2 = exceptionHandlerAtLoc.find(codePtr);
|
auto it2 = m_exception_handler_at_loc.find(codePtr);
|
||||||
if (it2 != exceptionHandlerAtLoc.end())
|
if (it2 != m_exception_handler_at_loc.end())
|
||||||
exceptionHandler = it2->second;
|
exceptionHandler = it2->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,7 +266,7 @@ void JitIL::Init()
|
||||||
blocks.Init();
|
blocks.Init();
|
||||||
asm_routines.Init(nullptr);
|
asm_routines.Init(nullptr);
|
||||||
|
|
||||||
farcode.Init(jo.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
m_far_code.Init(jo.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
code_block.m_stats = &js.st;
|
code_block.m_stats = &js.st;
|
||||||
|
@ -283,7 +283,7 @@ void JitIL::ClearCache()
|
||||||
{
|
{
|
||||||
blocks.Clear();
|
blocks.Clear();
|
||||||
trampolines.ClearCodeSpace();
|
trampolines.ClearCodeSpace();
|
||||||
farcode.ClearCodeSpace();
|
m_far_code.ClearCodeSpace();
|
||||||
ClearCodeSpace();
|
ClearCodeSpace();
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ void JitIL::Shutdown()
|
||||||
blocks.Shutdown();
|
blocks.Shutdown();
|
||||||
trampolines.Shutdown();
|
trampolines.Shutdown();
|
||||||
asm_routines.Shutdown();
|
asm_routines.Shutdown();
|
||||||
farcode.Shutdown();
|
m_far_code.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::FallBackToInterpreter(UGeckoInstruction _inst)
|
void JitIL::FallBackToInterpreter(UGeckoInstruction _inst)
|
||||||
|
@ -465,8 +465,8 @@ void JitIL::Trace()
|
||||||
|
|
||||||
void JitIL::Jit(u32 em_address)
|
void JitIL::Jit(u32 em_address)
|
||||||
{
|
{
|
||||||
if (IsAlmostFull() || farcode.IsAlmostFull() || trampolines.IsAlmostFull() || blocks.IsFull() ||
|
if (IsAlmostFull() || m_far_code.IsAlmostFull() || trampolines.IsAlmostFull() ||
|
||||||
SConfig::GetInstance().bJITNoBlockCache)
|
blocks.IsFull() || SConfig::GetInstance().bJITNoBlockCache)
|
||||||
{
|
{
|
||||||
ClearCache();
|
ClearCache();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue