@fitzgen (he/him) I was poking at somethings and noticed that there's a few instances in wasm translation where features.gc() affects what CLIF is generated. Notably checking type signatures in call-indirect (and another here) changes whether or not GC is enabled.
I think this is probably something we're going to want to fix prior to enable-by-default (or before we ship on-by-default) because otherwise this looks like it's de-optimizing the call_indirect path with gc enabled. I think this is probably an easy fix (specialize funcref tables specifically) by my read, but wanted to flag this with you
Alex Crichton said:
because otherwise this looks like it's de-optimizing the
call_indirectpath with gc enabled.
The fast path for call-indirect with GC is the same as call-indirect without GC, and the slow path with GC will always result in a trap without GC, so I don't think this is actually de-optimizing anything (other than a very slight bit of code size bloat, which is acceptable in this case IMO)
The codegen definitely changes though, and notably with -Wgc I see:
cmp esi, edx
sete al
movzx eax, al
...
test eax, eax
je 0xa2 <wasm[0]::function[0]+0xa2>
cmp esi, edx
sete al
movzx eax, al
cmp esi, edx
je 0x64 <wasm[0]::function[0]+0x64>
cries in peephole optimization and path-sensitive constant propagation pain
(eax will always be constant 1 when taken, constant 0 when not -- and after N years of effort our flags-related codegen is still decidedly Not Great. tangential to topic but we definitely still have low-hanging fruit here)
I can never get sightglass to do what I want...
execution
./benchmarks/spidermonkey/spidermonkey-markdown.wasm
cycles
[115443777 126864658.04 195022945] ../wasmtime/target/release/libwasmtime_bench_api.so
[122040249 130580372.04 194436680] ../wasmtime/target/release/libwasmtime_bench_api.so (-Wgc)
is the best I can get out of sightglass
so ~3% slowdown
hrm okay I can investigate
Alex Crichton said:
I can never get sightglass to do what I want...
execution ./benchmarks/spidermonkey/spidermonkey-markdown.wasm cycles [115443777 126864658.04 195022945] ../wasmtime/target/release/libwasmtime_bench_api.so [122040249 130580372.04 194436680] ../wasmtime/target/release/libwasmtime_bench_api.so (-Wgc)is the best I can get out of sightglass
fwiw, sightglass will currently only do its effect-size test when there are exactly two different engines, we haven't implemented the logic to do that when there is one engine but two different sets of engine flags, but should be pretty straightforward to do
One option available now: you can run multiple benchmark runs with different flags and then get the analysis results using the report command; this will generate a report including effect size analysis relative to the baseline (first input specified unless you override).
With the "raw" results recorded, which with my latest round of updates does capture flags, you can then use report for an html report and can also use the summarize and effect-size commands on the results.
This is mac-specific as written (but easy to adapt) to show one way of wiring this up for an experiment.
#!/usr/bin/env bash
set -x
OUTDIR=${OUTDIR:-"bench-$(date +%Y%m%d-%H%M%S)"}
REVISION=${REVISION:-"v45.0.1"}
mkdir -p "$OUTDIR"
sightglass() {
cargo run --release -- "$@"
}
build_engine() {
engine_dir="$PWD/engines/wasmtime/$REVISION"
# early exit if the directory exists; assume built
if [ -f "$engine_dir/libengine.dylib" ]; then
return 0
fi
mkdir -p "$engine_dir"
(
cd engines/wasmtime || exit
rustc build.rs
REVISION="$REVISION" ./build "$engine_dir"
)
}
benchmark() {
flags="$1"
variant="$2"
build_engine
sightglass benchmark \
--raw \
-e "engines/wasmtime/$REVISION/libengine.dylib" \
--engine-flags="$flags" \
-o "$OUTDIR/$variant.json"
}
benchmark "" "baseline"
benchmark "-Wgc" "gc"
(
cd "$OUTDIR" || exit
sightglass report -o report.html ./*.json
sightglass summarize -f ./*.json
)
Oh that's what I ended up doing yeah but the summarize at the end didn't print out %-changes
it also took me embarassingly long to figure out that I needed to use --raw to emit json
Yeah, I think we should change that. I think if an output file is specified or format, that should just infer you want structured output rather than the summary.
I think there's a collect/analyze flow that is probably going to be used enough that there's probably some command (maybe collect or record) that takes as input some sort of experiment description.
That's hand-wavy and coming up with an "experiment description" format that's powerful enough and concise is the hard part.
Last updated: Jul 29 2026 at 05:03 UTC