Thchere

Boosting WebAssembly Performance with Speculative Optimizations and Inlining in V8

Published: 2026-05-18 12:06:24 | Category: Environment & Energy

In this article, we explore the latest advancements in V8, Google's JavaScript and WebAssembly engine, which shipped with Chrome M137. Specifically, we discuss two powerful optimizations: speculative call_indirect inlining and deoptimization support for WebAssembly. Together, they leverage runtime feedback to generate faster machine code, significantly accelerating WebAssembly execution—especially for WasmGC programs. For instance, Dart microbenchmarks show over 50% average speedup, while larger real-world applications see improvements between 1% and 8%. Deoptimization also lays the groundwork for future enhancements. Below, we answer key questions about these techniques.

What are speculative optimizations in V8?

Speculative optimizations are a technique used by JIT compilers to generate efficient machine code based on observed runtime behavior. For example, if a JavaScript expression a + b repeatedly uses integers, V8 may generate specialized code for integer addition rather than generic code that handles strings, floats, and other types. This assumption allows for much faster execution. If the program later violates the assumption (e.g., a becomes a string), V8 performs a deoptimization—discarding the optimized code and reverting to slower, unoptimized code while collecting new feedback. This balance between risk and reward is central to modern JIT compilation, and it has now been extended to WebAssembly in V8.

Boosting WebAssembly Performance with Speculative Optimizations and Inlining in V8
Source: v8.dev

Why did WebAssembly not need these optimizations before?

Traditionally, WebAssembly (Wasm) 1.0 programs are well-suited to ahead-of-time compilation because they contain explicit static types for functions, instructions, and variables. Languages like C, C++, and Rust compile to Wasm via toolchains like Emscripten (LLVM-based) or Binaryen, which already perform extensive static analysis and optimizations. As a result, the generated machine code is quite efficient without runtime feedback. Unlike JavaScript, which is highly dynamic, Wasm 1.0 leaves little room for speculative assumptions—hence deopts were unnecessary. However, the introduction of WasmGC has changed this landscape, as we'll see next.

How does WasmGC motivate speculative optimizations?

WasmGC is a WebAssembly proposal that brings garbage collection support, enabling languages like Java, Kotlin, and Dart to compile to WebAssembly. The resulting bytecode is more high-level than Wasm 1.0, featuring rich types such as structs and arrays, subtyping, and operations on these types. This extra abstraction reduces the amount of static information available to the compiler. Consequently, runtime feedback becomes valuable for generating optimized machine code. Speculative optimizations allows V8 to make educated guesses about type usage, function targets, and memory patterns, and then deoptimize if those guesses prove wrong. This is especially beneficial for operations like function calls and type checks.

What is speculative call_indirect inlining?

Speculative call_indirect inlining is an optimization where V8 tries to inline the target of an indirect function call (via the call_indirect instruction) based on runtime feedback. Instead of always using the indirect call mechanism, which involves a table lookup and type check, the compiler can directly embed the code of the most frequently called function. This avoids call overhead and enables further optimizations like constant propagation. If the program later calls a different function, a deoptimization occurs, reverting to the original indirect call. V8 uses feedback collected during execution to decide which target to inline. This technique is analogous to polymorphic inline caching in JavaScript and dramatically speeds up dynamic dispatch in WasmGC programs.

How do deoptimizations work in WebAssembly?

Deoptimization (deopt) is a mechanism that rolls back from optimized code to a less optimized state when runtime assumptions are violated. In V8's WebAssembly implementation, when speculative code (e.g., inlined function or assumed type) encounters a situation that contradicts the original assumption, the engine triggers a deopt. This involves reconstructing the state of the program (stack frames, locals, etc.) to continue execution in unoptimized baseline code. The process is similar to JavaScript deopts but adapted for Wasm's structured control flow. Importantly, deoptimization is not an error—it's a safety net that allows aggressive optimization without risking correctness. The performance gain from speculations far outweighs the occasional deopt cost, as seen in the benchmarks.

What performance improvements have been observed?

In internal testing with Dart microbenchmarks, the combination of speculative call_indirect inlining and deoptimization support yielded over 50% average speedup. For larger, realistic applications and standard benchmarks, the improvement ranged from 1% to 8%. These numbers highlight that while speculative optimizations bring the most benefit to compute-intensive, type-dispatch-heavy code (common in WasmGC), even general applications see measurable gains. The 50% jump in microbenchmarks underscores the potency of inlining dynamic calls. Moreover, deoptimization paves the way for future optimizations like more aggressive type specialization and even inlining across module boundaries.

What does the future hold for WebAssembly optimizations in V8?

The introduction of speculative optimizations and deopts for WebAssembly marks a significant step, but it's just the beginning. V8's team plans to leverage these building blocks for even more advanced techniques, such as adaptive tiering (where code is re-optimized based on runtime data), cross-module inlining, and type feedback-driven branch prediction. As WasmGC continues to mature and attract more languages, speculative optimizations will become increasingly critical. The ability to deopt safely allows V8 to take calculated risks, resulting in faster code without sacrificing correctness. Future releases will likely extend these mechanisms to cover more WebAssembly features, bringing JavaScript-level performance agility to the Wasm ecosystem.