ConstantPool: Externalize memory allocation

This commit is contained in:
MerryMage
2017-03-21 18:37:48 +00:00
parent 615fcc621d
commit da434e1a1c
6 changed files with 33 additions and 50 deletions

View File

@ -44,7 +44,7 @@ public:
} }
// Call this before you generate any code. // Call this before you generate any code.
virtual void AllocCodeSpace(size_t size, bool need_low = true) void AllocCodeSpace(size_t size, bool need_low = true)
{ {
region_size = size; region_size = size;
total_region_size = size; total_region_size = size;
@ -54,7 +54,7 @@ public:
// Always clear code space with breakpoints, so that if someone accidentally executes // Always clear code space with breakpoints, so that if someone accidentally executes
// uninitialized, it just breaks into the debugger. // uninitialized, it just breaks into the debugger.
virtual void ClearCodeSpace() void ClearCodeSpace()
{ {
PoisonMemory(); PoisonMemory();
ResetCodePtr(); ResetCodePtr();

View File

@ -230,7 +230,9 @@ void Jit64::Init()
fpr.SetEmitter(this); fpr.SetEmitter(this);
trampolines.Init(jo.memcheck ? TRAMPOLINE_CODE_SIZE_MMU : TRAMPOLINE_CODE_SIZE); trampolines.Init(jo.memcheck ? TRAMPOLINE_CODE_SIZE_MMU : TRAMPOLINE_CODE_SIZE);
AllocCodeSpace(CODE_SIZE); const size_t constpool_size = m_const_pool.CONST_POOL_SIZE;
AllocCodeSpace(CODE_SIZE + constpool_size);
m_const_pool.Init(AllocChildCodeSpace(constpool_size), constpool_size);
// BLR optimization has the same consequences as block linking, as well as // BLR optimization has the same consequences as block linking, as well as
// depending on the fault handler to be safe in the event of excessive BL. // depending on the fault handler to be safe in the event of excessive BL.
@ -262,6 +264,7 @@ void Jit64::ClearCache()
blocks.Clear(); blocks.Clear();
trampolines.ClearCodeSpace(); trampolines.ClearCodeSpace();
m_far_code.ClearCodeSpace(); m_far_code.ClearCodeSpace();
m_const_pool.Clear();
ClearCodeSpace(); ClearCodeSpace();
Clear(); Clear();
UpdateMemoryOptions(); UpdateMemoryOptions();
@ -276,6 +279,7 @@ void Jit64::Shutdown()
trampolines.Shutdown(); trampolines.Shutdown();
asm_routines.Shutdown(); asm_routines.Shutdown();
m_far_code.Shutdown(); m_far_code.Shutdown();
m_const_pool.Shutdown();
} }
void Jit64::FallBackToInterpreter(UGeckoInstruction inst) void Jit64::FallBackToInterpreter(UGeckoInstruction inst)

View File

@ -10,21 +10,31 @@
#include "Common/x64Emitter.h" #include "Common/x64Emitter.h"
#include "Core/PowerPC/Jit64Common/ConstantPool.h" #include "Core/PowerPC/Jit64Common/ConstantPool.h"
ConstantPool::ConstantPool(Gen::X64CodeBlock* parent) : m_parent(parent) ConstantPool::ConstantPool() = default;
{
}
ConstantPool::~ConstantPool() = default; ConstantPool::~ConstantPool() = default;
void ConstantPool::AllocCodeSpace() void ConstantPool::Init(void* memory, size_t size)
{ {
_assert_(!m_current_ptr); m_region = memory;
Init(); m_region_size = size;
Clear();
} }
void ConstantPool::ClearCodeSpace() void ConstantPool::Clear()
{ {
Init(); m_current_ptr = m_region;
m_remaining_size = m_region_size;
m_const_info.clear();
}
void ConstantPool::Shutdown()
{
m_region = nullptr;
m_region_size = 0;
m_current_ptr = nullptr;
m_remaining_size = 0;
m_const_info.clear();
} }
Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size, Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size,
@ -51,17 +61,3 @@ Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size
u8* location = static_cast<u8*>(info.m_location); u8* location = static_cast<u8*>(info.m_location);
return Gen::M(location + element_size * index); return Gen::M(location + element_size * index);
} }
void ConstantPool::Init()
{
// If execution happens to run to the start of the constant pool, halt.
m_parent->INT3();
m_parent->AlignCode16();
// Reserve a block of memory CONST_POOL_SIZE in size.
m_current_ptr = m_parent->GetWritableCodePtr();
m_parent->ReserveCodeSpace(CONST_POOL_SIZE);
m_remaining_size = CONST_POOL_SIZE;
m_const_info.clear();
}

View File

@ -22,13 +22,12 @@ public:
static constexpr size_t CONST_POOL_SIZE = 1024 * 32; static constexpr size_t CONST_POOL_SIZE = 1024 * 32;
static constexpr size_t ALIGNMENT = 16; static constexpr size_t ALIGNMENT = 16;
explicit ConstantPool(Gen::X64CodeBlock* parent); ConstantPool();
~ConstantPool(); ~ConstantPool();
// ConstantPool reserves CONST_POOL_SIZE bytes from parent, and uses void Init(void* memory, size_t size);
// that space to store its constants. void Clear();
void AllocCodeSpace(); void Shutdown();
void ClearCodeSpace();
// Copies the value into the pool if it doesn't exist. Returns a pointer // Copies the value into the pool if it doesn't exist. Returns a pointer
// to existing values if they were already copied. Pointer equality is // to existing values if they were already copied. Pointer equality is
@ -37,16 +36,15 @@ public:
size_t index); size_t index);
private: private:
void Init();
struct ConstantInfo struct ConstantInfo
{ {
void* m_location; void* m_location;
size_t m_size; size_t m_size;
}; };
Gen::X64CodeBlock* m_parent; void* m_region = nullptr;
size_t m_region_size = 0;
void* m_current_ptr = nullptr; void* m_current_ptr = nullptr;
size_t m_remaining_size = CONST_POOL_SIZE; size_t m_remaining_size = 0;
std::map<const void*, ConstantInfo> m_const_info; std::map<const void*, ConstantInfo> m_const_info;
}; };

View File

@ -40,18 +40,6 @@ OpArg FixImmediate(int access_size, OpArg arg)
} }
} // Anonymous namespace } // Anonymous namespace
void EmuCodeBlock::ClearCodeSpace()
{
X64CodeBlock::ClearCodeSpace();
m_const_pool.ClearCodeSpace();
}
void EmuCodeBlock::AllocCodeSpace(size_t size, bool need_low)
{
X64CodeBlock::AllocCodeSpace(size + ConstantPool::CONST_POOL_SIZE, need_low);
m_const_pool.AllocCodeSpace();
}
void EmuCodeBlock::MemoryExceptionCheck() void EmuCodeBlock::MemoryExceptionCheck()
{ {
// TODO: We really should untangle the trampolines, exception handlers and // TODO: We really should untangle the trampolines, exception handlers and

View File

@ -23,9 +23,6 @@ class Mapping;
class EmuCodeBlock : public Gen::X64CodeBlock class EmuCodeBlock : public Gen::X64CodeBlock
{ {
public: public:
void ClearCodeSpace() override;
void AllocCodeSpace(size_t size, bool need_low = true) override;
void MemoryExceptionCheck(); void MemoryExceptionCheck();
// Simple functions to switch between near and far code emitting // Simple functions to switch between near and far code emitting
@ -121,7 +118,7 @@ public:
void Clear(); void Clear();
protected: protected:
ConstantPool m_const_pool{this}; ConstantPool m_const_pool;
FarCodeCache m_far_code; FarCodeCache m_far_code;
u8* m_near_code; // Backed up when we switch to far code. u8* m_near_code; // Backed up when we switch to far code.