Skip to content

fix(evm): do not report a null-pointer dereference as an EVM memory fault - #604

Open
abmcar wants to merge 1 commit into
DTVMStack:mainfrom
abmcar:fix/evm-null-deref-classification
Open

fix(evm): do not report a null-pointer dereference as an EVM memory fault#604
abmcar wants to merge 1 commit into
DTVMStack:mainfrom
abmcar:fix/evm-null-deref-classification

Conversation

@abmcar

@abmcar abmcar commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

1. Does this PR affect any open issues?(Y/N) and add issue references (e.g. "fix #123", "re #123".):

  • N
  • Y

2. What is the scope of this PR (e.g. component or file name):

src/runtime/runtime.cpp JIT trap handling for EVM, plus one new error code in
src/common/errors.def.

3. Provide a description of the PR(e.g. more details, effects, motivations or doc link):

  • Affects user behaviors
  • Contains CI/CD configuration changes
  • Contains documentation changes
  • Contains experimental features
  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Other

The JIT trap handler mapped every SIGSEGV to ErrorCode::OutOfBoundsMemory and
EVMC_INVALID_MEMORY_ACCESS. That is correct for a real out-of-bounds EVM memory
access and wrong for a fault at a null pointer: EVM memory is a heap buffer and
is never mapped at page zero, so a fault there is a defect in compiled code, not
an EVM condition.

The misclassification is not cosmetic. EVMC_INVALID_MEMORY_ACCESS is a
consensus status, so an engine crash was handed to the embedder as a plausible
exceptional halt. Execution continued and the block finished with the wrong gas
instead of failing: on mainnet block 25818502 the replay reported 27730760 gas
used against an expected 27644811. Locating the real cause required a patched
build that printed the faulting address.

This classifies a fault in the first page as EVMNullPointerDereference /
EVMC_INTERNAL_ERROR, which is not a consensus status and which an embedder must
reject. On the affected blocks the replay now stops with an internal-status error
rather than producing a wrong gas number.

This is a tripwire, not a fix. The branch should be unreachable, and this PR
does not make it so — it only ensures that if it is reached, the embedder is told
something it must reject rather than a consensus status it may accept.

Update since this PR was opened: the specific dereference behind those two
blocks has since been found and fixed in #607 — the multipass JIT reloaded its
cached memory size after a runtime helper but never the cached base, so a frame
whose first memory growth happened inside a helper kept an entry-time null base.
That does not make this PR redundant; it is the reason the defect survived as
long as it did. Without this reclassification a null dereference is reported as
EVMC_INVALID_MEMORY_ACCESS — a consensus status — so the caller treats an
engine crash as a legitimate exceptional halt, execution continues, and the
block's gas comes out wrong instead of the run failing loudly. #607 removes that
cause; this PR makes any remaining member of the class audible. The two are
independent and separately mergeable.

4. Are there any breaking changes?(Y/N) and describe the breaking changes(e.g. more details, motivations or doc link):

  • N
  • Y

An embedder that today sees EVMC_INVALID_MEMORY_ACCESS for a null-pointer fault
in JIT'd code will now see EVMC_INTERNAL_ERROR. This is deliberate and is the
point of the change: the old status is a consensus status that an embedder may
legitimately accept as an exceptional halt, and accepting it silently converts an
engine defect into a wrong execution result. No behaviour changes for a genuine
out-of-bounds EVM memory access, which still maps to
EVMC_INVALID_MEMORY_ACCESS.

5. Are there test cases for these changes?(Y/N) select and add more details, references or doc links:

  • Unit test
  • Integration test
  • Benchmark (add benchmark stats below)
  • Manual test (add detailed scripts or steps below)
  • Other

No automated test is added: the branch is only reachable through a defect in
generated code, and there is no supported way to construct that fault from an EVM
program. Suggestions for a test hook are welcome.

Validation on a GCC 12 / LLVM 15 Release multipass build, configured to match the
existing EVM configuration (ZEN_ENABLE_EVM, ZEN_ENABLE_MULTIPASS_JIT,
ZEN_ENABLE_VIRTUAL_STACK, ZEN_ENABLE_CPU_EXCEPTION all ON):

  • ./tools/format.sh check: PASS
  • Release build on top of 338d123: PASS
  • EVM fixture generation (tools/easm2bytecode.sh): 209/209
  • ctest: 11/12 test binaries pass

The one failure, solidityContractTests (7 cases), is solc not found in this
environment. It fails identically on a pristine 338d123 build configured the
same way, which was built and run side by side for exactly this comparison — so
it is environmental, not a regression from this change. Every other binary
passes, including evmDifferentialTests, evmJitFrontendTests, evmStateTests,
evmInterpTests, evmModuleCacheTests, evmFallbackExecutionTests and
evmProfileGuidedJITTests.

Behavioural check: mainnet witness replay of blocks 25818502 and 25818530 through
the EVMC interface. Before, the run completed with an incorrect gas figure; after,
it stops with a backend/internal status. Access counts at the fault are unchanged
(152 and 45), i.e. the underlying dereference is not affected by this change.

6. Release note

Report a null-pointer fault in JIT'd EVM code as an internal error instead of an out-of-bounds memory access.

…ault

The JIT trap handler mapped every SIGSEGV to ErrorCode::OutOfBoundsMemory and
EVMC_INVALID_MEMORY_ACCESS. That is right for a real out-of-bounds EVM memory
access, and wrong for a fault at a null pointer: EVM memory is a heap buffer
and is never mapped at page zero, so a fault there is a defect in compiled
code, not an EVM condition.

The misclassification is not cosmetic. EVMC_INVALID_MEMORY_ACCESS is a
consensus status, so an engine crash was handed to the embedder as a plausible
exceptional halt; execution continued and the block finished with the wrong
gas (mainnet block 25818502: 27730760 used against an expected 27644811)
instead of failing. Finding the real cause needed a patched build printing the
faulting address.

Classify a fault in the first page as EVMNullPointerDereference /
EVMC_INTERNAL_ERROR, which is not a consensus status and which an embedder
must reject. On the two blocks above the replay now stops with "nested DTVM
returned backend/internal status -1" rather than producing a wrong gas number.

This is a tripwire, not a fix: the branch should be unreachable. The
dereference behind those two blocks is still open, and is JIT-only - both
blocks replay correctly under mode=interpreter with database access counts
matching the reference exactly (3296 and 5153).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0187PTseLY2NbzxKrnstDWwS
Copilot AI lite review requested due to automatic review settings August 28, 2026 14:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts EVM JIT trap handling so that faults at (or near) a null pointer are reported as an internal engine error rather than being misclassified as an EVM out-of-bounds memory access, preventing an engine defect from being surfaced as a consensus-visible halt condition.

Changes:

  • Add a dedicated EVMNullPointerDereference error code for JIT-only null-pointer faults.
  • Update Runtime::callEVMInJITMode signal-trap mapping to classify low-address SIGSEGV/SIGBUS as EVMC_INTERNAL_ERROR instead of EVMC_INVALID_MEMORY_ACCESS.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/runtime/runtime.cpp Adds low-address (null) fault detection in the EVM JIT trap handler and maps it to an internal EVMC status.
src/common/errors.def Introduces EVMNullPointerDereference to represent JIT null-pointer dereference defects distinctly from EVM execution faults.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/runtime/runtime.cpp
Comment on lines +933 to +936
/// Size of the unmapped low address range. A faulting address below this is a
/// null pointer plus a small offset, never a real allocation.
static constexpr uintptr_t NullPointerPageSize = 4096;

@github-actions

Copy link
Copy Markdown

⚡ Performance Regression Check Results

✅ Performance Check Passed (interpreter)

Performance Benchmark Results (threshold: 25%)

Benchmark Baseline (us) Current (us) Change Status
total/main/blake2b_huff/8415nulls 2.10 1.91 -9.0% PASS
total/main/blake2b_huff/empty 0.03 0.03 -5.1% PASS
total/main/blake2b_shifts/8415nulls 11.55 12.53 +8.5% PASS
total/main/sha1_divs/5311 6.74 6.60 -2.1% PASS
total/main/sha1_divs/empty 0.08 0.08 -4.6% PASS
total/main/sha1_shifts/5311 4.29 4.25 -0.9% PASS
total/main/sha1_shifts/empty 0.04 0.04 +2.8% PASS
total/main/snailtracer/benchmark 72.01 67.48 -6.3% PASS
total/main/structarray_alloc/nfts_rank 1.01 1.08 +6.7% PASS
total/main/swap_math/insufficient_liquidity 0.00 0.00 +3.3% PASS
total/main/swap_math/received 0.01 0.01 +2.7% PASS
total/main/swap_math/spent 0.01 0.01 -4.5% PASS
total/main/weierstrudel/1 0.26 0.25 -3.4% PASS
total/main/weierstrudel/15 2.92 2.89 -1.2% PASS
total/micro/JUMPDEST_n0/empty 2.36 2.36 -0.0% PASS
total/micro/jump_around/empty 0.08 0.08 -6.4% PASS
total/micro/loop_with_many_jumpdests/empty 52.34 53.84 +2.9% PASS
total/micro/memory_grow_mload/by1 0.13 0.13 -6.8% PASS
total/micro/memory_grow_mload/by16 0.16 0.14 -8.6% PASS
total/micro/memory_grow_mload/by32 0.09 0.11 +17.4% PASS
total/micro/memory_grow_mload/nogrow 0.07 0.09 +27.9% PASS
total/micro/memory_grow_mstore/by1 0.15 0.14 -2.0% PASS
total/micro/memory_grow_mstore/by16 0.09 0.11 +17.7% PASS
total/micro/memory_grow_mstore/by32 0.19 0.18 -7.9% PASS
total/micro/memory_grow_mstore/nogrow 0.14 0.14 -1.9% PASS
total/micro/signextend/one 0.20 0.25 +25.6% PASS
total/micro/signextend/zero 0.35 0.33 -4.7% PASS
total/synth/ADD/b0 1.75 1.75 -0.0% PASS
total/synth/ADD/b1 2.13 2.19 +2.8% PASS
total/synth/ADDRESS/a0 5.13 4.95 -3.5% PASS
total/synth/ADDRESS/a1 4.47 5.52 +23.7% PASS
total/synth/AND/b0 1.43 1.43 -0.0% PASS
total/synth/AND/b1 1.85 1.88 +1.7% PASS
total/synth/BYTE/b0 5.35 6.23 +16.3% PASS
total/synth/BYTE/b1 7.24 6.75 -6.7% PASS
total/synth/CALLDATASIZE/a0 3.62 3.92 +8.1% PASS
total/synth/CALLDATASIZE/a1 2.91 3.71 +27.5% PASS
total/synth/CALLER/a0 5.11 5.02 -1.8% PASS
total/synth/CALLER/a1 5.36 5.53 +3.1% PASS
total/synth/CALLVALUE/a0 2.97 3.70 +24.7% PASS
total/synth/CALLVALUE/a1 4.49 5.10 +13.6% PASS
total/synth/CODESIZE/a0 4.59 4.62 +0.8% PASS
total/synth/CODESIZE/a1 4.49 4.98 +10.9% PASS
total/synth/DUP1/d0 1.29 1.70 +31.6% PASS
total/synth/DUP1/d1 1.41 1.79 +27.1% PASS
total/synth/DUP10/d0 1.39 1.70 +22.1% PASS
total/synth/DUP10/d1 1.27 1.87 +47.3% PASS
total/synth/DUP11/d0 1.00 1.22 +21.6% PASS
total/synth/DUP11/d1 1.31 1.62 +23.1% PASS
total/synth/DUP12/d0 1.31 1.73 +32.0% PASS
total/synth/DUP12/d1 0.79 1.23 +55.1% PASS
total/synth/DUP13/d0 1.24 1.86 +50.2% PASS
total/synth/DUP13/d1 1.35 1.87 +38.5% PASS
total/synth/DUP14/d0 1.00 1.22 +22.1% PASS
total/synth/DUP14/d1 1.34 1.88 +39.7% PASS
total/synth/DUP15/d0 1.26 1.74 +38.7% PASS
total/synth/DUP15/d1 0.79 1.23 +54.9% PASS
total/synth/DUP16/d0 1.35 1.63 +20.3% PASS
total/synth/DUP16/d1 1.23 1.81 +47.4% PASS
total/synth/DUP2/d0 1.00 1.22 +21.5% PASS
total/synth/DUP2/d1 1.50 1.82 +21.7% PASS
total/synth/DUP3/d0 1.34 1.86 +38.8% PASS
total/synth/DUP3/d1 0.79 1.23 +55.0% PASS
total/synth/DUP4/d0 1.36 1.86 +36.9% PASS
total/synth/DUP4/d1 1.18 1.87 +58.8% PASS
total/synth/DUP5/d0 1.01 1.22 +20.8% PASS
total/synth/DUP5/d1 1.52 1.86 +22.7% PASS
total/synth/DUP6/d0 1.34 1.69 +26.2% PASS
total/synth/DUP6/d1 0.87 1.23 +41.9% PASS
total/synth/DUP7/d0 1.26 1.86 +47.2% PASS
total/synth/DUP7/d1 1.36 1.76 +29.8% PASS
total/synth/DUP8/d0 1.01 1.22 +20.2% PASS
total/synth/DUP8/d1 1.28 1.86 +45.2% PASS
total/synth/DUP9/d0 1.28 1.81 +42.2% PASS
total/synth/DUP9/d1 0.79 1.23 +54.9% PASS
total/synth/EQ/b0 4.18 4.13 -1.1% PASS
total/synth/EQ/b1 4.37 4.49 +2.6% PASS
total/synth/GAS/a0 3.03 3.88 +28.0% PASS
total/synth/GAS/a1 5.18 5.76 +11.1% PASS
total/synth/GT/b0 4.44 4.44 +0.1% PASS
total/synth/GT/b1 4.33 4.43 +2.3% PASS
total/synth/ISZERO/u0 6.49 6.49 -0.0% PASS
total/synth/JUMPDEST/n0 2.36 2.36 -0.0% PASS
total/synth/LT/b0 4.44 4.40 -0.9% PASS
total/synth/LT/b1 3.70 3.72 +0.5% PASS
total/synth/MSIZE/a0 4.72 4.46 -5.2% PASS
total/synth/MSIZE/a1 4.91 5.25 +6.9% PASS
total/synth/MUL/b0 4.95 4.93 -0.4% PASS
total/synth/MUL/b1 4.63 4.64 +0.1% PASS
total/synth/NOT/u0 1.63 1.86 +13.6% PASS
total/synth/OR/b0 1.77 2.25 +27.7% PASS
total/synth/OR/b1 1.36 1.52 +11.2% PASS
total/synth/PC/a0 3.84 3.78 -1.4% PASS
total/synth/PC/a1 2.98 3.72 +25.0% PASS
total/synth/PUSH1/p0 1.58 1.57 -0.5% PASS
total/synth/PUSH1/p1 1.25 1.60 +28.0% PASS
total/synth/PUSH10/p0 1.55 1.52 -2.0% PASS
total/synth/PUSH10/p1 1.46 1.63 +12.1% PASS
total/synth/PUSH11/p0 1.64 1.59 -3.2% PASS
total/synth/PUSH11/p1 1.58 2.11 +33.4% PASS
total/synth/PUSH12/p0 1.13 1.14 +1.3% PASS
total/synth/PUSH12/p1 1.73 1.98 +14.4% PASS
total/synth/PUSH13/p0 1.54 1.63 +6.0% PASS
total/synth/PUSH13/p1 1.25 1.60 +28.4% PASS
total/synth/PUSH14/p0 1.59 1.72 +8.3% PASS
total/synth/PUSH14/p1 1.61 2.08 +29.3% PASS
total/synth/PUSH15/p0 1.14 1.15 +1.2% PASS
total/synth/PUSH15/p1 1.81 2.11 +16.1% PASS
total/synth/PUSH16/p0 1.61 1.55 -4.0% PASS
total/synth/PUSH16/p1 1.26 1.61 +28.0% PASS
total/synth/PUSH17/p0 1.63 1.61 -1.3% PASS
total/synth/PUSH17/p1 1.62 2.09 +29.0% PASS
total/synth/PUSH18/p0 1.13 1.14 +0.2% PASS
total/synth/PUSH18/p1 1.63 1.97 +20.6% PASS
total/synth/PUSH19/p0 1.59 1.69 +5.9% PASS
total/synth/PUSH19/p1 1.29 1.60 +24.7% PASS
total/synth/PUSH2/p0 1.60 1.64 +2.7% PASS
total/synth/PUSH2/p1 1.67 2.05 +22.3% PASS
total/synth/PUSH20/p0 1.65 1.55 -5.9% PASS
total/synth/PUSH20/p1 1.66 2.05 +23.4% PASS
total/synth/PUSH21/p0 1.14 1.14 +0.2% PASS
total/synth/PUSH21/p1 1.60 1.99 +24.0% PASS
total/synth/PUSH22/p0 1.59 1.50 -5.7% PASS
total/synth/PUSH22/p1 1.24 1.60 +29.3% PASS
total/synth/PUSH23/p0 1.62 1.64 +1.3% PASS
total/synth/PUSH23/p1 1.77 2.05 +15.9% PASS
total/synth/PUSH24/p0 1.14 1.14 +0.2% PASS
total/synth/PUSH24/p1 1.59 2.04 +28.5% PASS
total/synth/PUSH25/p0 1.58 1.57 -0.2% PASS
total/synth/PUSH25/p1 1.25 1.62 +29.9% PASS
total/synth/PUSH26/p0 1.68 1.69 +0.8% PASS
total/synth/PUSH26/p1 1.86 2.03 +9.1% PASS
total/synth/PUSH27/p0 1.15 1.14 -0.3% PASS
total/synth/PUSH27/p1 1.79 2.02 +13.2% PASS
total/synth/PUSH28/p0 1.64 1.56 -4.7% PASS
total/synth/PUSH28/p1 1.25 1.61 +28.3% PASS
total/synth/PUSH29/p0 1.70 1.74 +2.6% PASS
total/synth/PUSH29/p1 1.59 2.07 +30.1% PASS
total/synth/PUSH3/p0 1.13 1.15 +2.0% PASS
total/synth/PUSH3/p1 1.66 1.96 +18.4% PASS
total/synth/PUSH30/p0 1.13 1.15 +1.8% PASS
total/synth/PUSH30/p1 1.62 2.10 +29.6% PASS
total/synth/PUSH31/p0 1.68 1.56 -6.7% PASS
total/synth/PUSH31/p1 1.25 1.61 +28.5% PASS
total/synth/PUSH32/p0 1.61 1.57 -2.4% PASS
total/synth/PUSH32/p1 1.68 2.02 +19.9% PASS
total/synth/PUSH4/p0 1.63 1.62 -0.6% PASS
total/synth/PUSH4/p1 1.24 1.59 +29.0% PASS
total/synth/PUSH5/p0 1.57 1.73 +9.7% PASS
total/synth/PUSH5/p1 1.67 2.01 +20.6% PASS
total/synth/PUSH6/p0 1.14 1.13 -1.0% PASS
total/synth/PUSH6/p1 1.74 1.94 +12.0% PASS
total/synth/PUSH7/p0 1.63 1.61 -1.3% PASS
total/synth/PUSH7/p1 1.46 1.60 +9.2% PASS
total/synth/PUSH8/p0 1.65 1.72 +6.9% PASS
total/synth/PUSH8/p1 1.66 2.11 +26.9% PASS
total/synth/PUSH9/p0 1.13 1.15 +1.5% PASS
total/synth/PUSH9/p1 1.60 2.05 +27.9% PASS
total/synth/RETURNDATASIZE/a0 2.68 3.71 +38.6% PASS
total/synth/RETURNDATASIZE/a1 4.45 4.78 +7.4% PASS
total/synth/SAR/b0 3.37 4.41 +30.9% PASS
total/synth/SAR/b1 5.79 5.88 +1.6% PASS
total/synth/SGT/b0 3.30 3.28 -0.4% PASS
total/synth/SGT/b1 2.82 2.84 +0.7% PASS
total/synth/SHL/b0 3.33 3.26 -2.0% PASS
total/synth/SHL/b1 1.40 1.49 +6.3% PASS
total/synth/SHR/b0 3.02 3.00 -0.6% PASS
total/synth/SHR/b1 2.54 2.61 +2.6% PASS
total/synth/SIGNEXTEND/b0 2.78 3.66 +31.5% PASS
total/synth/SIGNEXTEND/b1 5.08 4.67 -8.1% PASS
total/synth/SLT/b0 3.08 3.06 -0.6% PASS
total/synth/SLT/b1 3.30 3.38 +2.6% PASS
total/synth/SUB/b0 2.08 2.09 +0.9% PASS
total/synth/SUB/b1 2.16 2.22 +2.9% PASS
total/synth/SWAP1/s0 1.43 1.58 +10.2% PASS
total/synth/SWAP10/s0 1.45 1.62 +11.9% PASS
total/synth/SWAP11/s0 2.22 2.36 +6.4% PASS
total/synth/SWAP12/s0 2.06 2.37 +15.1% PASS
total/synth/SWAP13/s0 1.45 1.59 +10.0% PASS
total/synth/SWAP14/s0 2.18 2.45 +12.4% PASS
total/synth/SWAP15/s0 2.09 2.47 +18.1% PASS
total/synth/SWAP16/s0 1.45 1.60 +10.2% PASS
total/synth/SWAP2/s0 2.07 2.56 +23.7% PASS
total/synth/SWAP3/s0 2.15 2.48 +15.4% PASS
total/synth/SWAP4/s0 1.46 1.58 +8.1% PASS
total/synth/SWAP5/s0 2.13 2.43 +14.3% PASS
total/synth/SWAP6/s0 2.12 2.59 +22.1% PASS
total/synth/SWAP7/s0 1.44 1.61 +11.4% PASS
total/synth/SWAP8/s0 2.11 2.46 +16.7% PASS
total/synth/SWAP9/s0 2.19 2.38 +8.6% PASS
total/synth/XOR/b0 1.65 1.58 -4.0% PASS
total/synth/XOR/b1 1.68 1.74 +3.6% PASS
total/synth/loop_v1 7.08 7.03 -0.6% PASS
total/synth/loop_v2 7.09 7.04 -0.8% PASS

Summary: 194 benchmarks, 0 regressions


✅ Performance Check Passed (multipass)

Performance Benchmark Results (threshold: 25%)

Benchmark Baseline (us) Current (us) Change Status
total/main/blake2b_huff/8415nulls 1.39 1.50 +8.2% PASS
total/main/blake2b_huff/empty 0.02 0.02 +7.5% PASS
total/main/blake2b_shifts/8415nulls 4.35 4.37 +0.6% PASS
total/main/sha1_divs/5311 0.86 0.86 +0.0% PASS
total/main/sha1_divs/empty 0.01 0.01 -0.6% PASS
total/main/sha1_shifts/5311 0.76 0.76 -0.3% PASS
total/main/sha1_shifts/empty 0.01 0.01 -1.2% PASS
total/main/snailtracer/benchmark 48.03 48.51 +1.0% PASS
total/main/structarray_alloc/nfts_rank 0.27 0.28 +0.8% PASS
total/main/swap_math/insufficient_liquidity 0.00 0.00 +1.0% PASS
total/main/swap_math/received 0.01 0.01 +1.5% PASS
total/main/swap_math/spent 0.01 0.01 +2.4% PASS
total/main/weierstrudel/1 0.33 0.33 +0.0% PASS
total/main/weierstrudel/15 3.69 3.74 +1.3% PASS
total/micro/JUMPDEST_n0/empty 0.00 0.00 -0.0% PASS
total/micro/jump_around/empty 0.07 0.08 +12.0% PASS
total/micro/loop_with_many_jumpdests/empty 0.01 0.01 -0.5% PASS
total/micro/memory_grow_mload/by1 0.02 0.02 -1.9% PASS
total/micro/memory_grow_mload/by16 0.02 0.02 +8.2% PASS
total/micro/memory_grow_mload/by32 0.01 0.01 +2.4% PASS
total/micro/memory_grow_mload/nogrow 0.01 0.01 -3.1% PASS
total/micro/memory_grow_mstore/by1 0.02 0.02 -1.3% PASS
total/micro/memory_grow_mstore/by16 0.01 0.01 -0.7% PASS
total/micro/memory_grow_mstore/by32 0.03 0.03 -0.2% PASS
total/micro/memory_grow_mstore/nogrow 0.02 0.02 -0.9% PASS
total/micro/signextend/one 0.08 0.08 -1.7% PASS
total/micro/signextend/zero 0.20 0.19 -4.5% PASS
total/synth/ADD/b0 0.00 0.00 -0.5% PASS
total/synth/ADD/b1 0.00 0.00 -1.6% PASS
total/synth/ADDRESS/a0 0.23 0.22 -2.7% PASS
total/synth/ADDRESS/a1 0.15 0.15 -0.0% PASS
total/synth/AND/b0 0.00 0.00 -0.6% PASS
total/synth/AND/b1 0.00 0.00 +0.5% PASS
total/synth/BYTE/b0 0.00 0.00 -0.7% PASS
total/synth/BYTE/b1 0.00 0.00 -0.2% PASS
total/synth/CALLDATASIZE/a0 0.12 0.12 -1.5% PASS
total/synth/CALLDATASIZE/a1 0.07 0.07 -0.0% PASS
total/synth/CALLER/a0 0.23 0.23 +0.1% PASS
total/synth/CALLER/a1 0.22 0.24 +6.6% PASS
total/synth/CALLVALUE/a0 0.19 0.19 +0.0% PASS
total/synth/CALLVALUE/a1 0.28 0.28 -2.6% PASS
total/synth/CODESIZE/a0 0.12 0.12 -2.9% PASS
total/synth/CODESIZE/a1 0.12 0.12 -0.9% PASS
total/synth/DUP1/d0 0.00 0.00 -1.1% PASS
total/synth/DUP1/d1 0.00 0.00 -0.0% PASS
total/synth/DUP10/d0 0.00 0.00 -0.5% PASS
total/synth/DUP10/d1 0.00 0.00 +0.3% PASS
total/synth/DUP11/d0 0.00 0.00 -0.5% PASS
total/synth/DUP11/d1 0.00 0.00 +0.8% PASS
total/synth/DUP12/d0 0.00 0.00 +0.6% PASS
total/synth/DUP12/d1 0.00 0.00 -0.8% PASS
total/synth/DUP13/d0 0.00 0.00 +1.1% PASS
total/synth/DUP13/d1 0.00 0.00 +0.9% PASS
total/synth/DUP14/d0 0.00 0.00 -0.4% PASS
total/synth/DUP14/d1 0.00 0.00 +0.0% PASS
total/synth/DUP15/d0 0.00 0.00 +1.9% PASS
total/synth/DUP15/d1 0.00 0.00 -0.5% PASS
total/synth/DUP16/d0 0.00 0.00 -0.5% PASS
total/synth/DUP16/d1 0.00 0.00 +0.4% PASS
total/synth/DUP2/d0 0.00 0.00 -0.4% PASS
total/synth/DUP2/d1 0.00 0.00 +0.2% PASS
total/synth/DUP3/d0 0.00 0.00 +0.3% PASS
total/synth/DUP3/d1 0.00 0.00 -0.1% PASS
total/synth/DUP4/d0 0.00 0.00 -0.4% PASS
total/synth/DUP4/d1 0.00 0.00 -0.5% PASS
total/synth/DUP5/d0 0.00 0.00 -0.2% PASS
total/synth/DUP5/d1 0.00 0.00 +0.0% PASS
total/synth/DUP6/d0 0.00 0.00 +0.8% PASS
total/synth/DUP6/d1 0.00 0.00 -0.6% PASS
total/synth/DUP7/d0 0.00 0.00 +9.0% PASS
total/synth/DUP7/d1 0.00 0.00 +2.7% PASS
total/synth/DUP8/d0 0.00 0.00 -0.6% PASS
total/synth/DUP8/d1 0.00 0.00 +0.1% PASS
total/synth/DUP9/d0 0.00 0.00 -1.5% PASS
total/synth/DUP9/d1 0.00 0.00 -0.5% PASS
total/synth/EQ/b0 0.00 0.00 +0.8% PASS
total/synth/EQ/b1 0.00 0.00 +0.3% PASS
total/synth/GAS/a0 0.76 0.77 +0.2% PASS
total/synth/GAS/a1 0.91 0.92 +1.7% PASS
total/synth/GT/b0 0.00 0.00 -0.4% PASS
total/synth/GT/b1 0.00 0.00 +1.7% PASS
total/synth/ISZERO/u0 0.00 0.00 +2.0% PASS
total/synth/JUMPDEST/n0 0.00 0.00 +0.1% PASS
total/synth/LT/b0 0.00 0.00 -0.9% PASS
total/synth/LT/b1 0.00 0.00 -0.3% PASS
total/synth/MSIZE/a0 0.00 0.00 +0.1% PASS
total/synth/MSIZE/a1 0.00 0.00 +0.2% PASS
total/synth/MUL/b0 0.00 0.00 +0.1% PASS
total/synth/MUL/b1 0.00 0.00 +0.3% PASS
total/synth/NOT/u0 0.00 0.00 +2.2% PASS
total/synth/OR/b0 0.00 0.00 -0.1% PASS
total/synth/OR/b1 0.00 0.00 -0.6% PASS
total/synth/PC/a0 0.00 0.00 +0.3% PASS
total/synth/PC/a1 0.00 0.00 -1.2% PASS
total/synth/PUSH1/p0 0.00 0.00 -0.4% PASS
total/synth/PUSH1/p1 0.00 0.00 -0.1% PASS
total/synth/PUSH10/p0 0.00 0.00 -1.7% PASS
total/synth/PUSH10/p1 0.00 0.00 +2.1% PASS
total/synth/PUSH11/p0 0.00 0.00 +1.3% PASS
total/synth/PUSH11/p1 0.00 0.00 -3.0% PASS
total/synth/PUSH12/p0 0.00 0.00 +2.5% PASS
total/synth/PUSH12/p1 0.00 0.00 -3.1% PASS
total/synth/PUSH13/p0 0.00 0.00 +0.2% PASS
total/synth/PUSH13/p1 0.00 0.00 +2.1% PASS
total/synth/PUSH14/p0 0.00 0.00 -3.3% PASS
total/synth/PUSH14/p1 0.00 0.00 +0.6% PASS
total/synth/PUSH15/p0 0.00 0.00 +1.9% PASS
total/synth/PUSH15/p1 0.00 0.00 +0.2% PASS
total/synth/PUSH16/p0 0.00 0.00 +3.3% PASS
total/synth/PUSH16/p1 0.00 0.00 +0.6% PASS
total/synth/PUSH17/p0 0.00 0.00 -8.4% PASS
total/synth/PUSH17/p1 0.00 0.00 +0.8% PASS
total/synth/PUSH18/p0 0.00 0.00 +1.9% PASS
total/synth/PUSH18/p1 0.00 0.00 +1.3% PASS
total/synth/PUSH19/p0 0.00 0.00 +4.9% PASS
total/synth/PUSH19/p1 0.00 0.00 +1.6% PASS
total/synth/PUSH2/p0 0.00 0.00 +1.1% PASS
total/synth/PUSH2/p1 0.00 0.00 -3.2% PASS
total/synth/PUSH20/p0 0.00 0.00 -1.1% PASS
total/synth/PUSH20/p1 0.00 0.00 -4.8% PASS
total/synth/PUSH21/p0 0.00 0.00 +1.3% PASS
total/synth/PUSH21/p1 0.00 0.00 -2.3% PASS
total/synth/PUSH22/p0 1.67 1.88 +12.6% PASS
total/synth/PUSH22/p1 1.63 1.75 +6.8% PASS
total/synth/PUSH23/p0 1.68 1.89 +13.4% PASS
total/synth/PUSH23/p1 1.99 2.26 +13.5% PASS
total/synth/PUSH24/p0 1.20 1.32 +10.2% PASS
total/synth/PUSH24/p1 1.92 2.24 +16.5% PASS
total/synth/PUSH25/p0 1.66 1.90 +14.4% PASS
total/synth/PUSH25/p1 1.65 1.75 +6.0% PASS
total/synth/PUSH26/p0 1.67 1.89 +13.7% PASS
total/synth/PUSH26/p1 1.88 2.25 +19.6% PASS
total/synth/PUSH27/p0 1.20 1.33 +10.6% PASS
total/synth/PUSH27/p1 1.87 2.26 +21.0% PASS
total/synth/PUSH28/p0 1.68 1.88 +11.8% PASS
total/synth/PUSH28/p1 1.64 1.76 +7.3% PASS
total/synth/PUSH29/p0 1.65 1.88 +13.6% PASS
total/synth/PUSH29/p1 1.89 2.24 +18.7% PASS
total/synth/PUSH3/p0 0.00 0.00 -0.4% PASS
total/synth/PUSH3/p1 0.00 0.00 -2.6% PASS
total/synth/PUSH30/p0 1.29 1.44 +11.4% PASS
total/synth/PUSH30/p1 1.97 2.30 +16.4% PASS
total/synth/PUSH31/p0 1.68 1.88 +11.8% PASS
total/synth/PUSH31/p1 1.70 1.83 +8.0% PASS
total/synth/PUSH32/p0 1.65 1.92 +16.5% PASS
total/synth/PUSH32/p1 1.92 2.22 +15.4% PASS
total/synth/PUSH4/p0 0.00 0.00 -1.6% PASS
total/synth/PUSH4/p1 0.00 0.00 +0.4% PASS
total/synth/PUSH5/p0 0.00 0.00 +2.0% PASS
total/synth/PUSH5/p1 0.00 0.00 +0.4% PASS
total/synth/PUSH6/p0 0.00 0.00 -0.7% PASS
total/synth/PUSH6/p1 0.00 0.00 +3.6% PASS
total/synth/PUSH7/p0 0.00 0.00 +3.5% PASS
total/synth/PUSH7/p1 0.00 0.00 -0.1% PASS
total/synth/PUSH8/p0 0.00 0.00 -2.5% PASS
total/synth/PUSH8/p1 0.00 0.00 +1.2% PASS
total/synth/PUSH9/p0 0.00 0.00 -1.1% PASS
total/synth/PUSH9/p1 0.00 0.00 -5.8% PASS
total/synth/RETURNDATASIZE/a0 0.03 0.03 -0.2% PASS
total/synth/RETURNDATASIZE/a1 0.06 0.06 +0.9% PASS
total/synth/SAR/b0 0.00 0.00 -0.4% PASS
total/synth/SAR/b1 0.00 0.00 +0.7% PASS
total/synth/SGT/b0 0.00 0.00 +0.7% PASS
total/synth/SGT/b1 0.00 0.00 -0.5% PASS
total/synth/SHL/b0 0.00 0.00 +0.4% PASS
total/synth/SHL/b1 0.00 0.00 -0.2% PASS
total/synth/SHR/b0 0.00 0.00 +0.6% PASS
total/synth/SHR/b1 0.00 0.00 +0.7% PASS
total/synth/SIGNEXTEND/b0 0.00 0.00 -0.1% PASS
total/synth/SIGNEXTEND/b1 0.00 0.00 +1.0% PASS
total/synth/SLT/b0 0.00 0.00 -0.7% PASS
total/synth/SLT/b1 0.00 0.00 -0.5% PASS
total/synth/SUB/b0 0.00 0.00 +1.2% PASS
total/synth/SUB/b1 0.00 0.00 +0.3% PASS
total/synth/SWAP1/s0 0.00 0.00 -0.9% PASS
total/synth/SWAP10/s0 0.00 0.00 -0.3% PASS
total/synth/SWAP11/s0 0.00 0.00 +0.0% PASS
total/synth/SWAP12/s0 0.00 0.00 +0.4% PASS
total/synth/SWAP13/s0 0.00 0.00 -0.2% PASS
total/synth/SWAP14/s0 0.00 0.00 -0.8% PASS
total/synth/SWAP15/s0 0.00 0.00 -0.2% PASS
total/synth/SWAP16/s0 0.00 0.00 -0.7% PASS
total/synth/SWAP2/s0 0.00 0.00 -0.2% PASS
total/synth/SWAP3/s0 0.00 0.00 +0.6% PASS
total/synth/SWAP4/s0 0.00 0.00 -0.2% PASS
total/synth/SWAP5/s0 0.00 0.00 +0.3% PASS
total/synth/SWAP6/s0 0.00 0.00 -0.8% PASS
total/synth/SWAP7/s0 0.00 0.00 -0.5% PASS
total/synth/SWAP8/s0 0.00 0.00 +3.9% PASS
total/synth/SWAP9/s0 0.00 0.00 -0.0% PASS
total/synth/XOR/b0 0.00 0.00 +0.8% PASS
total/synth/XOR/b1 0.00 0.00 -0.9% PASS
total/synth/loop_v1 8.20 8.69 +6.0% PASS
total/synth/loop_v2 8.59 8.48 -1.2% PASS

Summary: 194 benchmarks, 0 regressions


@abmcar

abmcar commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Updated section 3 of the description: when this PR was opened, the underlying null dereference was still unlocated. It has since been found and fixed in #607 (the multipass JIT reloaded its cached memory size after a runtime helper but never the cached base). Noting the edit here rather than leaving it silent.

This PR is unaffected in substance. The relationship between the three, for anyone reviewing them together:

Each stands alone, which is why they are three PRs and not one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants