Expand description
Per-basic-block gas cost model for PVM2 (JAR v0.8.0).
Simulates a single-pass CPU pipeline to compute gas cost for a
basic block. Cost = max(simulation_cycles - 3, 1).
Pipeline model:
- Reorder buffer: max 32 entries
- 4 decode slots per cycle, 5 dispatch slots per cycle
- Execution units: ALU:4, LOAD:4, STORE:4, MUL:1, DIV:1
Per-opcode pipeline metadata lives in RV_GAS_COST_LUT, indexed by
the per-kind constants below (RV_KIND_*). The interpreter and
recompiler share this LUT via rv_feed_gas_kind / rv_feed_gas_direct.
Structs§
- Fast
Cost FastCostis the per-instruction analysis the gas simulator consumes. Cycles, decode slots, exec-unit class, src/dst register masks.is_terminatormarks gas-block-ending instructions.
Enums§
- MemClass
- Memory class of a gas
kindfor category-#3 reserve accounting.
Constants§
- DEFAULT_
MEM_ CYCLES - Default load/store latency (L2 cache hit baseline).
- RV_
KIND_ ADD - RV_
KIND_ ADDI - RV_
KIND_ ADDIW - RV_
KIND_ ADDW - RV_
KIND_ BRANCH - RV_
KIND_ DIV - RV_
KIND_ ECALLI - RV_
KIND_ ECALL_ JAR - RV_
KIND_ FALLTHROUGH - RV_
KIND_ FENCE - RV_
KIND_ JAL - RV_
KIND_ JALR - RV_
KIND_ LOAD - RV_
KIND_ LUI - RV_
KIND_ MUL - RV_
KIND_ MULH - RV_
KIND_ MULHSU - RV_
KIND_ MULW - RV_
KIND_ RESERVED - RV_
KIND_ SLL - RV_
KIND_ SLLW - RV_
KIND_ SLT - RV_
KIND_ STORE - RV_
KIND_ TRAP - RV_
KIND_ ZBA - RV_
KIND_ ZBA_ IMM - RV_
KIND_ ZBB_ CTZ - RV_
KIND_ ZBB_ INV - RV_
KIND_ ZBB_ MINMAX - RV_
KIND_ ZBB_ RORI - RV_
KIND_ ZBB_ RORIW - RV_
KIND_ ZBB_ ROT - RV_
KIND_ ZBB_ ROTW - RV_
KIND_ ZBB_ U1 - RV_
KIND_ ZBB_ XNOR - RV_
KIND_ ZBS - RV_
KIND_ ZBS_ IMM - RV_
KIND_ ZICOND
Functions§
- rv_
block_ reserve_ for_ block - Worst-case category-#3 reserve (in gas) for the basic block starting
at
block_start: the maximum materialization cost the block can debit at faults. The block-entry gate reserves this (a gate, not a charge — see~/docs/spec-staging/gas-cost.md§1/§3) so #3 can never drive gas negative mid-block. - rv_
feed_ gas_ direct - Predecode-cached variant: same logic as
rv_feed_gas_kindbut takes a pre-resolvedcrate::predecode::RvGasMeta. Used by the per-block gas-cost helper that consumes thePredecodevector built bypredecode. - rv_
feed_ gas_ kind - Kind-driven PVM2 gas feed: look up the cost LUT, compute the
overlap-dependent decode_slots and the mem_cycles override, then
feed the simulator via
feed_direct. Takes raw(kind, src1, src2, dst)so the recompiler’s per-arm dispatch can supply them as compile-time constants + slot lookups without going through anRvGasMetastruct. - rv_
gas_ cost_ for_ block - Compute per-block gas cost for a PVM2 basic block. The block runs
from
insts[block_start]until the next instruction whoseis_gas_block_startis true (or the end ofinsts). Uses the single-passGasSimulator(decode-throughput + register-readiness tracking — the model fromspec/Jar/JAVM/GasCostSinglePass.lean) driven by the LUT fast path (rv_feed_gas_direct). Returnsmax(max_done − 3, 1). - rv_
gas_ meta - Compute the
crate::predecode::RvGasMetafor anInst. Called once per instruction at decode time; the result is cached incrate::predecode::RvPreDecodedInst::gas_metaso the gas hot path doesn’t have to re-match the variant. - rv_
kind_ mem_ class - Classify a gas
kindas a category-#3 memory op. Uses the sameexec_unit == EU_LOAD/EU_STOREpredicaterv_feed_gas_kinduses for the #2mem_cyclesoverride (gas_cost.rs), so “memory op for #3” and “memory op for #2” provably agree across both engines. - rv_
kind_ reserve - Per-instruction worst-case category-#3 reserve contribution for a
gas
kind:store → COW×2(×2 =MAX_PAGES_PER_ACCESS), else 0. Loads no longer reserve — read-only page-in is charged eagerly at the CALL (gas_const::call_frame_cost), not at a fault, so the only #3 a block can debit mid-flight is a store’s copy-on-write. Both engines accumulate this at every real gas feed, so the block reserve matches bit-for-bit. - rv_
slot_ u8 - PVM2 register → simulator slot (u8). 0xFF means “no register” — the
simulator’s
feed_directinterprets that as “skip dep / no write”. Single source:crate::regs::reg_slot_or_ff(the recompiler reads the same classification viaREG_SLOT_LUT, so gas agrees bit-for-bit).