Skip to main content

Module tlb

Module tlb 

Source
Expand description

A software TLB: the shape compiled code needs to reach guest memory without calling back into Rust.

The Mmu answers an access with a hash lookup, a per-page bounds walk and a per-byte permission scan. That is the right shape for an interpreter, which pays a dispatch per operation anyway, and the wrong one for compiled code, where it is the only thing standing between a guest load and a machine load. This cache is the part a compiled block can inline: an index, a tag compare, and an add.

§What an entry promises, and what it does not

An entry says only where the page lives: the host address of a resident PageData for one guest page. It says nothing about permissions. Compiled code checks those itself, per byte, out of the same allocation — which is why PageData keeps the permission bytes next to the data bytes at a fixed offset rather than in a second allocation.

Splitting reads from writes would let the table itself carry the coarse permission, as icicle’s does. It would buy nothing here: this MMU’s permissions are per byte, so the byte scan happens either way, and one table means one entry to fill and invalidate.

§Invalidation

An entry holds a raw pointer into a page allocation, so it outlives its page only if nobody drops one. Every operation that can add, drop or replace a page flushes the whole table; permission edits do not, because permissions are read live from the page rather than cached here.

Structs§

TlbEntry
One cached translation.
TranslationCache
The table compiled code indexes.

Constants§

TLB_ENTRIES
Number of entries in the table. A power of two, so indexing is a mask.
TLB_INDEX_BITS
log2 of the number of entries. 64 entries covers the working set of the code this runs — a stack page, a couple of data pages, the code page — with room for a few more before it thrashes, and the whole table stays inside a few cache lines.