constant_pool: Use std::span to manage pool

Simplifies some raw pointer arithmetic and type-usage into the new
`ConstantT` type.
This commit is contained in:
Wunkolo 2022-06-28 11:58:17 -07:00 committed by merry
parent 5d9b720189
commit a5318c775c
2 changed files with 18 additions and 14 deletions

View file

@ -14,22 +14,22 @@
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {
ConstantPool::ConstantPool(BlockOfCode& code, size_t size) ConstantPool::ConstantPool(BlockOfCode& code, size_t size)
: code(code), pool_size(size) { : code(code), insertion_point(0) {
code.int3(); code.int3();
code.align(align_size); code.align(align_size);
pool_begin = reinterpret_cast<u8*>(code.AllocateFromCodeSpace(size)); pool = std::span<ConstantT>(
current_pool_ptr = pool_begin; reinterpret_cast<ConstantT*>(code.AllocateFromCodeSpace(size)), size / align_size);
} }
Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) { Xbyak::Address ConstantPool::GetConstant(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) {
const auto constant = std::make_pair(lower, upper); const auto constant = ConstantT(lower, upper);
auto iter = constant_info.find(constant); auto iter = constant_info.find(constant);
if (iter == constant_info.end()) { if (iter == constant_info.end()) {
ASSERT(static_cast<size_t>(current_pool_ptr - pool_begin) < pool_size); ASSERT(insertion_point < pool.size());
std::memcpy(current_pool_ptr, &lower, sizeof(u64)); ConstantT& target_constant = pool[insertion_point];
std::memcpy(current_pool_ptr + sizeof(u64), &upper, sizeof(u64)); target_constant = constant;
iter = constant_info.emplace(constant, current_pool_ptr).first; iter = constant_info.emplace(constant, &target_constant).first;
current_pool_ptr += align_size; ++insertion_point;
} }
return frame[code.rip + iter->second]; return frame[code.rip + iter->second];
} }

View file

@ -6,6 +6,8 @@
#pragma once #pragma once
#include <bit> #include <bit>
#include <cstddef>
#include <span>
#include <utility> #include <utility>
#include <mcl/stdint.hpp> #include <mcl/stdint.hpp>
@ -29,18 +31,20 @@ public:
private: private:
static constexpr size_t align_size = 16; // bytes static constexpr size_t align_size = 16; // bytes
using ConstantT = std::pair<u64, u64>;
static_assert(sizeof(ConstantT) == align_size);
struct ConstantHash { struct ConstantHash {
std::size_t operator()(const std::pair<u64, u64>& constant) const noexcept { std::size_t operator()(const ConstantT& constant) const noexcept {
return constant.first ^ std::rotl<u64>(constant.second, 1); return constant.first ^ std::rotl<u64>(constant.second, 1);
} }
}; };
tsl::robin_map<std::pair<u64, u64>, void*, ConstantHash> constant_info; tsl::robin_map<ConstantT, void*, ConstantHash> constant_info;
BlockOfCode& code; BlockOfCode& code;
size_t pool_size; std::span<ConstantT> pool;
u8* pool_begin; std::size_t insertion_point;
u8* current_pool_ptr;
}; };
} // namespace Dynarmic::Backend::X64 } // namespace Dynarmic::Backend::X64