SpiderMonkey Newsletter (Firefox 92-93)

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 92 and 93 Nightly release cycles.

👷🏽‍♀️ JS features

⚡ WebAssembly

  • We’ve done some work towards Memory64 support.
  • The final JS API for Wasm exceptions has been implemented.
  • We added support for WebAssembly.Function from the js-types proposal.
  • We changed unaligned floating point accesses on 32-bit ARM to not use signal handlers.
  • Wasm code is now much faster and uses less memory when the debugger is used.
  • memory.fill and memory.copy are now optimized with SIMD instructions.
  • We now print better error messages to the console for asm.js

❇️ 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.

  • We’ve rewritten our implementation of self-hosted code (builtins implemented in JS) to be based on the stencil format instead of cloning from a special zone. This has resulted in significant memory and performance improvements.
  • We’re making changes to function delazification to later allow doing this off-thread.
  • We hardened XDR decoding more against memory/disk corruption.

🌍 Unified Intl implementation

Work is underway to unify the Intl (Internalization) code in SpiderMonkey and the rest of Gecko as a shared mozilla::intl component. This results in less code duplication and will make it easier to migrate from the ICU library to ICU4X in the future.

The past weeks Intl.Collator and Intl.RelativeTimeFormat have been ported to the new mozilla::intl code.

🗂 ReShape

ReShape is a project to optimize and simplify our object layout and property representation after removing TI. This will help us fix some long-standing issues related to performance, memory usage and code complexity.

  • We converted uses of object private slots to reserved slots and then removed private slots completely. This allowed us to optimize reserved slots.
  • We changed function objects to use reserved slots instead of a custom C++ layout.
  • We saved some memory by storing only the shape instead of an object for object literals.
  • We changed the shape teleporting optimization to avoid a performance cliff and to be simpler.
  • We changed global objects to use a C++ class instead of hundreds of reserved slots.
  • We optimized object allocation, especially for plain objects, array objects and functions because these are so common.

🧹 Garbage Collection

  • We now avoid marking and sweeping arenas for permanent atoms.
  • We simplified the GC threshold code. This resulted in a number of performance improvement alerts.
  • We simplified the GC allocation code for strings.
  • We made some changes to the way slice budgets are calculated to reduce jank caused by long GC pauses.
  • We fixed an issue with JIT code discarding heuristics that caused frequent OOMs in automation on 32-bit platforms.

📚 Miscellaneous

  • We tidied up our meta bugs in Bugzilla. We now have a tree of meta bugs.
  • We optimized Map and Set operations in the JITs.
  • We fixed a number of correctness issues with super, class return values, private methods and date parsing.
  • We now auto-generate more LIR boilerplate code.
  • A new contributor, sanketh, added an option to use fdlibm for more Math functions to get consistent results across platforms and to avoid fingerprinting.
  • We removed a lot of unnecessary includes.