Skip to main content

InstructionFetcher

Trait InstructionFetcher 

Source
pub trait InstructionFetcher<I, Memory>
where Self: ProgramCounter<<<I as Instruction>::Reg as Register>::Type, Memory>, I: Instruction,
{ // 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§

Source

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.

Source

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.

Source

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".

Implementors§

Source§

impl<I, Memory> InstructionFetcher<I, Memory> for BasicInstructionFetcher<I>
where I: Instruction, Memory: VirtualMemory,