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.
virtual void AllocCodeSpace(size_t size, bool need_low = true)
void AllocCodeSpace(size_t size, bool need_low = true)
{
region_size = size;
total_region_size = size;
@ -54,7 +54,7 @@ public:
// Always clear code space with breakpoints, so that if someone accidentally executes
// uninitialized, it just breaks into the debugger.
virtual void ClearCodeSpace()
void ClearCodeSpace()
{
PoisonMemory();
ResetCodePtr();

View File

@ -230,7 +230,9 @@ void Jit64::Init()
fpr.SetEmitter(this);
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
// depending on the fault handler to be safe in the event of excessive BL.
@ -262,6 +264,7 @@ void Jit64::ClearCache()
blocks.Clear();
trampolines.ClearCodeSpace();
m_far_code.ClearCodeSpace();
m_const_pool.Clear();
ClearCodeSpace();
Clear();
UpdateMemoryOptions();
@ -276,6 +279,7 @@ void Jit64::Shutdown()
trampolines.Shutdown();
asm_routines.Shutdown();
m_far_code.Shutdown();
m_const_pool.Shutdown();
}
void Jit64::FallBackToInterpreter(UGeckoInstruction inst)

View File

@ -10,21 +10,31 @@
#include "Common/x64Emitter.h"
#include "Core/PowerPC/Jit64Common/ConstantPool.h"
ConstantPool::ConstantPool(Gen::X64CodeBlock* parent) : m_parent(parent)
{
}
ConstantPool::ConstantPool() = default;
ConstantPool::~ConstantPool() = default;
void ConstantPool::AllocCodeSpace()
void ConstantPool::Init(void* memory, size_t size)
{
_assert_(!m_current_ptr);
Init();
m_region = memory;
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,
@ -51,17 +61,3 @@ Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size
u8* location = static_cast<u8*>(info.m_location);
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 ALIGNMENT = 16;
explicit ConstantPool(Gen::X64CodeBlock* parent);
ConstantPool();
~ConstantPool();
// ConstantPool reserves CONST_POOL_SIZE bytes from parent, and uses
// that space to store its constants.
void AllocCodeSpace();
void ClearCodeSpace();
void Init(void* memory, size_t size);
void Clear();
void Shutdown();
// 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
@ -37,16 +36,15 @@ public:
size_t index);
private:
void Init();
struct ConstantInfo
{
void* m_location;
size_t m_size;
};
Gen::X64CodeBlock* m_parent;
void* m_region = nullptr;
size_t m_region_size = 0;
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;
};

View File

@ -40,18 +40,6 @@ OpArg FixImmediate(int access_size, OpArg arg)
}
} // 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()
{
// TODO: We really should untangle the trampolines, exception handlers and

View File

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