mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-26 15:49:50 -06:00
ConstantPool: Implement a constant pool
Constants are copied into this pool so that they live at a memory location that is close to the code that references it. The pool allocates memory from a provided X64CodeBlock to use. The purpose of the pool is to overcome the 32-bit offset limitation that RIP-relative addressing has.`
This commit is contained in:
@ -244,6 +244,7 @@ if(_M_X86)
|
|||||||
PowerPC/Jit64/JitRegCache.cpp
|
PowerPC/Jit64/JitRegCache.cpp
|
||||||
PowerPC/Jit64/Jit_SystemRegisters.cpp
|
PowerPC/Jit64/Jit_SystemRegisters.cpp
|
||||||
PowerPC/Jit64Common/BlockCache.cpp
|
PowerPC/Jit64Common/BlockCache.cpp
|
||||||
|
PowerPC/Jit64Common/ConstantPool.cpp
|
||||||
PowerPC/Jit64Common/EmuCodeBlock.cpp
|
PowerPC/Jit64Common/EmuCodeBlock.cpp
|
||||||
PowerPC/Jit64Common/FarCodeCache.cpp
|
PowerPC/Jit64Common/FarCodeCache.cpp
|
||||||
PowerPC/Jit64Common/Jit64AsmCommon.cpp
|
PowerPC/Jit64Common/Jit64AsmCommon.cpp
|
||||||
|
@ -243,6 +243,7 @@
|
|||||||
<ClCompile Include="PowerPC\Interpreter\Interpreter_Paired.cpp" />
|
<ClCompile Include="PowerPC\Interpreter\Interpreter_Paired.cpp" />
|
||||||
<ClCompile Include="PowerPC\Interpreter\Interpreter_SystemRegisters.cpp" />
|
<ClCompile Include="PowerPC\Interpreter\Interpreter_SystemRegisters.cpp" />
|
||||||
<ClCompile Include="PowerPC\Interpreter\Interpreter_Tables.cpp" />
|
<ClCompile Include="PowerPC\Interpreter\Interpreter_Tables.cpp" />
|
||||||
|
<ClCompile Include="PowerPC\Jit64Common\ConstantPool.cpp" />
|
||||||
<ClCompile Include="PowerPC\JitILCommon\IR.cpp" />
|
<ClCompile Include="PowerPC\JitILCommon\IR.cpp" />
|
||||||
<ClCompile Include="PowerPC\JitILCommon\JitILBase_Branch.cpp" />
|
<ClCompile Include="PowerPC\JitILCommon\JitILBase_Branch.cpp" />
|
||||||
<ClCompile Include="PowerPC\JitILCommon\JitILBase_FloatingPoint.cpp" />
|
<ClCompile Include="PowerPC\JitILCommon\JitILBase_FloatingPoint.cpp" />
|
||||||
@ -484,6 +485,7 @@
|
|||||||
<ClInclude Include="PowerPC\CachedInterpreter\InterpreterBlockCache.h" />
|
<ClInclude Include="PowerPC\CachedInterpreter\InterpreterBlockCache.h" />
|
||||||
<ClInclude Include="PowerPC\Interpreter\Interpreter.h" />
|
<ClInclude Include="PowerPC\Interpreter\Interpreter.h" />
|
||||||
<ClInclude Include="PowerPC\Interpreter\Interpreter_FPUtils.h" />
|
<ClInclude Include="PowerPC\Interpreter\Interpreter_FPUtils.h" />
|
||||||
|
<ClInclude Include="PowerPC\Jit64Common\ConstantPool.h" />
|
||||||
<ClInclude Include="PowerPC\Jit64IL\JitIL.h" />
|
<ClInclude Include="PowerPC\Jit64IL\JitIL.h" />
|
||||||
<ClInclude Include="PowerPC\Jit64\FPURegCache.h" />
|
<ClInclude Include="PowerPC\Jit64\FPURegCache.h" />
|
||||||
<ClInclude Include="PowerPC\Jit64\GPRRegCache.h" />
|
<ClInclude Include="PowerPC\Jit64\GPRRegCache.h" />
|
||||||
|
@ -867,6 +867,9 @@
|
|||||||
<ClCompile Include="IOS\USB\Bluetooth\WiimoteHIDAttr.cpp">
|
<ClCompile Include="IOS\USB\Bluetooth\WiimoteHIDAttr.cpp">
|
||||||
<Filter>IOS\USB\Bluetooth</Filter>
|
<Filter>IOS\USB\Bluetooth</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PowerPC\Jit64Common\ConstantPool.cpp">
|
||||||
|
<Filter>PowerPC\Jit64Common</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="BootManager.h" />
|
<ClInclude Include="BootManager.h" />
|
||||||
@ -1487,6 +1490,9 @@
|
|||||||
<ClInclude Include="IOS\MIOS.h">
|
<ClInclude Include="IOS\MIOS.h">
|
||||||
<Filter>IOS</Filter>
|
<Filter>IOS</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PowerPC\Jit64Common\ConstantPool.h">
|
||||||
|
<Filter>PowerPC\Jit64Common</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="CMakeLists.txt" />
|
<Text Include="CMakeLists.txt" />
|
||||||
|
67
Source/Core/Core/PowerPC/Jit64Common/ConstantPool.cpp
Normal file
67
Source/Core/Core/PowerPC/Jit64Common/ConstantPool.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2017 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Common/Assert.h"
|
||||||
|
#include "Common/x64Emitter.h"
|
||||||
|
#include "Core/PowerPC/Jit64Common/ConstantPool.h"
|
||||||
|
|
||||||
|
ConstantPool::ConstantPool(Gen::X64CodeBlock* parent) : m_parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantPool::~ConstantPool() = default;
|
||||||
|
|
||||||
|
void ConstantPool::AllocCodeSpace()
|
||||||
|
{
|
||||||
|
_assert_(!m_current_ptr);
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConstantPool::ClearCodeSpace()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
Gen::OpArg ConstantPool::GetConstantOpArg(const void* value, size_t element_size,
|
||||||
|
size_t num_elements, size_t index)
|
||||||
|
{
|
||||||
|
const size_t value_size = element_size * num_elements;
|
||||||
|
auto iter = m_const_info.find(value);
|
||||||
|
|
||||||
|
if (iter == m_const_info.end())
|
||||||
|
{
|
||||||
|
void* ptr = std::align(ALIGNMENT, value_size, m_current_ptr, m_remaining_size);
|
||||||
|
_assert_msg_(DYNA_REC, ptr, "Constant pool has run out of space.");
|
||||||
|
|
||||||
|
m_current_ptr = static_cast<u8*>(m_current_ptr) + value_size;
|
||||||
|
m_remaining_size -= value_size;
|
||||||
|
|
||||||
|
std::memcpy(ptr, value, value_size);
|
||||||
|
iter = m_const_info.emplace(std::make_pair(value, ConstantInfo{ptr, value_size})).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConstantInfo& info = iter->second;
|
||||||
|
_assert_msg_(DYNA_REC, info.m_size == value_size,
|
||||||
|
"Constant has incorrect size in constant pool.");
|
||||||
|
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();
|
||||||
|
}
|
52
Source/Core/Core/PowerPC/Jit64Common/ConstantPool.h
Normal file
52
Source/Core/Core/PowerPC/Jit64Common/ConstantPool.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2017 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace Gen
|
||||||
|
{
|
||||||
|
struct OpArg;
|
||||||
|
class X64CodeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constants are copied into this pool so that they live at a memory location
|
||||||
|
// that is close to the code that references it. This ensures that the 32-bit
|
||||||
|
// limitation on RIP addressing is not an issue.
|
||||||
|
class ConstantPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr size_t CONST_POOL_SIZE = 1024 * 32;
|
||||||
|
static constexpr size_t ALIGNMENT = 16;
|
||||||
|
|
||||||
|
explicit ConstantPool(Gen::X64CodeBlock* parent);
|
||||||
|
~ConstantPool();
|
||||||
|
|
||||||
|
// ConstantPool reserves CONST_POOL_SIZE bytes from parent, and uses
|
||||||
|
// that space to store its constants.
|
||||||
|
void AllocCodeSpace();
|
||||||
|
void ClearCodeSpace();
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// used to determine if two constants are the same.
|
||||||
|
Gen::OpArg GetConstantOpArg(const void* value, size_t element_size, size_t num_elements,
|
||||||
|
size_t index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
struct ConstantInfo
|
||||||
|
{
|
||||||
|
void* m_location;
|
||||||
|
size_t m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gen::X64CodeBlock* m_parent;
|
||||||
|
void* m_current_ptr = nullptr;
|
||||||
|
size_t m_remaining_size = CONST_POOL_SIZE;
|
||||||
|
std::map<const void*, ConstantInfo> m_const_info;
|
||||||
|
};
|
Reference in New Issue
Block a user