pub trait InstructionFetcher<I, Memory>{
// Required methods
fn peek_instruction(&mut self, memory: &Memory) -> FetchInstructionResult<I>;
unsafe fn advance(&mut self, instruction_size: u8);
fn fetch_instruction(
&mut self,
memory: &Memory,
) -> FetchInstructionResult<I>;
}Expand description
Generic instruction fetcher.
§Performance considerations
In threaded dispatch, the instruction fetcher is moved through the handler chain by value, so it
should have 16 bytes size (next instruction pointer + pointer to extra state) and no drop glue.
A fetcher that owns something is dropped by whichever handler ends execution. Every handler that
can fail is a candidate for that, which forces a stack frame, callee-saved register spills, and
a reload into the hot path of every load, store, branch and jump. A fetcher that only borrows
what it walks (Copy, or at least !needs_drop) keeps them all frameless and fast.
Required Methods§
Sourcefn peek_instruction(&mut self, memory: &Memory) -> FetchInstructionResult<I>
fn peek_instruction(&mut self, memory: &Memory) -> FetchInstructionResult<I>
Read the instruction at the current position, leaving the program counter on it.
Self::advance() is what moves past it, and the two are separate because of what deriving
the size from the instruction is costly for threaded dispatch: it makes the address of the
next instruction depend on decoding the current one. In threaded dispatch caller already
knows which variant it is holding and advances by a constant instead, allowing the next load
to be issued immediately.
Sourceunsafe fn advance(&mut self, instruction_size: u8)
unsafe fn advance(&mut self, instruction_size: u8)
Move the program counter past an instruction of instruction_size bytes that
Self::peek_instruction() has just returned.
§Safety
Must be called exactly once after a successful Self::peek_instruction(), with the size
of the instruction that call returned. Implementations are free to rely on that and skip
checks accordingly: one over a pre-decoded stream that is known to end with a jump, for
instance, treats the resulting position as valid without bounds-checking it.
Sourcefn fetch_instruction(&mut self, memory: &Memory) -> FetchInstructionResult<I>
fn fetch_instruction(&mut self, memory: &Memory) -> FetchInstructionResult<I>
Fetch a single instruction at a specified address and advance the program counter on successful fetch.
This is Self::peek_instruction() followed by Self::advance() and exists for callers
that do not know what they are about to fetch, which is every caller that dispatches
through a match rather than through per-variant handlers.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".