ConstantPool: Externalize memory allocation
This commit is contained in:
parent
615fcc621d
commit
da434e1a1c
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue