Skip to main content

Module gas_cost

Module gas_cost 

Source
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§

FastCost
FastCost is the per-instruction analysis the gas simulator consumes. Cycles, decode slots, exec-unit class, src/dst register masks. is_terminator marks gas-block-ending instructions.

Enums§

MemClass
Memory class of a gas kind for 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_kind but takes a pre-resolved crate::predecode::RvGasMeta. Used by the per-block gas-cost helper that consumes the Predecode vector built by predecode.
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 an RvGasMeta struct.
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 whose is_gas_block_start is true (or the end of insts). Uses the single-pass GasSimulator (decode-throughput + register-readiness tracking — the model from spec/Jar/JAVM/GasCostSinglePass.lean) driven by the LUT fast path (rv_feed_gas_direct). Returns max(max_done − 3, 1).
rv_gas_meta
Compute the crate::predecode::RvGasMeta for an Inst. Called once per instruction at decode time; the result is cached in crate::predecode::RvPreDecodedInst::gas_meta so the gas hot path doesn’t have to re-match the variant.
rv_kind_mem_class
Classify a gas kind as a category-#3 memory op. Uses the same exec_unit == EU_LOAD/EU_STORE predicate rv_feed_gas_kind uses for the #2 mem_cycles override (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_direct interprets that as “skip dep / no write”. Single source: crate::regs::reg_slot_or_ff (the recompiler reads the same classification via REG_SLOT_LUT, so gas agrees bit-for-bit).