From 84f4fc28c291d018ddc630b9e99aa09b08dd0c3e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 14:40:59 +0000 Subject: [PATCH] Build the wasm module with -DNDEBUG `rake wasm:build` compiled the parser without `NDEBUG`, so every `RBS_ASSERT` survived into `rbs_parser.wasm`. The MRI extension already drops them (ext/rbs_extension/extconf.rb), and the assertions that matter sit on the hottest paths there are: two per character in `rbs_encoding.c`, one per character in `rbs_skip`, and five around the constant pool. Each one is an out-of-line varargs call to `rbs_assert_impl`, which the compiler cannot inline away, so the cost is paid on every character lexed. Parsing core/ + stdlib/ (250 files, 4.3MB) through a WASI host, best of 10: assert build 75.7 ms NDEBUG build 61.9 ms (-18%) Measured the same on wasmtime and on V8. The serialized ASTs for all 250 files are byte-identical between the two builds. `DEBUG=1 rake wasm:build` keeps the assertions, matching the DEBUG convention extconf.rb and the prepare_bench / prepare_profiling tasks already use. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012uu4EqN6azBeVjM9F71TUp --- Rakefile | 7 +++++++ wasm/README.md | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/Rakefile b/Rakefile index 98cfe8d389..387533ed23 100644 --- a/Rakefile +++ b/Rakefile @@ -926,6 +926,12 @@ namespace :wasm do desc "Build the RBS parser as a WebAssembly module (requires WASI_SDK_PATH)" task :build do + # `-DNDEBUG` compiles out `RBS_ASSERT`, the same way ext/rbs_extension does + # for the MRI extension. The assertions sit in the lexer and the constant + # pool, so keeping them costs about 20% of parse time; set `DEBUG=1` to keep + # them when debugging the module itself. + debug_flags = ENV["DEBUG"] ? [] : ["-DNDEBUG"] + mkdir_p WASM_DIR sh wasi_clang, "--target=wasm32-wasip1", @@ -933,6 +939,7 @@ namespace :wasm do "-mexec-model=reactor", "-std=gnu11", "-O2", + *debug_flags, "-Wno-unused-parameter", "-I#{File.join(__dir__, "include")}", "-o", WASM_OUTPUT, diff --git a/wasm/README.md b/wasm/README.md index c1993b19fd..174a56a850 100644 --- a/wasm/README.md +++ b/wasm/README.md @@ -27,6 +27,11 @@ $ rake wasm:install_jars # download the Chicory/ASM jars into ~/.m2 (run on JRub The compiled `rbs_parser.wasm` is a build artifact and is not checked in. +Like the MRI extension, the module is compiled with `-DNDEBUG`, which removes the +`RBS_ASSERT` checks — they sit in the lexer and the constant pool, so leaving them +in costs around 20% of parse time. `DEBUG=1 rake wasm:build` keeps them, which is +what you want when debugging the parser itself through the module. + The WASI SDK is needed for the *build*, not for running the result — the host clang already knows the `wasm32` target, but there is no wasm32 libc on a normal machine, so it picks up the host headers and fails on the first `#include`. That is what the SDK supplies, along with the