SpiderMonkey is the JavaScript engine used in Mozilla Firefox. This newsletter gives an overview of the JavaScript and WebAssembly work we’ve done as part of the Firefox 112 and 113 Nightly release cycles.
🛠️ Profiler instrumentation
We’re working with the performance team to improve profiler support for JIT code. This work allows us to see JS functions (and JIT optimization data) in profiles from tools such as samply. This makes it much easier for us to find and investigate performance issues in the engine.
- We fixed some JIT code trampolines to properly maintain frame pointers.
- We added better frame unwinding information for Windows so external profilers can iterate through JIT frames using frame pointers.
- We added Windows ETW events for mapping JIT code to method names.
- We added an optional mode for profiling that adds frame pointers to Baseline IC code.
- We added an optional mode for profiling that adds entry trampolines for scripts running in the interpreters. This makes it possible to distinguish between different scripts that are executing in the interpreter.
🚀 Performance
We’re working on improving performance for popular web frameworks such as React. We can’t list all of these improvements here, but the list below covers some of this work.
- We optimized global name lookups to use a generation counter instead of shape guards.
- We added an optimization to guess the size of objects allocated by constructor functions.
- We rewrote our implementation of
Function.prototype.bind
to be faster, simpler and use less memory. - We implemented monomorphic function inlining for cases where we can skip the trial inlining phase.
- We added inlining of megamorphic cache lookups to Baseline ICs in addition to Ion.
- We made our
ArraySpeciesLookup
cache more robust. - We made some improvements to the GC’s parallel marking implementation.
- We changed our self-hosted builtins to use specialized intrinsics instead of
arguments
, to eliminate unnecessary arguments object allocations in the interpreter and Baseline tiers.
⚡ Wasm GC
High-level programming languages currently need to bring their own GC if they want to run on WebAssembly. This can result in memory leaks because it cannot collect cycles that form with the browser. The Wasm GC proposal adds struct and array types to Wasm so these languages can use the browser’s GC instead.
- We profiled the dart-barista benchmark and fixed various performance issues.
- We optimized allocation and GC support for Wasm GC objects.
- We improved the memory layout of Wasm GC objects to be more efficient.
⚙️ Modernizing JS modules
We’re working on improving our implementation of modules. This includes supporting modules in Workers, adding support for Import Maps, and ESMification (replacing the JSM module system for Firefox internal JS code with standard ECMAScript modules).
- See the AreWeESMifiedYet website for the status of ESMification. As of this week, almost 70% of modules have been ESMified 🎉
- We’ve finished most of the work for worker modules. We’re hoping to ship this soon.
📚 Miscellaneous
- We added Stencil APIs for parsing code without using a
JSContext
. - We implemented the
memory.discard
instruction for WebAssembly. - We improved mitigations for fingerprinting based on time zones and math functions.
- We made some improvements to the static analysis for GC hazards.
- We implemented more parts of the decorator proposal.