Skip to content

[WASM R0] build: define ecosystem ABI profiles - #2471

Merged
xushiwei merged 7 commits into
xgo-dev:mainfrom
cpunion:codex/wasm-r0-targets-cpunion-20260901
Sep 2, 2026
Merged

[WASM R0] build: define ecosystem ABI profiles#2471
xushiwei merged 7 commits into
xgo-dev:mainfrom
cpunion:codex/wasm-r0-targets-cpunion-20260901

Conversation

@cpunion

@cpunion cpunion commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Part of #2152.

This replaces the earlier draft #2469 after the target contract was clarified and the implementation was rebuilt on current main. Full CI validation was completed in cpunion#218.

Summary

  • add the canonical C-ecosystem targets emscripten, emscripten-memory64, and wasi;
  • retain wasm as the Emscripten wasm32 compatibility name and wasip1 as the WASI Preview 1 compatibility name;
  • propagate an explicit WebAssembly ABI profile through target resolution, SSA, Go/C type layout, output selection, diagnostics, and package-cache fingerprints;
  • make named wasm/wasi targets resolve to their physical WebAssembly backend instead of producing a host artifact with a .wasm suffix;
  • add an actual Emscripten module runner and Go/C ABI probes for wasm32 and full Memory64/LP64;
  • keep wasm-unknown and wasip2 as distinct freestanding/component profiles without treating their borrowed source-selection GOOS/GOARCH as the physical backend.

The public target contract is:

Command ABI/toolchain
llgo build -target emscripten Emscripten wasm32 C ABI
llgo build -target emscripten-memory64 Emscripten full Memory64/LP64 C ABI
llgo build -target wasm compatibility alias of emscripten
llgo build -target wasi WASI Preview 1 wasm32 C ABI
llgo build -target wasip1 compatibility alias of wasi

Compatibility and scope

The standard wasm, js && wasm, and wasip1 && wasm source constraints are reserved for official Go semantics. R0 does not introduce an llgo.wasm.go tag and does not add a C-ecosystem tag to raw GOOS/GOARCH:

  • GOOS=js GOARCH=wasm keeps its current driver behavior but receives no llgo.wasm.emscripten tag or Emscripten cache identity;
  • GOOS=wasip1 GOARCH=wasm keeps its current driver behavior but receives no llgo.wasm.wasi tag or WASI C-profile cache identity;
  • only explicit ecosystem targets add llgo.wasm.emscripten, llgo.wasm.emscripten.memory64, or llgo.wasm.wasi;
  • named Emscripten targets additionally enable the configured Node emulator, without adding Node glue to raw browser/worker output.

The current raw 32-bit layout and runtime are implementation gaps to close in G1/G2, not long-term C-profile contracts. G1/G2 make the standard tag combinations Go-compatible without requiring a positive LLGo-specific Go ABI source tag.

The old targets/wasm.json was an unreachable TinyGo-derived mixture of a JS source context, WASI triple/libc, and wasm_exec.js; it was not the working raw js/wasm path. The retained wasm name now follows that working Emscripten path.

This intentionally changes the implicit executable name for -target wasm
from package.wasm to the Emscripten entry module package.mjs (with its
package.wasm sidecar). Scripts that consume a standalone WASI module should
use -target wasi; scripts using the legacy Emscripten target should launch or
publish the .mjs entry module.

The named Emscripten/WASI JSON files contain only the profile identity, source
tags, LLVM triple, and emulator fields that the named path actually consumes.
Ecosystem driver, compiler, libc, and linker flags remain centralized in the
existing installed-toolchain paths instead of presenting ignored JSON knobs.
The Memory64 emulator probes Node and uses the legacy
--experimental-wasm-memory64 flag only on releases that still require it.

This is the R0 foundation only. It does not add a scheduler, blocking primitive, timer, or collector. R1 changes WASI process entry, imported-memory ownership, exception/longjmp behavior, and scheduling as one coherent runtime contract before executing the WASI probes under Wasmtime. R3 restores linked freestanding/component acceptance; R0 verifies their resolver, backend, layout, and cache identities without reviving the borrowed linux/arm source set as an ABI.

Validation

  • go test ./internal/targets ./internal/crosscompile ./ssa
  • go test -coverprofile=... ./internal/crosscompile (90.5% package coverage)
  • go test -coverprofile=... ./internal/build (425.975s, 86.4% package coverage)
  • invalid/missing ABI profile, GOOS, and LLVM-triple rejection tests
  • go test ./internal/build -run '^TestPCLNExternalLinkOptionsIntegration$' -count=1 -v
  • dev/test_wasm_target_profiles.sh
  • llgo run -target emscripten -emulator ./internal/build/testdata/wasm-profile
  • llgo run -target emscripten-memory64 -emulator ./internal/build/testdata/wasm-profile
  • llgo run -target wasm -emulator ./internal/build/testdata/wasm-profile
  • actionlint .github/workflows/llgo.yml

The executable probes verify Go uintptr, C sizeof(void *), and C sizeof(long) together. Emscripten wasm32, Memory64, and the legacy alias all instantiate their generated module and print wasm ABI profile ok; canonical and legacy WASI entries emit modules with the WebAssembly magic rather than host binaries.

Native macOS/arm64 size comparison against the direct main base, with identical flags and cache disabled:

Program Base This PR Delta
cprintf 84,480 B 84,480 B 0 B
println 114,944 B 114,944 B 0 B
fmtprintf 1,473,136 B 1,473,136 B 0 B

All three native binaries also produced the same expected output.

@fennoai fennoai Bot 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.

Review: WASM target profiles (memory64 / emscripten)

Solid, well-tested change. The new WasmABI type gives WebAssembly ecosystem ABIs a first-class, cache-participating identity instead of overloading GOOS/GOARCH, validation is layered defensively across the direct/named/generic entry points, and the model_32.go / model_memory64.go fixture pair genuinely verifies 64-bit pointer semantics at runtime rather than just checking WASM magic bytes. No correctness-blocking defects found. Security review found nothing exploitable (the emulator template is executed via shellparse + exec.Command, not a shell; scripts quote inputs and operate on trusted build-time data). Performance is unaffected — all changed Go paths run once per build.

Findings below are minor / worth-acknowledging, not blocking.

Additional (no reliable inline location):

  • dev/test_wasm_target_profiles.sh — The emscripten-memory64-runner.mjs probe/retry logic is never exercised by CI. run_node always invokes targets/emscripten-runner.mjs and the memory64 case manually retries with --experimental-wasm-memory64, while llgo run uses the new emscripten-memory64-runner.mjs (with its WebAssembly.validate probe + spawnSync re-exec). The shipped runner's non-trivial branching therefore has no automated coverage, and the script's manual --experimental-wasm-memory64 retry contradicts that runner's own comment about newer Node rejecting the flag. Consider running the actual memory64 runner, or aligning/clarifying the divergence.
  • THIRD_PARTY_NOTICES.md:33 — Stale reference to targets/wasm_exec.js. This PR removes the last functional use of that file (the old wasm.json emulator line) and the file is not present in the tree, so the notice entry should be removed or corrected.
  • User-facing docs-target wasm materially changes: it now inherits from emscripten and emits an ES-module (.mjs) + sibling .wasm via emcc/Node instead of a WASI .wasm via wasm-ld. Neither the new emscripten / emscripten-memory64 profiles nor the output-extension change are reflected in the README target table (line ~57). Worth documenting so operators aren't surprised by the .mjs output.
  • targets/wasip2.json / targets/wasm-unknown.json — Both drop "libc": "wasmbuiltins". Since getLibcCompileConfigByName only supports picolibc/newlib-esp32, a wasmbuiltins value would have errored if these targets reached UseTarget with libc set — so this is effectively a cleanup/fix rather than a regression, worth calling out explicitly given the PR is otherwise framed as additive.

Comment thread internal/build/outputs.go
Comment thread internal/build/build.go
Comment thread internal/crosscompile/crosscompile.go Outdated
@cpunion cpunion added the wasm WebAssembly, wasm32, and WASI support label Sep 1, 2026
@cpunion

cpunion commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the non-inline review notes in b837f77:

  • the target-profile script now executes emscripten-memory64-runner.mjs directly, covering its Memory64 probe/re-exec path;
  • the README documents the named Emscripten/WASI profiles and .mjs plus sibling .wasm output contract;
  • the removed wasmbuiltins values were stale/unsupported target metadata, while compiler/libc/linker selection remains centralized in the installed-toolchain path as described in the PR body.

I kept the THIRD_PARTY_NOTICES.md entry: targets/wasm_exec.js is still present and distributed in this tree, so its Go BSD notice remains required even though the legacy target no longer invokes it.

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.76543% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/build/build.go 93.33% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

LLGo baseline benchmarks

eea855338111 | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Text size vs base Build vs base Run vs base
Linux cprintf 19608 B 0 B / +0.0% 387 B 0 B / +0.0% 356.112 ms -5.522 ms / -1.5% (better) 1.401 ms -9.605 us / -0.7% (better)
Linux cprintf-lto 19440 B 0 B / +0.0% 368 B 0 B / +0.0% 363.761 ms +2.869 ms / +0.8% (worse) 1.394 ms +1.492 us / +0.1% (worse)
Linux fmtprintf 1615688 B 0 B / +0.0% 493418 B 0 B / +0.0% 2.539 s +42.77 ms / +1.7% (worse) 3.501 ms +3.415 us / +0.1% (worse)
Linux fmtprintf-lto 1491480 B 0 B / +0.0% 453936 B 0 B / +0.0% 8.693 s -193.8 ms / -2.2% (better) 3.379 ms +102.4 us / +3.1% (worse)
Linux println 62808 B 0 B / +0.0% 15360 B 0 B / +0.0% 354.522 ms -345.7 us / -0.1% (better) 1.725 ms +210 ns / +0.01217% (worse)
Linux println-lto 54648 B 0 B / +0.0% 12985 B 0 B / +0.0% 545.763 ms -10.85 ms / -1.9% (better) 1.732 ms -43.3 us / -2.4% (better)
macOS cprintf 84480 B 0 B / +0.0% 16845 B 0 B / +0.0% 465.618 ms +47.1 ms / +11.3% (worse) 3.087 ms +729.7 us / +31.0% (worse)
macOS cprintf-lto 100704 B 0 B / +0.0% 16825 B 0 B / +0.0% 562.204 ms +73.68 ms / +15.1% (worse) 3.211 ms +587.1 us / +22.4% (worse)
macOS fmtprintf 1473136 B 0 B / +0.0% 869312 B 0 B / +0.0% 2.547 s +151.2 ms / +6.3% (worse) 4.720 ms +193.1 us / +4.3% (worse)
macOS fmtprintf-lto 1176000 B 0 B / +0.0% 864884 B 0 B / +0.0% 6.965 s -915.7 ms / -11.6% (better) 5.140 ms +804.3 us / +18.5% (worse)
macOS println 114944 B 0 B / +0.0% 35377 B 0 B / +0.0% 461.470 ms +40.61 ms / +9.6% (worse) 3.534 ms -330.8 us / -8.6% (better)
macOS println-lto 118736 B 0 B / +0.0% 33029 B 0 B / +0.0% 619.513 ms +33.25 ms / +5.7% (worse) 6.059 ms +2.548 ms / +72.6% (worse)
Windows MinGW cprintf 20480 B 0 B / +0.0% 4662 B 0 B / +0.0% 808.372 ms -21.8 ms / -2.6% (better) 3.391 ms -358.6 us / -9.6% (better)
Windows MinGW cprintf-lto 18432 B 0 B / +0.0% 4582 B 0 B / +0.0% 856.115 ms +3.385 ms / +0.4% (worse) 3.464 ms +106 us / +3.2% (worse)
Windows MinGW fmtprintf 1932800 B 0 B / +0.0% 597574 B 0 B / +0.0% 3.389 s -59.7 ms / -1.7% (better) 7.822 ms -23.8 us / -0.3% (better)
Windows MinGW fmtprintf-lto 1982464 B 0 B / +0.0% 589622 B 0 B / +0.0% 9.328 s +59.45 ms / +0.6% (worse) 7.718 ms -22.2 us / -0.3% (better)
Windows MinGW println 74240 B 0 B / +0.0% 25014 B 0 B / +0.0% 810.191 ms -1.01 ms / -0.1% (better) 6.497 ms -313.2 us / -4.6% (better)
Windows MinGW println-lto 67584 B 0 B / +0.0% 21830 B 0 B / +0.0% 1.026 s -1.903 ms / -0.2% (better) 6.992 ms +474.3 us / +7.3% (worse)
Windows MinGW 386 cprintf 37888 B 0 B / +0.0% 5228 B 0 B / +0.0% 977.865 ms +30.62 ms / +3.2% (worse) 5.051 ms +134.4 us / +2.7% (worse)
Windows MinGW 386 cprintf-lto 21504 B 0 B / +0.0% 5028 B 0 B / +0.0% 962.736 ms +21.19 ms / +2.3% (worse) 5.014 ms -89.7 us / -1.8% (better)
Windows MinGW 386 fmtprintf 1947136 B 0 B / +0.0% 472062 B 0 B / +0.0% 3.582 s -40.3 ms / -1.1% (better) 11.644 ms +633.8 us / +5.8% (worse)
Windows MinGW 386 fmtprintf-lto 2188288 B 0 B / +0.0% 472002 B 0 B / +0.0% 10.738 s +439.6 ms / +4.3% (worse) 10.423 ms -145.9 us / -1.4% (better)
Windows MinGW 386 println 88064 B 0 B / +0.0% 20726 B 0 B / +0.0% 883.471 ms -9.377 ms / -1.1% (better) 8.540 ms -149.4 us / -1.7% (better)
Windows MinGW 386 println-lto 72192 B 0 B / +0.0% 18790 B 0 B / +0.0% 1.157 s +2.61 ms / +0.2% (worse) 9.553 ms +708.9 us / +8.0% (worse)
Windows MinGW ARM64 cprintf 19968 B 0 B / +0.0% 4632 B 0 B / +0.0% 947.116 ms -93.27 ms / -9.0% (better) 6.454 ms -804.3 us / -11.1% (better)
Windows MinGW ARM64 cprintf-lto 18432 B 0 B / +0.0% 4552 B 0 B / +0.0% 985.932 ms -28.29 ms / -2.8% (better) 6.107 ms -19.7 us / -0.3% (better)
Windows MinGW ARM64 fmtprintf 1820160 B 0 B / +0.0% 510596 B 0 B / +0.0% 3.391 s -29.4 us / -0.0008669% (better) 12.758 ms -104.6 us / -0.8% (better)
Windows MinGW ARM64 fmtprintf-lto 1886720 B 0 B / +0.0% 506320 B 0 B / +0.0% 8.618 s -78.86 ms / -0.9% (better) 12.728 ms -52 us / -0.4% (better)
Windows MinGW ARM64 println 71680 B 0 B / +0.0% 23832 B 0 B / +0.0% 943.133 ms -17.14 ms / -1.8% (better) 10.383 ms -732.2 us / -6.6% (better)
Windows MinGW ARM64 println-lto 67072 B 0 B / +0.0% 21068 B 0 B / +0.0% 1.154 s -19.39 ms / -1.7% (better) 10.713 ms -706.9 us / -6.2% (better)
Windows MSVC cprintf 12288 B 0 B / +0.0% 4438 B 0 B / +0.0% 743.224 ms -56.18 ms / -7.0% (better) 3.931 ms -33.1 us / -0.8% (better)
Windows MSVC cprintf-lto 11776 B 0 B / +0.0% 4278 B 0 B / +0.0% 786.730 ms -29.45 ms / -3.6% (better) 3.745 ms -298.7 us / -7.4% (better)
Windows MSVC fmtprintf 1471488 B 0 B / +0.0% 597142 B 0 B / +0.0% 3.405 s -1.376 ms / -0.0404% (better) 8.861 ms +96.3 us / +1.1% (worse)
Windows MSVC fmtprintf-lto 1517056 B 0 B / +0.0% 596502 B 0 B / +0.0% 10.411 s -353.6 ms / -3.3% (better) 10.176 ms +307.5 us / +3.1% (worse)
Windows MSVC println 47104 B 0 B / +0.0% 25030 B 0 B / +0.0% 747.248 ms -47.14 ms / -5.9% (better) 7.290 ms -161.4 us / -2.2% (better)
Windows MSVC println-lto 44032 B 0 B / +0.0% 22198 B 0 B / +0.0% 1.126 s +89.78 ms / +8.7% (worse) 8.331 ms +1.567 ms / +23.2% (worse)
Windows MSVC 386 cprintf 9728 B 0 B / +0.0% 3930 B 0 B / +0.0% 823.979 ms +15.93 ms / +2.0% (worse) 5.434 ms -302.5 us / -5.3% (better)
Windows MSVC 386 cprintf-lto 9216 B 0 B / +0.0% 3840 B 0 B / +0.0% 921.883 ms -31.79 ms / -3.3% (better) 5.445 ms -3.487 ms / -39.0% (better)
Windows MSVC 386 fmtprintf 1189888 B 0 B / +0.0% 456032 B 0 B / +0.0% 3.416 s -168.9 ms / -4.7% (better) 12.445 ms -996.5 us / -7.4% (better)
Windows MSVC 386 fmtprintf-lto 1252352 B 0 B / +0.0% 452437 B 0 B / +0.0% 9.941 s -148.3 ms / -1.5% (better) 10.996 ms -1.359 ms / -11.0% (better)
Windows MSVC 386 println 35328 B 0 B / +0.0% 19712 B 0 B / +0.0% 790.217 ms -40.53 ms / -4.9% (better) 9.054 ms -1.131 ms / -11.1% (better)
Windows MSVC 386 println-lto 34304 B 0 B / +0.0% 17927 B 0 B / +0.0% 1.050 s +5.479 ms / +0.5% (worse) 9.425 ms -88 us / -0.9% (better)
Windows MSVC ARM64 cprintf 11264 B 0 B / +0.0% 3976 B 0 B / +0.0% 1.767 s -27.71 ms / -1.5% (better) 7.459 ms -435.1 us / -5.5% (better)
Windows MSVC ARM64 cprintf-lto 10752 B 0 B / +0.0% 3844 B 0 B / +0.0% 1.795 s -21.64 ms / -1.2% (better) 7.788 ms +166.1 us / +2.2% (worse)
Windows MSVC ARM64 fmtprintf 1365504 B 0 B / +0.0% 510268 B 0 B / +0.0% 5.836 s -55.02 ms / -0.9% (better) 15.597 ms +238.1 us / +1.6% (worse)
Windows MSVC ARM64 fmtprintf-lto 1413120 B 0 B / +0.0% 507148 B 0 B / +0.0% 18.044 s +44.64 ms / +0.2% (worse) 16.126 ms +7.5 us / +0.04653% (worse)
Windows MSVC ARM64 println 43008 B 0 B / +0.0% 22824 B 0 B / +0.0% 1.773 s +25.71 ms / +1.5% (worse) 13.509 ms -163.8 us / -1.2% (better)
Windows MSVC ARM64 println-lto 40960 B 0 B / +0.0% 20732 B 0 B / +0.0% 2.207 s -8.121 ms / -0.4% (better) 13.634 ms -1.079 ms / -7.3% (better)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 12.560 ns/op -0.03 ns/op / -0.2% (better)
Linux BenchmarkMergeCompilerFlags 135.600 ns/op +0.3 ns/op / +0.2% (worse)
Linux BenchmarkMergeLinkerFlags 90.650 ns/op -0.11 ns/op / -0.1% (better)
Linux BenchmarkChannelBuffered 37.080 ns/op -2.25 ns/op / -5.7% (better)
Linux BenchmarkChannelHandoff 25519 ns/op +138 ns/op / +0.5% (worse)
Linux BenchmarkDefer 50.790 ns/op -0.31 ns/op / -0.6% (better)
Linux BenchmarkDirectCall 1.758 ns/op 0 ns/op / +0.0%
Linux BenchmarkGlobalRead 1.758 ns/op -0.003 ns/op / -0.2% (better)
Linux BenchmarkGlobalWrite 2.808 ns/op -0.002 ns/op / -0.1% (better)
Linux BenchmarkGoroutine 30255 ns/op -503 ns/op / -1.6% (better)
Linux BenchmarkInterfaceCall 8.270 ns/op +0.1 ns/op / +1.2% (worse)
Linux BenchmarkRuntimeGetG 2.112 ns/op +0.001 ns/op / +0.04737% (worse)
macOS BenchmarkLookupPCRandom 16.040 ns/op -0.35 ns/op / -2.1% (better)
macOS BenchmarkMergeCompilerFlags 135.300 ns/op +2.7 ns/op / +2.0% (worse)
macOS BenchmarkMergeLinkerFlags 86.430 ns/op +2.59 ns/op / +3.1% (worse)
macOS BenchmarkChannelBuffered 38.750 ns/op +8.02 ns/op / +26.1% (worse)
macOS BenchmarkChannelHandoff 13640 ns/op +3378 ns/op / +32.9% (worse)
macOS BenchmarkDefer 46.980 ns/op +2.34 ns/op / +5.2% (worse)
macOS BenchmarkDirectCall 1.212 ns/op -0.015 ns/op / -1.2% (better)
macOS BenchmarkGlobalRead 1.244 ns/op +0.069 ns/op / +5.9% (worse)
macOS BenchmarkGlobalWrite 1.568 ns/op +0.187 ns/op / +13.5% (worse)
macOS BenchmarkGoroutine 45095 ns/op +2848 ns/op / +6.7% (worse)
macOS BenchmarkInterfaceCall 5.767 ns/op +0.035 ns/op / +0.6% (worse)
macOS BenchmarkRuntimeGetG 2.746 ns/op +0.086 ns/op / +3.2% (worse)
Windows MinGW BenchmarkLookupPCRandom 13.260 ns/op +0.16 ns/op / +1.2% (worse)
Windows MinGW BenchmarkMergeCompilerFlags 602.200 ns/op -6.5 ns/op / -1.1% (better)
Windows MinGW BenchmarkMergeLinkerFlags 531.100 ns/op -17.6 ns/op / -3.2% (better)
Windows MinGW BenchmarkChannelBuffered 34.450 ns/op -0.97 ns/op / -2.7% (better)
Windows MinGW BenchmarkChannelHandoff 841.100 ns/op -42.1 ns/op / -4.8% (better)
Windows MinGW BenchmarkDefer 56.410 ns/op -0.03 ns/op / -0.1% (better)
Windows MinGW BenchmarkDirectCall 1.857 ns/op -0.001 ns/op / -0.1% (better)
Windows MinGW BenchmarkGlobalRead 1.547 ns/op +0.001 ns/op / +0.1% (worse)
Windows MinGW BenchmarkGlobalWrite 2.467 ns/op -0.005 ns/op / -0.2% (better)
Windows MinGW BenchmarkGoroutine 78442 ns/op -1794 ns/op / -2.2% (better)
Windows MinGW BenchmarkInterfaceCall 9.307 ns/op +0.011 ns/op / +0.1% (worse)
Windows MinGW BenchmarkRuntimeGetG 2.476 ns/op -0.001 ns/op / -0.04037% (better)
Windows MinGW 386 BenchmarkLookupPCRandom 26.690 ns/op +0.09 ns/op / +0.3% (worse)
Windows MinGW 386 BenchmarkMergeCompilerFlags 701.600 ns/op -43 ns/op / -5.8% (better)
Windows MinGW 386 BenchmarkMergeLinkerFlags 677.200 ns/op -21.4 ns/op / -3.1% (better)
Windows MinGW 386 BenchmarkChannelBuffered 43.720 ns/op +0.3 ns/op / +0.7% (worse)
Windows MinGW 386 BenchmarkChannelHandoff 906.300 ns/op -39.4 ns/op / -4.2% (better)
Windows MinGW 386 BenchmarkDefer 45.900 ns/op +2.69 ns/op / +6.2% (worse)
Windows MinGW 386 BenchmarkDirectCall 1.547 ns/op -0.003 ns/op / -0.2% (better)
Windows MinGW 386 BenchmarkGlobalRead 1.549 ns/op -0.002 ns/op / -0.1% (better)
Windows MinGW 386 BenchmarkGlobalWrite 7.777 ns/op -0.017 ns/op / -0.2% (better)
Windows MinGW 386 BenchmarkGoroutine 84516 ns/op -1953 ns/op / -2.3% (better)
Windows MinGW 386 BenchmarkInterfaceCall 9.780 ns/op +0.02 ns/op / +0.2% (worse)
Windows MinGW 386 BenchmarkRuntimeGetG 2.168 ns/op +0.001 ns/op / +0.04615% (worse)
Windows MinGW ARM64 BenchmarkLookupPCRandom 12.070 ns/op -0.03 ns/op / -0.2% (better)
Windows MinGW ARM64 BenchmarkMergeCompilerFlags 586.500 ns/op +0.7 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkMergeLinkerFlags 544.200 ns/op -8.8 ns/op / -1.6% (better)
Windows MinGW ARM64 BenchmarkChannelBuffered 43.760 ns/op +0.03 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkChannelHandoff 2401 ns/op -14 ns/op / -0.6% (better)
Windows MinGW ARM64 BenchmarkDefer 53.680 ns/op -0.13 ns/op / -0.2% (better)
Windows MinGW ARM64 BenchmarkDirectCall 0.589 ns/op -0.002 ns/op / -0.3% (better)
Windows MinGW ARM64 BenchmarkGlobalRead 0.737 ns/op 0 ns/op / +0.0%
Windows MinGW ARM64 BenchmarkGlobalWrite 0.664 ns/op -0.0007 ns/op / -0.1% (better)
Windows MinGW ARM64 BenchmarkGoroutine 61822 ns/op +1298 ns/op / +2.1% (worse)
Windows MinGW ARM64 BenchmarkInterfaceCall 4.741 ns/op -0.001 ns/op / -0.02109% (better)
Windows MinGW ARM64 BenchmarkRuntimeGetG 1.802 ns/op +0.032 ns/op / +1.8% (worse)
Windows MSVC BenchmarkLookupPCRandom 13.230 ns/op +0.27 ns/op / +2.1% (worse)
Windows MSVC BenchmarkMergeCompilerFlags 630.100 ns/op +18.6 ns/op / +3.0% (worse)
Windows MSVC BenchmarkMergeLinkerFlags 531.900 ns/op +4.7 ns/op / +0.9% (worse)
Windows MSVC BenchmarkChannelBuffered 34.890 ns/op +0.02 ns/op / +0.1% (worse)
Windows MSVC BenchmarkChannelHandoff 1061 ns/op -4 ns/op / -0.4% (better)
Windows MSVC BenchmarkDefer 56.780 ns/op +0.59 ns/op / +1.1% (worse)
Windows MSVC BenchmarkDirectCall 1.860 ns/op -0.002 ns/op / -0.1% (better)
Windows MSVC BenchmarkGlobalRead 1.554 ns/op +0.006 ns/op / +0.4% (worse)
Windows MSVC BenchmarkGlobalWrite 2.471 ns/op -0.001 ns/op / -0.04045% (better)
Windows MSVC BenchmarkGoroutine 81563 ns/op +2649 ns/op / +3.4% (worse)
Windows MSVC BenchmarkInterfaceCall 9.316 ns/op -0.004 ns/op / -0.04292% (better)
Windows MSVC BenchmarkRuntimeGetG 2.482 ns/op 0 ns/op / +0.0%
Windows MSVC 386 BenchmarkLookupPCRandom 27.860 ns/op -0.04 ns/op / -0.1% (better)
Windows MSVC 386 BenchmarkMergeCompilerFlags 755.200 ns/op -52.4 ns/op / -6.5% (better)
Windows MSVC 386 BenchmarkMergeLinkerFlags 739.600 ns/op +7.4 ns/op / +1.0% (worse)
Windows MSVC 386 BenchmarkChannelBuffered 47.380 ns/op +0.02 ns/op / +0.04223% (worse)
Windows MSVC 386 BenchmarkChannelHandoff 743.700 ns/op -12.5 ns/op / -1.7% (better)
Windows MSVC 386 BenchmarkDefer 48.420 ns/op -2.83 ns/op / -5.5% (better)
Windows MSVC 386 BenchmarkDirectCall 1.747 ns/op +0.001 ns/op / +0.1% (worse)
Windows MSVC 386 BenchmarkGlobalRead 1.760 ns/op +0.013 ns/op / +0.7% (worse)
Windows MSVC 386 BenchmarkGlobalWrite 8.981 ns/op -0.005 ns/op / -0.1% (better)
Windows MSVC 386 BenchmarkGoroutine 72833 ns/op -3086 ns/op / -4.1% (better)
Windows MSVC 386 BenchmarkInterfaceCall 11.190 ns/op 0 ns/op / +0.0%
Windows MSVC 386 BenchmarkRuntimeGetG 2.101 ns/op +0.001 ns/op / +0.04762% (worse)
Windows MSVC ARM64 BenchmarkLookupPCRandom 12.090 ns/op +0.03 ns/op / +0.2% (worse)
Windows MSVC ARM64 BenchmarkMergeCompilerFlags 575.200 ns/op -10.5 ns/op / -1.8% (better)
Windows MSVC ARM64 BenchmarkMergeLinkerFlags 536.900 ns/op -13.4 ns/op / -2.4% (better)
Windows MSVC ARM64 BenchmarkChannelBuffered 42.920 ns/op -0.55 ns/op / -1.3% (better)
Windows MSVC ARM64 BenchmarkChannelHandoff 2700 ns/op -34 ns/op / -1.2% (better)
Windows MSVC ARM64 BenchmarkDefer 66.260 ns/op -0.63 ns/op / -0.9% (better)
Windows MSVC ARM64 BenchmarkDirectCall 0.663 ns/op +0.0001 ns/op / +0.01508% (worse)
Windows MSVC ARM64 BenchmarkGlobalRead 0.738 ns/op +0.0007 ns/op / +0.1% (worse)
Windows MSVC ARM64 BenchmarkGlobalWrite 3.796 ns/op +0.002 ns/op / +0.1% (worse)
Windows MSVC ARM64 BenchmarkGoroutine 57313 ns/op +149 ns/op / +0.3% (worse)
Windows MSVC ARM64 BenchmarkInterfaceCall 4.718 ns/op -0.017 ns/op / -0.4% (better)
Windows MSVC ARM64 BenchmarkRuntimeGetG 1.806 ns/op +0.036 ns/op / +2.0% (worse)

Timer runtime benchmarks

Platform Operation and runtime ns/op vs base
Linux AfterFuncZeroDelivery/Go 546.800 ns/op -2 ns/op / -0.4% (better)
Linux AfterFuncZeroDelivery/LLGo 46490 ns/op -1918 ns/op / -4.0% (better)
Linux CreateStop/Go 155.700 ns/op -1.8 ns/op / -1.1% (better)
Linux CreateStop/LLGo 1029 ns/op -493 ns/op / -32.4% (better)
Linux RearmStopped/Go 56.140 ns/op -0.26 ns/op / -0.5% (better)
Linux RearmStopped/LLGo 1338 ns/op -69 ns/op / -4.9% (better)
Linux ResetActive/Go 43.520 ns/op -0.19 ns/op / -0.4% (better)
Linux ResetActive/LLGo 711.600 ns/op -0.9 ns/op / -0.1% (better)
Linux ResetHeap1024/Go 43.670 ns/op -0.06 ns/op / -0.1% (better)
Linux ResetHeap1024/LLGo 162.900 ns/op -2.6 ns/op / -1.6% (better)
macOS AfterFuncZeroDelivery/Go 547.900 ns/op -29.4 ns/op / -5.1% (better)
macOS AfterFuncZeroDelivery/LLGo 84159 ns/op -2476 ns/op / -2.9% (better)
macOS CreateStop/Go 174.200 ns/op -3.2 ns/op / -1.8% (better)
macOS CreateStop/LLGo 522.500 ns/op -174.8 ns/op / -25.1% (better)
macOS RearmStopped/Go 70.320 ns/op +0.93 ns/op / +1.3% (worse)
macOS RearmStopped/LLGo 476.300 ns/op +16.1 ns/op / +3.5% (worse)
macOS ResetActive/Go 51.370 ns/op +1.19 ns/op / +2.4% (worse)
macOS ResetActive/LLGo 245.500 ns/op +61.8 ns/op / +33.6% (worse)
macOS ResetHeap1024/Go 51.250 ns/op -0.63 ns/op / -1.2% (better)
macOS ResetHeap1024/LLGo 95.250 ns/op -23.75 ns/op / -20.0% (better)
Windows MinGW AfterFuncZeroDelivery/Go 544.500 ns/op -0.3 ns/op / -0.1% (better)
Windows MinGW AfterFuncZeroDelivery/LLGo 153289 ns/op +4045 ns/op / +2.7% (worse)
Windows MinGW CreateStop/Go 115.400 ns/op +2.1 ns/op / +1.9% (worse)
Windows MinGW CreateStop/LLGo 451.800 ns/op +2.4 ns/op / +0.5% (worse)
Windows MinGW RearmStopped/Go 31.190 ns/op -0.03 ns/op / -0.1% (better)
Windows MinGW RearmStopped/LLGo 301.400 ns/op +5.2 ns/op / +1.8% (worse)
Windows MinGW ResetActive/Go 20.060 ns/op 0 ns/op / +0.0%
Windows MinGW ResetActive/LLGo 163.800 ns/op +7.8 ns/op / +5.0% (worse)
Windows MinGW ResetHeap1024/Go 20.410 ns/op -0.15 ns/op / -0.7% (better)
Windows MinGW ResetHeap1024/LLGo 144.700 ns/op +2.2 ns/op / +1.5% (worse)
Windows MinGW 386 AfterFuncZeroDelivery/Go 938.700 ns/op -1.6 ns/op / -0.2% (better)
Windows MinGW 386 AfterFuncZeroDelivery/LLGo 195315 ns/op -2269 ns/op / -1.1% (better)
Windows MinGW 386 CreateStop/Go 193 ns/op +2.3 ns/op / +1.2% (worse)
Windows MinGW 386 CreateStop/LLGo 1863 ns/op -4 ns/op / -0.2% (better)
Windows MinGW 386 RearmStopped/Go 63.560 ns/op +0.21 ns/op / +0.3% (worse)
Windows MinGW 386 RearmStopped/LLGo 382.400 ns/op +8.6 ns/op / +2.3% (worse)
Windows MinGW 386 ResetActive/Go 39.080 ns/op -0.13 ns/op / -0.3% (better)
Windows MinGW 386 ResetActive/LLGo 938.500 ns/op -19.7 ns/op / -2.1% (better)
Windows MinGW 386 ResetHeap1024/Go 39.580 ns/op +0.03 ns/op / +0.1% (worse)
Windows MinGW 386 ResetHeap1024/LLGo 195.700 ns/op -1 ns/op / -0.5% (better)
Windows MinGW ARM64 AfterFuncZeroDelivery/Go 669.100 ns/op -5.2 ns/op / -0.8% (better)
Windows MinGW ARM64 AfterFuncZeroDelivery/LLGo 137197 ns/op -1389 ns/op / -1.0% (better)
Windows MinGW ARM64 CreateStop/Go 211.500 ns/op +10 ns/op / +5.0% (worse)
Windows MinGW ARM64 CreateStop/LLGo 397.800 ns/op -12.2 ns/op / -3.0% (better)
Windows MinGW ARM64 RearmStopped/Go 70.600 ns/op -0.01 ns/op / -0.01416% (better)
Windows MinGW ARM64 RearmStopped/LLGo 294.900 ns/op +1.5 ns/op / +0.5% (worse)
Windows MinGW ARM64 ResetActive/Go 31.020 ns/op -0.02 ns/op / -0.1% (better)
Windows MinGW ARM64 ResetActive/LLGo 124.100 ns/op -9.3 ns/op / -7.0% (better)
Windows MinGW ARM64 ResetHeap1024/Go 31.130 ns/op +0.08 ns/op / +0.3% (worse)
Windows MinGW ARM64 ResetHeap1024/LLGo 142.200 ns/op -1.2 ns/op / -0.8% (better)
Windows MSVC AfterFuncZeroDelivery/Go 558.400 ns/op -4.7 ns/op / -0.8% (better)
Windows MSVC AfterFuncZeroDelivery/LLGo 163420 ns/op +1628 ns/op / +1.0% (worse)
Windows MSVC CreateStop/Go 115.600 ns/op -0.5 ns/op / -0.4% (better)
Windows MSVC CreateStop/LLGo 471.400 ns/op -8.2 ns/op / -1.7% (better)
Windows MSVC RearmStopped/Go 31.700 ns/op +0.29 ns/op / +0.9% (worse)
Windows MSVC RearmStopped/LLGo 316.200 ns/op +6.1 ns/op / +2.0% (worse)
Windows MSVC ResetActive/Go 20.010 ns/op -0.09 ns/op / -0.4% (better)
Windows MSVC ResetActive/LLGo 182.400 ns/op -7 ns/op / -3.7% (better)
Windows MSVC ResetHeap1024/Go 20.430 ns/op +0.01 ns/op / +0.04897% (worse)
Windows MSVC ResetHeap1024/LLGo 142.900 ns/op +2.1 ns/op / +1.5% (worse)
Windows MSVC 386 AfterFuncZeroDelivery/Go 985.300 ns/op -15.7 ns/op / -1.6% (better)
Windows MSVC 386 AfterFuncZeroDelivery/LLGo 157025 ns/op +254 ns/op / +0.2% (worse)
Windows MSVC 386 CreateStop/Go 215.500 ns/op -2 ns/op / -0.9% (better)
Windows MSVC 386 CreateStop/LLGo 1986 ns/op -70 ns/op / -3.4% (better)
Windows MSVC 386 RearmStopped/Go 72.810 ns/op +0.17 ns/op / +0.2% (worse)
Windows MSVC 386 RearmStopped/LLGo 347.400 ns/op +0.2 ns/op / +0.1% (worse)
Windows MSVC 386 ResetActive/Go 42.020 ns/op +0.06 ns/op / +0.1% (worse)
Windows MSVC 386 ResetActive/LLGo 1014 ns/op +1 ns/op / +0.1% (worse)
Windows MSVC 386 ResetHeap1024/Go 42.220 ns/op +0.07 ns/op / +0.2% (worse)
Windows MSVC 386 ResetHeap1024/LLGo 193.900 ns/op -0.6 ns/op / -0.3% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/Go 668.200 ns/op -1.8 ns/op / -0.3% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/LLGo 145790 ns/op +5846 ns/op / +4.2% (worse)
Windows MSVC ARM64 CreateStop/Go 214.400 ns/op +12.2 ns/op / +6.0% (worse)
Windows MSVC ARM64 CreateStop/LLGo 446.400 ns/op -8.9 ns/op / -2.0% (better)
Windows MSVC ARM64 RearmStopped/Go 70.530 ns/op -0.18 ns/op / -0.3% (better)
Windows MSVC ARM64 RearmStopped/LLGo 312.100 ns/op +2.1 ns/op / +0.7% (worse)
Windows MSVC ARM64 ResetActive/Go 31.060 ns/op +0.06 ns/op / +0.2% (worse)
Windows MSVC ARM64 ResetActive/LLGo 137.700 ns/op -1 ns/op / -0.7% (better)
Windows MSVC ARM64 ResetHeap1024/Go 31.120 ns/op -0.02 ns/op / -0.1% (better)
Windows MSVC ARM64 ResetHeap1024/LLGo 149.200 ns/op +1.4 ns/op / +0.9% (worse)

Compared with ba6b6af4c4dd measured in the same runner job.

@xushiwei
xushiwei merged commit be3fa9d into xgo-dev:main Sep 2, 2026
96 of 98 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasm WebAssembly, wasm32, and WASI support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants