{"slug": "warpmonkey", "title": "WarpMonkey", "summary": "Mozilla's SpiderMonkey is the JavaScript and WebAssembly engine for Firefox, implementing ECMAScript and WebAssembly specs. It features a garbage collector, JS::Value and JSObject types, and a parser that generates bytecode via Stencil, with lazy parsing to optimize performance.", "body_md": "# SpiderMonkey\n\n*SpiderMonkey* is the *JavaScript* and *WebAssembly* implementation library of\nthe *Mozilla Firefox* web browser. The implementation behaviour is defined by\nthe [ECMAScript](https://tc39.es/ecma262/) and [WebAssembly](https://webassembly.org/) specifications.\n\nMuch of the internal technical documentation of the engine can be found\nthroughout the source files themselves by looking for comments labelled with\n[[SMDOC]](https://searchfox.org/mozilla-central/search?q=[SMDOC]&path=js%2F). Information about the team, our processes, and about embedding\n*SpiderMonkey* in your own projects can be found at [https://spidermonkey.dev](https://spidermonkey.dev).\n\nSpecific documentation on a few topics is available at:\n\n## Components of SpiderMonkey\n\n### 🧹 Garbage Collector\n\n*JavaScript* is a garbage collected language and at the core of *SpiderMonkey*\nwe manage a garbage-collected memory heap. Elements of this heap have a base\nC++ type of [gc::Cell](https://searchfox.org/mozilla-central/search?q=[SMDOC]+GC+Cell). Each round of garbage collection will free up any\n*Cell* that is not referenced by a *root* or another live *Cell* in turn.\n\nSee [GC overview](gc.html) for more details.\n\n### 📦 JS::Value and JSObject\n\n*JavaScript* values are divided into either objects or primitives\n(*Undefined*, *Null*, *Boolean*, *Number*, *BigInt*, *String*, or *Symbol*).\nValues are represented with the [JS::Value](https://searchfox.org/mozilla-central/search?q=[SMDOC]+JS%3A%3AValue+type&path=js%2F) type which may in turn point to\nan object that extends from the [JSObject](https://searchfox.org/mozilla-central/search?q=[SMDOC]+JSObject+layout) type. Objects include both plain\n*JavaScript* objects and exotic objects representing various things from\nfunctions to *ArrayBuffers* to *HTML Elements* and more.\n\nMost objects extend `NativeObject`\n\n(which is a subtype of `JSObject`\n\n)\nwhich provides a way to store properties as key-value pairs similar to a hash\ntable. These objects hold their *values* and point to a *Shape* that\nrepresents the set of *keys*. Similar objects point to the same *Shape* which\nsaves memory and allows the JITs to quickly work with objects similar to ones\nit has seen before. See the [[SMDOC] Shapes](https://searchfox.org/mozilla-central/search?q=[SMDOC]+Shapes) comment for more details.\n\nC++ (and Rust) code may create and manipulate these objects using the\ncollection of interfaces we traditionally call the **JSAPI**.\n\n### 🗃️ JavaScript Parser\n\nIn order to evaluate script text, we parse it using the *Parser* into an\n[Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST) temporarily and then run the *BytecodeEmitter*\n(BCE) to generate [Bytecode](https://en.wikipedia.org/wiki/Bytecode) and associated metadata. We refer to this\nresulting format as [Stencil](https://searchfox.org/mozilla-central/search?q=[SMDOC]+Script+Stencil) and it has the helpful characteristic that it\ndoes not utilize the Garbage Collector. The *Stencil* can then be\ninstantiated into a series of GC *Cells* that can be mutated and understood\nby the execution engines described below.\n\nEach function as well as the top-level itself generates a distinct script.\nThis is the unit of execution granularity since functions may be set as\ncallbacks that the host runs at a later time. There are both\n`ScriptStencil`\n\nand `js::BaseScript`\n\nforms of scripts.\n\nBy default, the parser runs in a mode called *syntax* or *lazy* parsing where\nwe avoid generating full bytecode for functions within the source that we are\nparsing. This lazy parsing is still required to check for all *early errors*\nthat the specification describes. When such a lazily compiled inner function\nis first executed, we recompile just that function in a process called\n*delazification*. Lazy parsing avoids allocating the AST and bytecode which\nsaves both CPU time and memory. In practice, many functions are never\nexecuted during a given load of a webpage so this delayed parsing can be\nquite beneficial.\n\n### ⚙️ JavaScript Interpreter\n\nThe *bytecode* generated by the parser may be executed by an interpreter\nwritten in C++ that manipulates objects in the GC heap and invokes native\ncode of the host (eg. web browser). See [[SMDOC] Bytecode Definitions](https://searchfox.org/mozilla-central/search?q=[SMDOC]+Bytecode+Definitions&path=js%2F) for\ndescriptions of each bytecode opcode and `js/src/vm/Interpreter.cpp`\n\nfor\ntheir implementation.\n\n### ⚡ JavaScript JITs\n\nIn order to speed up execution of *bytecode*, we use a series of Just-In-Time\n(JIT) compilers to generate specialized machine code (eg. x86, ARM, etc)\ntailored to the *JavaScript* that is run and the data that is processed.\n\nAs an individual script runs more times (or has a loop that runs many times)\nwe describe it as getting *hotter* and at certain thresholds we *tier-up* by\nJIT-compiling it. Each subsequent JIT tier spends more time compiling but\naims for better execution performance.\n\n#### Baseline Interpreter\n\nThe *Baseline Interpreter* is a hybrid interpreter/JIT that interprets the\n*bytecode* one opcode at a time, but attaches small fragments of code called\n*Inline Caches* (ICs) that rapidly speed-up executing the same opcode the next\ntime (if the data is similar enough). See the [[SMDOC] JIT Inline Caches](https://searchfox.org/mozilla-central/search?q=[SMDOC]+JIT+Inline+Caches)\ncomment for more details.\n\n#### Baseline Compiler\n\nThe *Baseline Compiler* use the same *Inline Caches* mechanism from the\n*Baseline Interpreter* but additionally translates the entire bytecode to\nnative machine code. This removes dispatch overhead and does minor local\noptimizations. This machine code still calls back into C++ for complex\noperations. The translation is very fast but the `BaselineScript`\n\nuses\nmemory and requires `mprotect`\n\nand flushing CPU caches.\n\n#### WarpMonkey\n\nThe *WarpMonkey* JIT replaces the former *IonMonkey* engine and is the\nhighest level of optimization for the most frequently run scripts. It is able\nto inline other scripts and specialize code based on the data and arguments\nbeing processed.\n\nWe translate the *bytecode* and *Inline Cache* data into a Mid-level\n[Intermediate Representation](https://en.wikipedia.org/wiki/Intermediate_representation) (Ion MIR) representation. This graph is\ntransformed and optimized before being *lowered* to a Low-level Intermediate\nRepresentation (Ion LIR). This *LIR* performs register allocation and then\ngenerates native machine code in a process called *Code Generation*.\n\nSee [MIR Optimizations](./MIR-optimizations/index.html) for an overview of MIR optimizations.\n\nThe optimizations here assume that a script continues to see data similar\nwhat has been seen before. The *Baseline* JITs are essential to success here\nbecause they generate *ICs* that match observed data. If after a script is\ncompiled with *Warp*, it encounters data that it is not prepared to handle it\nperforms a *bailout*. The *bailout* mechanism reconstructs the native machine\nstack frame to match the layout used by the *Baseline Interpreter* and then\nbranches to that interpreter as though we were running it all along. Building\nthis stack frame may use special side-table saved by *Warp* to reconstruct\nvalues that are not otherwise available.\n\n### 🟪 WebAssembly\n\nIn addition to *JavaScript*, the engine is also able to execute *WebAssembly*\n(WASM) sources.\n\n#### WASM-Baseline (RabaldrMonkey)\n\nThis engine performs fast translation to machine code in order to minimize latency to first execution.\n\n#### WASM-Ion (BaldrMonkey)\n\nThis engine translates the WASM input into same *MIR* form that *WarpMonkey*\nuses and uses the *IonBackend* to optimize. These optimizations (and in\nparticular, the register allocation) generate very fast native machine code.", "url": "https://wpnews.pro/news/warpmonkey", "canonical_source": "https://firefox-source-docs.mozilla.org/js/index.html#warpmonkey", "published_at": "2026-06-16 14:34:57+00:00", "updated_at": "2026-06-16 14:48:37.541845+00:00", "lang": "en", "topics": ["large-language-models", "developer-tools"], "entities": ["SpiderMonkey", "Mozilla Firefox", "ECMAScript", "WebAssembly", "JS::Value", "JSObject", "Stencil", "BytecodeEmitter"], "alternates": {"html": "https://wpnews.pro/news/warpmonkey", "markdown": "https://wpnews.pro/news/warpmonkey.md", "text": "https://wpnews.pro/news/warpmonkey.txt", "jsonld": "https://wpnews.pro/news/warpmonkey.jsonld"}}