BlockOfCode: Detect space remaining
We also clear the code cache when we run out of space. This closes #111.
This commit is contained in:
parent
80c56aa89d
commit
ea4c3292d5
3 changed files with 27 additions and 0 deletions
|
@ -57,6 +57,25 @@ void BlockOfCode::ClearCache() {
|
||||||
SetCodePtr(near_code_begin);
|
SetCodePtr(near_code_begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t BlockOfCode::SpaceRemaining() const {
|
||||||
|
// This function provides an underestimate of near-code-size but that's okay.
|
||||||
|
// (Why? The maximum size of near code should be measured from near_code_begin, not top_.)
|
||||||
|
// These are offsets from Xbyak::CodeArray::top_.
|
||||||
|
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;
|
||||||
|
if (near_code_offset > FAR_CODE_OFFSET)
|
||||||
|
return 0;
|
||||||
|
return std::min(TOTAL_CODE_SIZE - far_code_offset, FAR_CODE_OFFSET - near_code_offset);
|
||||||
|
}
|
||||||
|
|
||||||
size_t BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const {
|
size_t BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const {
|
||||||
constexpr size_t max_cycles_to_run = static_cast<size_t>(std::numeric_limits<decltype(jit_state->cycles_remaining)>::max());
|
constexpr size_t max_cycles_to_run = static_cast<size_t>(std::numeric_limits<decltype(jit_state->cycles_remaining)>::max());
|
||||||
ASSERT(cycles_to_run <= max_cycles_to_run);
|
ASSERT(cycles_to_run <= max_cycles_to_run);
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
|
|
||||||
/// Clears this block of code and resets code pointer to beginning.
|
/// Clears this block of code and resets code pointer to beginning.
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
/// Calculates how much space is remaining to use. This is the minimum of near code and far code.
|
||||||
|
size_t SpaceRemaining() const;
|
||||||
|
|
||||||
/// Runs emulated code for approximately `cycles_to_run` cycles.
|
/// Runs emulated code for approximately `cycles_to_run` cycles.
|
||||||
size_t RunCode(JitState* jit_state, size_t cycles_to_run) const;
|
size_t RunCode(JitState* jit_state, size_t cycles_to_run) const;
|
||||||
|
|
|
@ -141,6 +141,12 @@ private:
|
||||||
if (block)
|
if (block)
|
||||||
return *block;
|
return *block;
|
||||||
|
|
||||||
|
constexpr size_t MINIMUM_REMAINING_CODESIZE = 1 * 1024 * 1024;
|
||||||
|
if (block_of_code.SpaceRemaining() < MINIMUM_REMAINING_CODESIZE) {
|
||||||
|
invalidate_entire_cache = true;
|
||||||
|
PerformCacheInvalidation();
|
||||||
|
}
|
||||||
|
|
||||||
IR::Block ir_block = Arm::Translate(descriptor, callbacks.memory.ReadCode);
|
IR::Block ir_block = Arm::Translate(descriptor, callbacks.memory.ReadCode);
|
||||||
Optimization::GetSetElimination(ir_block);
|
Optimization::GetSetElimination(ir_block);
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
|
Loading…
Reference in a new issue