perf(wasm-privacy-coin): JIT-compile WASM + cache module/pool instances#322
Open
OttoAllmendinger wants to merge 1 commit into
Open
perf(wasm-privacy-coin): JIT-compile WASM + cache module/pool instances#322OttoAllmendinger wants to merge 1 commit into
OttoAllmendinger wants to merge 1 commit into
Conversation
OttoAllmendinger
force-pushed
the
otto/T1-3728-jit-compile-wasm-cache
branch
from
July 20, 2026 18:05
4a0d789 to
ebfa3fc
Compare
The shielded merkle tree test suite spent ~452s, almost entirely in WASM module setup rather than tree operations. Three layers of fix: 1. Module caching — the parsed WasmModule is cached in a static volatile field (immutable, safely shared). Only the first WasmBridge pays the parse cost; subsequent trees reuse it. 2. Instance pooling — a ConcurrentLinkedDeque reuses Chicory Instances. close() drops the in-WASM tree via drop_tree and returns the Instance to the pool; the next WasmBridge borrows it and from_frontier / from_state re-initializes the tree state. Failed init uses discard() to avoid polluting the pool with a dirty Instance. 3. JIT compiler — upgraded Chicory 1.1.1 -> 1.7.5 and added the compiler module. MachineFactoryCompiler translates all WASM functions to JVM bytecode once per JVM, replacing the interpreter with native-speed execution that the JVM C2 JIT further optimizes. Results on a downstream shielded merkle tree test suite that consumes this package: MerkleTreeServiceTest 213s -> 2.96s (72x) MerkleTreePruningTest 194s -> 3.38s (57x) MerkleTreeEndToEndTest 45s -> 4.57s (10x) Total 452s -> 10.9s (41x) All 41 wasm-privacy-coin tests pass, plus the downstream consumer's merkle tree tests. The Chicory version bump (1.1.1 -> 1.7.5) is a breaking change for any consumer still on 1.1.1. Refs: T1-3728
OttoAllmendinger
force-pushed
the
otto/T1-3728-jit-compile-wasm-cache
branch
from
July 21, 2026 08:16
ebfa3fc to
418a75d
Compare
Ranjna-G
approved these changes
Jul 21, 2026
OttoAllmendinger
marked this pull request as ready for review
July 21, 2026 08:47
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.
Summary
The shielded merkle tree test suite that consumes this package (
MerkleTreeServiceTest,MerkleTreePruningTest,MerkleTreeEndToEndTest) was spending ~452s — almost entirely in WASM module setup, not actual tree operations. This PR makes those tests ~41x faster (452s → 10.9s) with three layers of optimization inwasm-privacy-coin.Root cause
WasmBridgere-parsed the 466 KBprivacy_coin.wasmbinary and re-instantiated a fresh ChicoryInstanceon everyShieldedMerkleTreecreation (~14s per cycle). Chicory 1.1.1 was interpreter-only, so even after caching, interpreted WASM execution dominated the remainder.Changes
Module caching (
WasmBridge.java) — the parsedWasmModuleis cached in astatic volatilefield (immutable, safely shared across threads). Only the firstWasmBridge()pays the parse cost.Instance pooling (
WasmBridge.java) — aConcurrentLinkedDeque<Instance>reuses Chicory Instances. Onclose(),drop_treedrops the in-WASM tree and the Instance returns to the pool. The nextWasmBridge()borrows it;from_frontier/from_statere-initializes the tree state in the existing linear memory. Failed init usesdiscard()to avoid polluting the pool with a dirty Instance.JIT compiler (
pom.xml+WasmBridge.java) — upgraded Chicory 1.1.1 → 1.7.5 and added thecompilermodule.MachineFactoryCompiler.compile(module)JIT-compiles all WASM functions to JVM bytecode once per JVM; the resultingMachinereplaces the interpreter, giving native-speed execution that the JVM C2 JIT further optimizes.ShieldedMerkleTree.close()now delegates toWasmBridge.close()(which drops the tree + pools the instance), andcreate()usesdiscard()on init failure.Results (downstream shielded merkle tree test suite)
MerkleTreeServiceTest(15 tests)MerkleTreePruningTest(3 tests)MerkleTreeEndToEndTest(2 tests)Verification
wasm-privacy-cointests pass.Refs: T1-3728