Skip to main content

Module mat

Module mat 

Source
Expand description

Shared per-page memory-materialization (#3) state machine.

Both engines drive this same state machine so they charge bit-identical category-#3 gas (consensus determinism): the interpreter does software first-touch accounting (no real unmap), the x86 recompiler does the same accounting off hardware page-table faults. See ~/docs/spec-staging/gas-cost.md §3.

The charge rules key strictly on the per-page PageState and the static PageKind — never on the instruction — so a load-then-store to one page charges identically regardless of engine. The sole fault-driven #3 charge is copy-on-write (the first write to a writable page), charged at most once per page (per frame). Read-only page-in is not charged at the fault: bringing a read-only region into the working set is accounted eagerly at the CALL that maps it (crate::gas_const::call_frame_cost, computed statically from the callee Image), so a read — first or not — debits nothing here. A read only records the residency PageState transition. The one re-touch event is a MGMT_MOVE/MGMT_DROP slot eviction, a block terminator.

§Read-only materialization is a mapping event, not a charge

Read-only (PageKind::PinnedCapRo) regions — the program’s code and pinned data caps — are still materialized in units, where a unit is the intersection of one DataCap with one 2 MiB cluster (CLUSTER_SHIFT, unit_base): the recompiler fault-arounds a whole unit’s RO pages on first touch so later reads in the unit hit no further faults, and both engines record the same unit set. That clustering is now purely a mapping / fault-reduction optimization with zero gas — the read-only page-in cost is charged once, eagerly, at the CALL (one crate::gas_const::PAGE_IN_COST per declared 2 MiB unit), not lazily per touched unit at the fault. Copy-on-write (RW) regions stay 4 KiB-granular: a write copies one page and charges COW_COST. Both engines key on the same unit_base, so the (gas-free) unit set and the per-page CoW charge match bit-for-bit.

Structs§

HardFault
A write to a read-only (pinned) page — a permanent PVM2-level fault. (Accesses outside any declared mapping are rejected by the caller before reaching charge_for.) Charge nothing.
PageSet
The set of consensus 4 KiB pages a single width-byte access at addr touches: the base page, plus the next page iff the access straddles a page boundary. At most crate::gas_const::MAX_PAGES_PER_ACCESS (= 2) pages. Pages are ordered low → high — the fixed order both engines iterate, so the charged page set and total match exactly.

Enums§

PageKind
Static per-page source kind, derived once from the Image’s declared memory mappings (pinned slot vs initial slot vs ephemeral / zero tail).
PageState
Dynamic per-page first-touch state.

Constants§

CLUSTER_SHIFT
log2 of the read-only materialization cluster size. 21 → 2 MiB, the common large-page size on x86 (PDE), AArch64 (L2 block), and RISC-V (megapage), so the clustered charge model is arch-portable. TODO(gas-calibration): cluster size is subject to change.

Functions§

access_pages
Compute the page set for a width-byte access at addr. Keyed only on addr and width so the recompiler (which learns width from a compile-time side table) and the interpreter (which knows it from the opcode) agree byte-for-byte. width must be in 1..=8.
charge_for
The category-#3 charge and resulting state for one page touch.
cluster_of
Absolute 2 MiB cluster index of addr (addr >> CLUSTER_SHIFT).
unit_base
Identity of the read-only materialization unit containing addr: the cap ∩ cluster region, named by its base address max(cluster_lo, cap_start). The recompiler fault-arounds exactly the unit’s pages on its first touch (mapping them all read-only in one go), so a unit is mapped at most once — a pure fault-reduction key. It carries no gas: read-only page-in is charged eagerly at the CALL (crate::gas_const::call_frame_cost), not per touched unit.