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);
|
||||
}
|
||||
|
||||
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 {
|
||||
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);
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
|
||||
/// Clears this block of code and resets code pointer to beginning.
|
||||
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.
|
||||
size_t RunCode(JitState* jit_state, size_t cycles_to_run) const;
|
||||
|
|
|
@ -141,6 +141,12 @@ private:
|
|||
if (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);
|
||||
Optimization::GetSetElimination(ir_block);
|
||||
Optimization::DeadCodeElimination(ir_block);
|
||||
|
|
Loading…
Reference in a new issue