block_of_code: Enable configuration of code cache sizes
This commit is contained in:
parent
d0372aebaf
commit
c788bcdf17
6 changed files with 29 additions and 24 deletions
|
@ -197,6 +197,13 @@ struct UserConfig {
|
||||||
/// NOTE: Calling Jit::SetCpsr with CPSR.E=1 while this option is enabled may result
|
/// NOTE: Calling Jit::SetCpsr with CPSR.E=1 while this option is enabled may result
|
||||||
/// in unusual behavior.
|
/// in unusual behavior.
|
||||||
bool always_little_endian = false;
|
bool always_little_endian = false;
|
||||||
|
|
||||||
|
// Minimum size is about 8MiB. Maximum size is about 2GiB. Maximum size is limited by
|
||||||
|
// the maximum length of a x64 jump.
|
||||||
|
size_t code_cache_size = 256 * 1024 * 1024; // bytes
|
||||||
|
// Determines the relative size of the near and far code caches. Must be smaller than
|
||||||
|
// code_cache_size.
|
||||||
|
size_t far_code_offset = 200 * 1024 * 1024; // bytes
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace A32
|
} // namespace A32
|
||||||
|
|
|
@ -245,6 +245,13 @@ struct UserConfig {
|
||||||
// Determines whether AddTicks and GetTicksRemaining are called.
|
// Determines whether AddTicks and GetTicksRemaining are called.
|
||||||
// If false, execution will continue until soon after Jit::HaltExecution is called.
|
// If false, execution will continue until soon after Jit::HaltExecution is called.
|
||||||
// bool enable_ticks = true; // TODO
|
// bool enable_ticks = true; // TODO
|
||||||
|
|
||||||
|
// Minimum size is about 8MiB. Maximum size is about 2GiB. Maximum size is limited by
|
||||||
|
// the maximum length of a x64 jump.
|
||||||
|
size_t code_cache_size = 256 * 1024 * 1024; // bytes
|
||||||
|
// Determines the relative size of the near and far code caches. Must be smaller than
|
||||||
|
// code_cache_size.
|
||||||
|
size_t far_code_offset = 200 * 1024 * 1024; // bytes
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace A64
|
} // namespace A64
|
||||||
|
|
|
@ -53,7 +53,7 @@ static std::function<void(BlockOfCode&)> GenRCP(const A32::UserConfig& conf) {
|
||||||
|
|
||||||
struct Jit::Impl {
|
struct Jit::Impl {
|
||||||
Impl(Jit* jit, A32::UserConfig conf)
|
Impl(Jit* jit, A32::UserConfig conf)
|
||||||
: block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this), JitStateInfo{jit_state}, GenRCP(conf))
|
: block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this), JitStateInfo{jit_state}, conf.code_cache_size, conf.far_code_offset, GenRCP(conf))
|
||||||
, emitter(block_of_code, conf, jit)
|
, emitter(block_of_code, conf, jit)
|
||||||
, conf(std::move(conf))
|
, conf(std::move(conf))
|
||||||
, jit_interface(jit)
|
, jit_interface(jit)
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct Jit::Impl final {
|
||||||
public:
|
public:
|
||||||
Impl(Jit* jit, UserConfig conf)
|
Impl(Jit* jit, UserConfig conf)
|
||||||
: conf(conf)
|
: conf(conf)
|
||||||
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this), JitStateInfo{jit_state}, GenRCP(conf))
|
, block_of_code(GenRunCodeCallbacks(conf.callbacks, &GetCurrentBlockThunk, this), JitStateInfo{jit_state}, conf.code_cache_size, conf.far_code_offset, GenRCP(conf))
|
||||||
, emitter(block_of_code, conf, jit)
|
, emitter(block_of_code, conf, jit)
|
||||||
{
|
{
|
||||||
ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
|
ASSERT(conf.page_table_address_space_bits >= 12 && conf.page_table_address_space_bits <= 64);
|
||||||
|
|
|
@ -44,8 +44,6 @@ const std::array<Xbyak::Reg64, 6> BlockOfCode::ABI_PARAMS = {BlockOfCode::ABI_PA
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr size_t TOTAL_CODE_SIZE = 256 * 1024 * 1024;
|
|
||||||
constexpr size_t FAR_CODE_OFFSET = 200 * 1024 * 1024;
|
|
||||||
constexpr size_t CONSTANT_POOL_SIZE = 2 * 1024 * 1024;
|
constexpr size_t CONSTANT_POOL_SIZE = 2 * 1024 * 1024;
|
||||||
|
|
||||||
class CustomXbyakAllocator : public Xbyak::Allocator {
|
class CustomXbyakAllocator : public Xbyak::Allocator {
|
||||||
|
@ -75,10 +73,11 @@ void ProtectMemory(const void* base, size_t size, bool is_executable) {
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, std::function<void(BlockOfCode&)> rcp)
|
BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, size_t far_code_offset, std::function<void(BlockOfCode&)> rcp)
|
||||||
: Xbyak::CodeGenerator(TOTAL_CODE_SIZE, nullptr, &s_allocator)
|
: Xbyak::CodeGenerator(total_code_size, nullptr, &s_allocator)
|
||||||
, cb(std::move(cb))
|
, cb(std::move(cb))
|
||||||
, jsi(jsi)
|
, jsi(jsi)
|
||||||
|
, far_code_offset(far_code_offset)
|
||||||
, constant_pool(*this, CONSTANT_POOL_SIZE)
|
, constant_pool(*this, CONSTANT_POOL_SIZE)
|
||||||
{
|
{
|
||||||
EnableWriting();
|
EnableWriting();
|
||||||
|
@ -88,7 +87,7 @@ BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, std::function<vo
|
||||||
void BlockOfCode::PreludeComplete() {
|
void BlockOfCode::PreludeComplete() {
|
||||||
prelude_complete = true;
|
prelude_complete = true;
|
||||||
near_code_begin = getCurr();
|
near_code_begin = getCurr();
|
||||||
far_code_begin = getCurr() + FAR_CODE_OFFSET;
|
far_code_begin = getCurr() + far_code_offset;
|
||||||
ClearCache();
|
ClearCache();
|
||||||
DisableWriting();
|
DisableWriting();
|
||||||
}
|
}
|
||||||
|
@ -115,22 +114,13 @@ void BlockOfCode::ClearCache() {
|
||||||
|
|
||||||
size_t BlockOfCode::SpaceRemaining() const {
|
size_t BlockOfCode::SpaceRemaining() const {
|
||||||
ASSERT(prelude_complete);
|
ASSERT(prelude_complete);
|
||||||
// This function provides an underestimate of near-code-size but that's okay.
|
const u8* current_near_ptr = in_far_code ? reinterpret_cast<const u8*>(near_code_ptr) : getCode<const u8*>();
|
||||||
// (Why? The maximum size of near code should be measured from near_code_begin, not top_.)
|
const u8* current_far_ptr = in_far_code ? getCode<const u8*>() : reinterpret_cast<const u8*>(far_code_ptr);
|
||||||
// These are offsets from Xbyak::CodeArray::top_.
|
if (current_near_ptr >= far_code_begin)
|
||||||
std::size_t far_code_offset, near_code_offset;
|
|
||||||
if (in_far_code) {
|
|
||||||
near_code_offset = static_cast<const u8*>(near_code_ptr) - getCode();
|
|
||||||
far_code_offset = getCurr() - getCode();
|
|
||||||
} else {
|
|
||||||
near_code_offset = getCurr() - getCode();
|
|
||||||
far_code_offset = static_cast<const u8*>(far_code_ptr) - getCode();
|
|
||||||
}
|
|
||||||
if (far_code_offset > TOTAL_CODE_SIZE)
|
|
||||||
return 0;
|
return 0;
|
||||||
if (near_code_offset > FAR_CODE_OFFSET)
|
if (current_far_ptr >= &top_[maxSize_])
|
||||||
return 0;
|
return 0;
|
||||||
return std::min(TOTAL_CODE_SIZE - far_code_offset, FAR_CODE_OFFSET - near_code_offset);
|
return std::min(current_near_ptr - reinterpret_cast<const u8*>(far_code_begin), current_far_ptr - &top_[maxSize_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockOfCode::RunCode(void* jit_state, CodePtr code_ptr) const {
|
void BlockOfCode::RunCode(void* jit_state, CodePtr code_ptr) const {
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct RunCodeCallbacks {
|
||||||
|
|
||||||
class BlockOfCode final : public Xbyak::CodeGenerator {
|
class BlockOfCode final : public Xbyak::CodeGenerator {
|
||||||
public:
|
public:
|
||||||
BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, std::function<void(BlockOfCode&)> rcp);
|
BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, size_t far_code_offset, std::function<void(BlockOfCode&)> rcp);
|
||||||
BlockOfCode(const BlockOfCode&) = delete;
|
BlockOfCode(const BlockOfCode&) = delete;
|
||||||
|
|
||||||
/// Call when external emitters have finished emitting their preludes.
|
/// Call when external emitters have finished emitting their preludes.
|
||||||
|
@ -164,10 +164,11 @@ public:
|
||||||
private:
|
private:
|
||||||
RunCodeCallbacks cb;
|
RunCodeCallbacks cb;
|
||||||
JitStateInfo jsi;
|
JitStateInfo jsi;
|
||||||
|
size_t far_code_offset;
|
||||||
|
|
||||||
bool prelude_complete = false;
|
bool prelude_complete = false;
|
||||||
CodePtr near_code_begin;
|
CodePtr near_code_begin = nullptr;
|
||||||
CodePtr far_code_begin;
|
CodePtr far_code_begin = nullptr;
|
||||||
|
|
||||||
ConstantPool constant_pool;
|
ConstantPool constant_pool;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue