Configurable EVM shared-memory pre-allocation (SharedMemoryCapacity) - #5
Merged
Merged
Conversation
The per-context EVM working-memory buffer was hardcoded to 64 KB in two places
(EvmCache + EvmOverlay), tuned for a state-heavy upstream workload. Make it a
first-class knob:
- `SharedMemoryCapacity { Fixed(usize), Auto }`, default `Fixed(64_000)`,
configured via `EvmCacheBuilder::shared_memory_capacity`. `Fixed` pins the size
(general users running wide fan-outs of small sims can lower it to cut
per-overlay memory); `Auto` sizes from the chain state loaded at build time
(e.g. a bincode state file) — `loaded_slots * 16`, clamped to a 64 KB floor /
4 MiB ceiling.
- Resolution happens in the new `with_cache_capacity` constructor (the builder's
worker; `with_cache`/`new`/`from_backend` keep their signatures, defaulting to
Fixed(64_000)). `Auto` reads the post-load layer-2 slot count, so it captures
the maintain-list filter and any source, not just the raw file.
- The resolved size is stored on EvmCache, exposed via
`EvmCache::shared_memory_capacity()`, raised by `reserve_shared_memory`, and
copied onto every EvmSnapshot so snapshot-backed EvmOverlays pre-allocate the
same amount (overlay gains a `buffer_capacity` field; the hardcoded overlay
constant is removed).
Tests: a `resolve` heuristic unit test (floor/linear/ceiling, both feature
configs) and `tests/shared_memory_capacity.rs` end-to-end over the builder
(default, Fixed, Auto-with-no-state floor, and Auto sizing 10k loaded slots →
160_000). Full suite 335 (default) / 282 (--no-default-features); fmt + clippy
(both configs) + doc + bench --no-run clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
KaiCode2
force-pushed
the
configurable-shared-memory
branch
from
June 17, 2026 08:45
1a095a2 to
776fe3e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the per-context EVM shared-memory (working-memory) buffer configurable, instead of hardcoded to 64 KB. Stacked on
phase-5-cow-snapshots(#4) because it extends that branch's shared-memory-buffer machinery.Motivation
The 64 KB buffer was tuned for a state-heavy upstream workload where resizing revm's memory to accommodate loaded chain state was hot. For general users that is often overkill — a wide parallel fan-out of small simulations pays 64 KB per overlay — while state-heavy users may want more. So: let users pick, and auto-size from a loaded state file.
API
SharedMemoryCapacity { Fixed(usize), Auto }(defaultFixed(64_000)), set on the builder:Fixed(n)pins the buffer; the 64 KB default preserves today's behavior.Autosizes from the chain state loaded at build time (e.g. a bincode state file viacache_config):loaded_slots * 16, clamped to a 64 kB floor / 4 MiB ceiling. It reads the post-load layer-2 slot count, so it reflects the maintain-list filter and any load source — not just raw file bytes.Autois an honest heuristic (persisted state size is a proxy for working-set, not a peak-memory model); the16 bytes/slotfactor and floor/ceiling are named, documented constants, andFixedis the escape hatch for anyone who has profiled.Plumbing (no breakage)
with_cache_capacityconstructor (the builder's worker).new/with_cache/from_backendkeep their signatures and default toFixed(64_000), so existing call sites are untouched.EvmCache, exposed viaEvmCache::shared_memory_capacity(), raised by the existingreserve_shared_memory, and copied onto everyEvmSnapshotso snapshot-backedEvmOverlays pre-allocate the same amount (overlay gains abuffer_capacityfield; the old hardcoded overlay constant is removed — both buffers now honor one knob).Tests
resolveheuristic unit test (floor / linear / ceiling; both feature configs).tests/shared_memory_capacity.rsend-to-end over the builder: default → 64 000;Fixed(8192)honored;Autowith no state → 64 000 floor;Autoafter persisting + reloading 10 000 slots → 160 000.--no-default-features), zero failures; fmt + clippy (both configs) + doc +bench --no-runclean.🤖 Generated with Claude Code