CPU/Recompiler: Write exception exits to far code buffer

Keeps the hot path nice and clean.
This commit is contained in:
Connor McLaughlin
2019-11-22 17:57:02 +10:00
parent 7b0978119b
commit 11966e4caf
7 changed files with 345 additions and 286 deletions

View File

@ -7,10 +7,12 @@
#include <sys/mman.h>
#endif
JitCodeBuffer::JitCodeBuffer(size_t size)
JitCodeBuffer::JitCodeBuffer(size_t size /* = 64 * 1024 * 1024 */, size_t far_code_size /* = 0 */)
{
m_total_size = size + far_code_size;
#if defined(Y_PLATFORM_WINDOWS)
m_code_ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
m_code_ptr = VirtualAlloc(nullptr, m_total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_ANDROID)
m_code_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#else
@ -20,6 +22,10 @@ JitCodeBuffer::JitCodeBuffer(size_t size)
m_code_size = size;
m_code_used = 0;
m_far_code_ptr = static_cast<u8*>(m_code_ptr) + size;
m_far_code_size = far_code_size;
m_far_code_used = 0;
if (!m_code_ptr)
Panic("Failed to allocate code space.");
}
@ -27,34 +33,39 @@ JitCodeBuffer::JitCodeBuffer(size_t size)
JitCodeBuffer::~JitCodeBuffer()
{
#if defined(Y_PLATFORM_WINDOWS)
VirtualFree(m_code_ptr, m_code_size, MEM_RELEASE);
VirtualFree(m_code_ptr, m_total_size, MEM_RELEASE);
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_ANDROID)
munmap(m_code_ptr, m_code_size);
munmap(m_code_ptr, m_total_size);
#endif
}
void JitCodeBuffer::CommitCode(size_t length)
{
// // Function alignment?
// size_t extra_bytes = ((length % 16) != 0) ? (16 - (length % 16)) : 0;
// for (size_t i = 0; i < extra_bytes; i++)
// reinterpret_cast<char*>(m_free_code_ptr)[i] = 0xCC;
Assert(length <= (m_code_size - m_code_used));
m_free_code_ptr = reinterpret_cast<char*>(m_free_code_ptr) + length;
m_free_code_ptr = reinterpret_cast<u8*>(m_free_code_ptr) + length;
m_code_used += length;
}
void JitCodeBuffer::CommitFarCode(size_t length)
{
Assert(length <= (m_far_code_size - m_far_code_used));
m_free_far_code_ptr = reinterpret_cast<u8*>(m_free_far_code_ptr) + length;
m_far_code_used += length;
}
void JitCodeBuffer::Reset()
{
#if defined(Y_PLATFORM_WINDOWS)
FlushInstructionCache(GetCurrentProcess(), m_code_ptr, m_code_size);
FlushInstructionCache(GetCurrentProcess(), m_code_ptr, m_total_size);
#elif defined(Y_PLATFORM_LINUX) || defined(Y_PLATFORM_ANDROID)
// TODO
#endif
m_free_code_ptr = m_code_ptr;
m_code_used = 0;
m_free_far_code_ptr = m_far_code_ptr;
m_far_code_used = 0;
}
void JitCodeBuffer::Align(u32 alignment, u8 padding_value)