Skip to content

wasm2c: Save memory base/size locally as a perf optimization - #2804

Merged
shravanrn merged 3 commits into
WebAssembly:mainfrom
UT-Security:local-base
Aug 18, 2026
Merged

wasm2c: Save memory base/size locally as a perf optimization#2804
shravanrn merged 3 commits into
WebAssembly:mainfrom
UT-Security:local-base

Conversation

@shravanrn

@shravanrn shravanrn commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

For Wasm modules with a single unshared wasm-32 memory, and when using the MMap based memory allocation (which guarantees that the base won't move over the Wasm instance lifetime), this change caches the memory base and memory size ina local variables and uses that instead of fetching the value each time from the instance pointer.

While this seems like it really shouldn't do much, it unlocks a bunch of optimizations in C compilers, as they don't seem to be able to reason that the base pointer hasn't changed after most function calls with the Wasm code. The end result is some dramatic improvements.

Alternate approaches - I tried to get the same benefits using the restrict keyword on instances and const keyword on memory, but these didn't work.

As a reference, this approach is able to claw back a lot of the same performance overheads of segue (i.e., using the segment register) in wasm2c except without segment registers, meaning this will work on all platforms. This makes some intuitive sense, as I expect that segue is more important to classic SFI tools (like LFI) rather than a Wasm like system. (But there are other benchmarks that segue still is a huge win --- on average, segue still remains the best option if supported on the target platform)

Local size optimization

Removes roughly 4% to 10% of overhead across multiple benchmarks in Firefox. Below is the improvement in performance.

Expat: 5.6% to 6.5%
Graphite: 3.7%
WOFF2: 9.6%
Ogg: 5.5%
Hunspell: 4.4%

Local base optimization

Here are the performance numbers from two use cases in Firefox: Expat XML parsing, Graphite font rendering that use Wasm sandboxes. The number is the overhead over native code (so bigger is worse)

Note the "local base" row is the new row below

Expat XML parsing overhead

Baseline: native

Wasm2c (Mmap + guard pages, no segue): +37.6%
Wasm2c (Mmap + guard pages, segue): +13.7%
Wasm2c (Mmap + guard pages, local base): +18.7%

Wasm2c (Mmap + bounds checks, no segue): +50.7%
Wasm2c (Mmap + bounds checks, segue): +37.4%
Wasm2c (Mmap + bounds checks, local base): +32.8%

Graphite font overhead

Baseline: native

Wasm2c (Mmap + guard pages, no segue): +41.2%
Wasm2c (Mmap + guard pages, segue): +18.2%
Wasm2c (Mmap + guard pages, local base): +14.1%

Wasm2c (Mmap + bounds checks, no segue): +60.0%
Wasm2c (Mmap + bounds checks, segue): +43.3%
Wasm2c (Mmap + bounds checks, local base): +41.8%

I intend to enable this optimization in Firefox's builds asap once it is landed here.

@sbc100

sbc100 commented Aug 3, 2026

Copy link
Copy Markdown
Member

Can you update the PR description now that part 1 has landed?

@shravanrn

shravanrn commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

Did some cleanup to simplify the code and reduce the code-diff and updated the PR description.

@sbc100

sbc100 commented Aug 3, 2026

Copy link
Copy Markdown
Member

In your benchmark results I guess +37.6% means 37% overhead compared to native? i.e. bigger is worse?

Comment thread src/template/wasm2c.declarations.c
@shravanrn
shravanrn requested a review from sbc100 August 7, 2026 19:20
@shravanrn shravanrn changed the title wasm2c: Save memory base locally as a perf optimization wasm2c: Save memory base/size locally as a perf optimization Aug 15, 2026
@shravanrn

Copy link
Copy Markdown
Collaborator Author

@sbc100 @keithw Just rebased and also added a memory size caching. Any chance y'all can review this? Would love to land this as this is the most substantial performance fix I've found, and I would like to start using this in Firefox.

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm.

Lets give @keithw another day to respond. Feel free to land EOD monday if we don't hear back.

@shravanrn

Copy link
Copy Markdown
Collaborator Author

lgtm.

Lets give @keithw another day to respond. Feel free to land EOD monday if we don't hear back.

Thanks @sbc100 Will wait till EOD Monday. Could you sign off on the code review if it looks good, as I won't be able to land this on Monday if no one signs off

@shravanrn
shravanrn enabled auto-merge (rebase) August 18, 2026 21:02
@shravanrn
shravanrn merged commit 9d9366b into WebAssembly:main Aug 18, 2026
17 checks passed
@shravanrn
shravanrn deleted the local-base branch August 18, 2026 21:14
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.

2 participants