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 withBigInt64Array
andBigUint64Array
, and variousTypedArray
,DataView
andRegExp
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
- Ted added a SpiderMonkey overview page to Firefox source docs.
- Jon added GC documentation.
- Iain added a high-level overview of MIR optimizations.
- Matthew improved the JIT frame layout comment.
Old bugs
- Jan changed
Number.prototype.{toFixed, toExponential, toPrecision}
to use the double-conversion code in MFBT instead of dtoa. This fixes atoExponential
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 theObjectGroup
to typed objects to prepare for upcoming object layout changes. - Julian improved the
IONFLAGS
logging output. - Jan renamed the confusingly-named
IfEq
andIfNe
bytecode instructions toJumpIfFalse
andJumpIfTrue
. - Jon added a flag to make it easier to run shell tests with a non-standard ‘GC zeal’.