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 86 and 87 Nightly release cycles.

If you like these newsletters, you may also enjoy Yulia’s Compiler Compiler live stream.

🏆 New contributors

  • Jonatan fixed a subtle bug in how our error messages got printed around private fields.

👷🏽‍♀️ JS features

  • Yulia attended the TC39 meeting in January and took notes.
  • André implemented support for the ‘Arbitrary module namespace identifier names’ spec change.
  • Jan added support for large ArrayBuffers to structured cloning, JITs, typed arrays and the JSAPI. This is now available behind a pref in Nightly and will let us support WebAssembly memories larger than 2 GB on 64-bit platforms.
  • André changed typed array elements to appear configurable, following a recent spec change.
  • Jason optimized the bytecode generated for private fields.
  • André updated timezone information twice.
  • Yulia updated the Top Level Await implementation to fix a spec bug.
  • Yulia reviewed an incoming potential change to the TLA specification.
  • André enabled the Intl.DisplayNames constructor by default.

⚡ WebAssembly

  • Lars and Yury made many changes for SIMD support.
  • Ioanna and Asumu from Igalia implemented support for the exception handling proposal in the Wasm Baseline compiler.
  • Lars fixed various issues to support the Ion backend for Wasm on ARM64.
  • Luke Wagner added telemetry for duplicate imports, to see if this could be disallowed in the future.
  • Tom improved error messages when trying to consume a Response for Wasm.
  • Ryan added support for optional parameters in the WebAssembly.Table API.
  • Ryan continues to work on implementing the draft wasm GC specification.

🧹 Garbage Collection

  • Jon improved arena unmarking to happen concurrently at the start of GC.
  • Jon changed nursery collections during major GCs to happen only when necessary.
  • Steve added counters for various string operations.
  • Steve used MADV_FREE_REUSE on macOS when using decommitted memory to improve the accuracy of memory usage data.
  • Jon changed idle collections to collect and shrink the nursery when it’s underused.
  • Jon moved chunk metadata from the end of the chunk to the start, so that it can be accessed more efficiently, and cleaned up the chunk code.
  • Jon optimized the tracing/marking code more to fix a telemetry regression.
  • Steve optimized nursery collections by not adding strings and BigInts without children to the fixup list. He also split collectToFixedPoint in separate object and string parts to improve GC statistics.

❇️ Stencil

Stencil is our project to create an explicit interface between the frontend (parser, bytecode emitter) and the rest of the VM, decoupling those components. This lets us improve web-browsing performance, simplify a lot of code and improve bytecode caching.

  • Nicolas made shell tests a lot faster by using cached bytecode for self-hosted code.
  • Arai landed a large number of changes to improve performance of the Stencil XDR (bytecode serialization) format.
  • Ted enabled stencil-mvp by default. This switched bytecode caching to use the new Stencil-based format and fixes performance-cliffs related to GC blocking off-thread parsing.
  • Matthew later removed the stencil-mvp pref to unblock more optimization work.
  • Ted optimized ScriptSource to XDR encoding and main-thread GC function allocations.
  • Arai optimized main-thread GC allocations for object literals.
  • Arai changed the frontend to use a snapshot of scope information.
  • Ted cleaned up code for missing class constructor by synthesizing these functions in the parser instead of cloning self-hosted functions.
  • Arai landed many performance and memory usage improvements for parser atoms.
  • Ted added a public API for Stencil data structures. This will be used in the browser to improve bytecode caching more.

🚀 JIT

  • Matthew implemented support for compiling async functions and generators with Warp. Enabling this by default showed a 4% win on Ares6.
  • Iain improved the bailout code and added a mechanism to catch bailout loops in debug builds. Bailout loops can result in performance cliffs, and this work caught various issues.
  • Nicolas enabled use of the JSCVT instruction on Apple ARM64 hardware.
  • Caroline added filtering for the JSON output used by the CacheIR health report tool, to get it down to reasonable size for complex websites.
  • André, Tom and Jan cleaned up and deleted even more code following the IonBuilder and TI removal in Firefox 85.
  • Iain added CacheIR and Warp optimizations for Math.min/max spread calls with arrays.
  • André added CacheIR and Warp optimizations for Object.prototype.toString, Atomics functions with BigInt64Array and BigUint64Array, and various TypedArray, DataView and RegExp getters.
  • Tom added a mechanism to inline certain self-hosted functions in Warp even if they’re normally too big to be considered for inlining.
  • André optimized BigInt operations in Warp by supporting them in the CacheIR-to-MIR transpiler.
  • Iain is making progress on replacing the heavyweight lazy-arguments optimization with a simpler implementation based on scalar replacement in the JIT backend.

📚 Miscellaneous

Documentation

Old bugs

  • Jan changed Number.prototype.{toFixed, toExponential, toPrecision} to use the double-conversion code in MFBT instead of dtoa. This fixes a toExponential rounding issue and is also faster in most cases.
  • Calixte Denizet fixed a date parsing bug for GMT values starting with ‘00’.
  • arai fixed an old bug where function stringification could include too much source code.

Modern C++

  • Chris Peterson replaced MOZ_MUST_USE with the C++17 [[nodiscard]] attribute.
  • André replaced calls to various array-related functions in MFBT with STL equivalents.

Other

  • Jason fixed debugger regressions from generator optimizations.
  • Jan moved the TypeDescr for typed objects from the ObjectGroup to typed objects to prepare for upcoming object layout changes.
  • Julian improved the IONFLAGS logging output.
  • Jan renamed the confusingly-named IfEq and IfNe bytecode instructions to JumpIfFalse and JumpIfTrue.
  • Jon added a flag to make it easier to run shell tests with a non-standard ‘GC zeal’.