Merge pull request #9727 from hrydgard/arm64-jitcache-fix

ARM64: Don't rewrite the dispatcher when clearing the code cache
This commit is contained in:
Henrik Rydgård 2017-05-26 16:41:35 +02:00 committed by GitHub
commit 4b46bb4ecf
20 changed files with 54 additions and 38 deletions

View File

@ -302,7 +302,7 @@ const u8* ARM64XEmitter::AlignCode16()
{
int c = int((u64)m_code & 15);
if (c)
ReserveCodeSpace(16-c);
ReserveCodeSpace(16 - c);
return m_code;
}
@ -509,7 +509,7 @@ void ARM64XEmitter::EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const voi
distance >>= 2;
_assert_msg_(DYNA_REC, distance >= -0x3FFF && distance < 0x3FFF, "%s: Received too large distance: %llx", __FUNCTION__, distance);
_assert_msg_(DYNA_REC, distance >= -0x1FFF && distance < 0x1FFF, "%s: Received too large distance: %llx", __FUNCTION__, distance);
Rt = DecodeReg(Rt);
Write32((b64Bit << 31) | (0x36 << 24) | (op << 24) | \
@ -3896,4 +3896,15 @@ void ARM64XEmitter::SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
}
}
void ARM64CodeBlock::PoisonMemory(int offset) {
u32* ptr = (u32*)(region + offset);
u32* maxptr = (u32*)(region + region_size - offset);
// If our memory isn't a multiple of u32 then this won't write the last remaining bytes with anything
// Less than optimal, but there would be nothing we could do but throw a runtime warning anyway.
// AArch64: 0xD4200000 = BRK 0
while (ptr < maxptr)
*ptr++ = 0xD4200000;
FlushIcacheSection((u8 *)ptr, (u8 *)maxptr);
}
} // namespace

View File

@ -985,15 +985,6 @@ private:
class ARM64CodeBlock : public CodeBlock<ARM64XEmitter>
{
private:
void PoisonMemory() override
{
u32* ptr = (u32*)region;
u32* maxptr = (u32*)(region + region_size);
// If our memory isn't a multiple of u32 then this won't write the last remaining bytes with anything
// Less than optimal, but there would be nothing we could do but throw a runtime warning anyway.
// AArch64: 0xD4200000 = BRK 0
while (ptr < maxptr)
*ptr++ = 0xD4200000;
}
void PoisonMemory(int offset) override;
};
}

View File

@ -3211,10 +3211,10 @@ void ARMXEmitter::VCVTF16F32(ARMReg Dest, ARMReg Src) {
// Always clear code space with breakpoints, so that if someone accidentally executes
// uninitialized, it just breaks into the debugger.
void ARMXCodeBlock::PoisonMemory() {
void ARMXCodeBlock::PoisonMemory(int offset) {
// TODO: this isn't right for ARM!
memset(region, 0xCC, region_size);
ResetCodePtr();
memset(region + offset, 0xCC, region_size - offset);
ResetCodePtr(offset);
}
}

View File

@ -895,7 +895,7 @@ public:
class ARMXCodeBlock : public CodeBlock<ARMXEmitter> {
public:
void PoisonMemory() override;
void PoisonMemory(int offset) override;
};
// VFP Specific

View File

@ -42,7 +42,7 @@ template<class T> class CodeBlock : public CodeBlockCommon, public T, NonCopyabl
private:
// A privately used function to set the executable RAM space to something invalid.
// For debugging usefulness it should be used to set the RAM to a host specific breakpoint instruction
virtual void PoisonMemory() = 0;
virtual void PoisonMemory(int offset) = 0;
public:
CodeBlock() : writeStart_(nullptr) {}
@ -58,14 +58,13 @@ public:
// Always clear code space with breakpoints, so that if someone accidentally executes
// uninitialized, it just breaks into the debugger.
void ClearCodeSpace() {
void ClearCodeSpace(int offset) {
if (PlatformIsWXExclusive()) {
ProtectMemoryPages(region, region_size, MEM_PROT_READ | MEM_PROT_WRITE);
} else {
ProtectMemoryPages(region, region_size, MEM_PROT_READ | MEM_PROT_WRITE | MEM_PROT_EXEC);
}
PoisonMemory();
ResetCodePtr();
// If not WX Exclusive, no need to call ProtectMemoryPages because we never change the protection from RWX.
PoisonMemory(offset);
ResetCodePtr(offset);
}
// BeginWrite/EndWrite assume that we keep appending.
@ -109,8 +108,8 @@ public:
return T::GetCodePointer();
}
void ResetCodePtr() {
T::SetCodePointer(region);
void ResetCodePtr(int offset) {
T::SetCodePointer(region + offset);
}
size_t GetSpaceLeft() const {

View File

@ -17,6 +17,8 @@
#include "ppsspp_config.h"
#include "base/logging.h"
#include "Common.h"
#include "MemoryUtil.h"
#include "StringUtils.h"

View File

@ -53,7 +53,11 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
va_start(args, format);
CharArrayFromFormatV(buffer, sizeof(buffer)-1, format, args);
va_end(args);
// Safe android logging
#ifdef PPSSPP_PLATFORM(ANDROID)
ELOG("%s: %s", caption, buffer);
#endif
// Normal logging
ERROR_LOG(SYSTEM, "%s: %s", caption, buffer);
// Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored

View File

@ -101,7 +101,7 @@ void ThunkManager::Init()
void ThunkManager::Reset()
{
thunks.clear();
ResetCodePtr();
ResetCodePtr(0);
}
void ThunkManager::Shutdown()

View File

@ -1980,9 +1980,9 @@ void XEmitter::FNSTSW_AX() { Write8(0xDF); Write8(0xE0); }
void XEmitter::RDTSC() { Write8(0x0F); Write8(0x31); }
void XCodeBlock::PoisonMemory() {
void XCodeBlock::PoisonMemory(int offset) {
// x86/64: 0xCC = breakpoint
memset(region, 0xCC, region_size);
memset(region + offset, 0xCC, region_size - offset);
}
}

View File

@ -1061,7 +1061,7 @@ public:
class XCodeBlock : public CodeBlock<XEmitter> {
public:
void PoisonMemory() override;
void PoisonMemory(int offset) override;
};
} // namespace

View File

@ -152,7 +152,7 @@ void ArmJit::FlushPrefixV()
void ArmJit::ClearCache()
{
blocks.Clear();
ClearCodeSpace();
ClearCodeSpace(0);
GenerateFixedCode();
}

View File

@ -318,10 +318,11 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
}
}
// Don't forget to zap the instruction cache! This must stay at the end of this function.
FlushIcache();
// Let's spare the pre-generated code from unprotect-reprotect.
AlignCodePage();
jitStartOffset = (int)(GetCodePtr() - start);
// Don't forget to zap the instruction cache! This must stay at the end of this function.
FlushIcache();
EndWrite();
}

View File

@ -142,8 +142,7 @@ void Arm64Jit::FlushPrefixV() {
void Arm64Jit::ClearCache() {
ILOG("ARM64Jit: Clearing the cache!");
blocks.Clear();
ClearCodeSpace();
GenerateFixedCode(jo);
ClearCodeSpace(jitStartOffset);
}
void Arm64Jit::InvalidateCacheAt(u32 em_address, int length) {

View File

@ -280,6 +280,8 @@ public:
const u8 *applyRoundingMode;
const u8 *updateRoundingMode;
int jitStartOffset;
// Indexed by FPCR FZ:RN bits for convenience. Uses SCRATCH2.
const u8 *convertS0ToSCRATCH1[8];
};

View File

@ -219,7 +219,7 @@ void Jit::UpdateRoundingMode() {
void Jit::ClearCache()
{
blocks.Clear();
ClearCodeSpace();
ClearCodeSpace(0);
GenerateFixedCode(jo);
}

View File

@ -448,7 +448,7 @@ void JitSafeMemFuncs::Init(ThunkManager *thunks) {
}
void JitSafeMemFuncs::Shutdown() {
ResetCodePtr();
ResetCodePtr(0);
FreeCodeSpace();
}

View File

@ -1281,5 +1281,5 @@ VertexDecoderJitCache::VertexDecoderJitCache()
}
void VertexDecoderJitCache::Clear() {
ClearCodeSpace();
ClearCodeSpace(0);
}

View File

@ -359,6 +359,9 @@ void SystemInfoScreen::CreateViews() {
deviceSpecs->Add(new ItemHeader("System Information"));
deviceSpecs->Add(new InfoItem("Name", System_GetProperty(SYSPROP_NAME)));
deviceSpecs->Add(new InfoItem("Lang/Region", System_GetProperty(SYSPROP_LANGREGION)));
std::string board = System_GetProperty(SYSPROP_BOARDNAME);
if (!board.empty())
deviceSpecs->Add(new InfoItem("Board", board));
deviceSpecs->Add(new InfoItem("ABI", GetCompilerABI()));
#ifdef _WIN32
if (IsDebuggerPresent()) {

View File

@ -330,6 +330,7 @@ static std::queue<FrameCommand> frameCommands;
std::string systemName;
std::string langRegion;
std::string mogaVersion;
std::string boardName;
static float left_joystick_x_async;
static float left_joystick_y_async;
@ -419,6 +420,8 @@ std::string System_GetProperty(SystemProperty prop) {
return langRegion;
case SYSPROP_MOGA_VERSION:
return mogaVersion;
case SYSPROP_BOARDNAME:
return boardName;
default:
return "";
}
@ -548,7 +551,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
std::string shortcut_param = GetJavaString(env, jshortcutParam);
std::string cacheDir = GetJavaString(env, jcacheDir);
std::string buildBoard = GetJavaString(env, jboard);
boardName = buildBoard;
ILOG("NativeApp.init(): External storage path: %s", externalDir.c_str());
ILOG("NativeApp.init(): Launch shortcut parameter: %s", shortcut_param.c_str());

View File

@ -155,6 +155,7 @@ enum SystemProperty {
SYSPROP_NAME,
SYSPROP_LANGREGION,
SYSPROP_CPUINFO,
SYSPROP_BOARDNAME,
SYSPROP_CLIPBOARD_TEXT,
SYSPROP_GPUDRIVER_VERSION,