Repo deep dive

v8/v8

The directory names are the design. Four compile tiers each get their own, the object model and the collector get one each, and the public surface an embedder is allowed to touch fits in a handful of headers.

entry

include/ & src/api

the embedder surface

The headers Chromium and Node.js compile against, and the C++ that implements them. Everything an embedder can do — create an isolate, enter a context, install a native callback, run a script — enters here. It is deliberately narrow: the rest of the tree is not public API.

v8::Isolate::New(params);
v8::Script::Compile(ctx, src);
front end

src/parsing

scanner, parser, preparser

Turns characters into an AST, or into as little as it can get away with. The preparser exists here alongside the real parser precisely so most function bodies can be skipped on first sight and revisited only when called.

src/parsing/parser.cc
src/parsing/preparser.cc
tier 0

src/interpreter

Ignition

The bytecode generator, the instruction set, and the handlers. bytecodes.h is the list of everything V8 can be asked to do, and it is short enough to read in one sitting — a good map of the language from the engine’s side.

src/interpreter/bytecodes.h
tier 1

src/baseline

Sparkplug

A few thousand lines, most of it a switch over bytecodes emitting the equivalent machine code. The smallest compiler in the tree, and the clearest one to read first — there is no IR in the way between input and output.

src/baseline/baseline-compiler.cc
tier 2

src/maglev

the mid-tier JIT

Builds an SSA graph straight from the bytecode, specialises it against the feedback vector, allocates registers, emits code. Newer than the rest, and written knowing what TurboFan cost — the whole design brief was most of the benefit for a fraction of the compile time.

src/maglev/maglev-graph-builder.cc
tier 3

src/compiler

TurboFan

The largest directory in the engine: graph construction, typing, the reducer passes, escape analysis, scheduling, instruction selection per architecture. Everything speculative about V8 is decided here, and every guard it inserts is a place execution can fall back to the interpreter.

src/compiler/pipeline.cc
src/compiler/js-typed-lowering.cc
model

src/objects

the heap object model

Every shape a value can take on the heap: Map, JSObject, String and its dozen representations, FixedArray, FeedbackVector. The .tq files here declare field layouts once, and the generated accessors keep C++ and compiled code agreeing about where a field lives.

src/objects/map.h
src/objects/js-objects.tq
memory

src/heap

the collector

Spaces, the scavenger, mark-compact, incremental and concurrent marking, and the write barriers that hold it all together. cppgc lives here too — the C++ garbage collector that started as Blink’s Oilpan and now collects DOM objects with the same machinery.

src/heap/mark-compact.cc
src/heap/cppgc/
library

src/builtins

the standard library

Array.prototype.map, Object.assign, the string methods — implemented not in C++ or JavaScript but in Torque, a typed DSL that compiles to the same code generator the compilers use. Written once, compiled ahead of time, and baked into the binary.

src/builtins/array-map.tq
backend

src/codegen

assemblers

The per-architecture assemblers and macro-assemblers everything above eventually calls, plus CodeStubAssembler — a portable, structured way to emit machine code without writing an architecture back end four times. Torque compiles down to it.

src/codegen/x64/macro-assembler-x64.cc
src/codegen/code-stub-assembler.h
runtime

src/execution

Isolate & frames

isolate.h is the god object: the heap, the stack, the pending exception, the microtask queue, the compilation cache. Stack frame walking lives here too, which is what makes a JavaScript stack trace possible across three tiers of compiled code.

src/execution/isolate.h
src/execution/frames.cc
runtime

src/regexp

Irregexp

Regular expressions get their own compiler. A pattern is parsed, turned into an automaton, and either interpreted or compiled to machine code through the same assemblers — which is why a hot regex can run at native speed, and why a pathological one can hang the thread.

src/regexp/regexp-compiler.cc
wasm

src/wasm

the second front end

Module decoding and validation, the Liftoff baseline compiler, and the bridge into TurboFan for tier-up. It reuses the heap, the isolate and the code manager — WebAssembly is a different input language into the same engine, not a second engine.

src/wasm/baseline/liftoff-compiler.cc
startup

src/snapshot

startup time

Bootstrapping a fresh JavaScript environment means building thousands of objects. V8 does that once at build time, serialises the heap, and deserialises it on startup — so creating a context is closer to a memcpy than to running setup code. Embedders can snapshot their own state on top.

mksnapshot → embedded blob in the binary