V8pedia

The big picture

This page is the map you will keep coming back to. It traces a single function from source text to top-tier machine code, names every component it passes through, and links each one to its own deep dive. Read it once for orientation, then again after you have read the detail pages — it will read very differently the second time.

One sentence

V8 parses JavaScript to an AST, lowers that to bytecode for the Ignition interpreter, and then — guided by runtime feedback — recompiles hot functions through a ladder of progressively more optimizing JITs (Sparkplug → Maglev → TurboFan), all while a generational, mostly-concurrent garbage collector (Orinoco) reclaims memory in the background.

Everything else is detail. Let's unfold it.

The journey of a function

 source text
     │  Scanner (tokens) ──► Parser / PreParser

   AST  ── BytecodeGenerator ──►  Bytecode  ◄─────────────┐
     │                              │                     │ (feedback drives
     │                       Ignition interpreter         │  recompilation)
     │                              │  collects type feedback
     │                              ▼  into the FeedbackVector
     │                      ┌──────────────┐
     │     hot enough?  ──► │  Sparkplug   │  baseline JIT (no opt)
     │                      └──────────────┘
     │                              │  hotter?
     │                      ┌──────────────┐
     │                      │   Maglev     │  mid-tier optimizer (SSA)
     │                      └──────────────┘
     │                              │  hotter & type-stable?
     │                      ┌──────────────┐
     │                      │  TurboFan    │  top-tier optimizer (Sea of Nodes)
     │                      └──────────────┘
     │                              │  assumption violated?
     │                              ▼
     │                       Deoptimization ──► back to Ignition/Sparkplug

  (the heap, managed by Orinoco GC, underlies all of the above)

The stages, one by one

1. Parse: source → AST

The scanner tokenizes UTF-16 source; the parser builds an Abstract Syntax Tree (AST). To keep startup fast, V8 is lazy by default: inner function bodies are pre-parsed (validated and scope-scanned, but no AST built) and only fully parsed when first called. AST nodes are allocated in a Zone — a region allocator freed in one shot — not on the GC heap.

2. Lower: AST → bytecode

The BytecodeGenerator walks the AST and emits Ignition bytecode — a compact, register-machine instruction set with an implicit accumulator. It also allocates feedback slots at this stage, one per operation that wants to learn from runtime types. See Bytecode generation.

3. Interpret: Ignition

Ignition executes bytecode and, crucially, records what it sees — the shapes of objects, the targets of calls, the types of operands — into a per-function FeedbackVector. This feedback is the fuel for every optimization that follows.

4. Climb the tiers

When a function gets hot, V8 tiers it up. Each tier trades more compile time for faster code:

Tier Role Compile speed Code speed
Ignition interpreter baseline
Sparkplug baseline JIT (no optimization) very fast fast
Maglev mid-tier optimizer (SSA CFG) fast faster
TurboFan top-tier optimizer (Sea of Nodes) slow fastest

The tiering manager decides when to climb, based on an interrupt budget scaled by function size. OSR lets a long-running loop jump into optimized code without waiting for the next call.

5. Speculate and recover

Maglev and TurboFan speculate: they compile code that assumes the types seen so far keep holding (e.g. "this is always a Smi"), guarded by cheap checks. When an assumption breaks, deoptimization reconstructs the interpreter frame and resumes in a lower tier. Speculation is the heart of how a dynamically-typed language reaches near-native speed.

6. Manage memory: Orinoco

Underneath everything, the Orinoco garbage collector reclaims memory. It is generational (cheap, frequent Scavenges of the young generation; rarer Mark-Compact of the old), and it does most of its work concurrently and in parallel to keep pauses short. The price JS pays is a write barrier on pointer stores.

The data structures that tie it together

Two object-model inventions make the whole pipeline possible, so read these early:

  • Maps (hidden classes) — every object points to a Map that describes its shape. Objects with the same shape share a Map, which is what lets caches and compilers specialize.

  • Tagged values & Smis — every value is one machine word that is either a small integer or a tagged pointer, so type tests are a bit test and small integers never touch the heap.

What runs all this: the Isolate

A V8 Isolate is one isolated VM instance — its own heap, its own threads, its own GC. The pipeline above happens inside an isolate. Embedders (Chrome, Node.js, Deno) create one or more isolates and feed them Contexts (global environments). To start fast, an isolate boots by deserializing a snapshot of a pre-initialized heap rather than building it from scratch.

Where to go next