V8pedia

d8 & debugging tools

d8 is V8's standalone developer shell: a small binary that embeds V8 and lets you run JavaScript directly, with debugging hooks the public web never exposes. It is the single most useful tool for learning V8, because it lets you watch the machinery this site describes — tiering, deopts, IC states, GC — happen on real code.

::: info Ubiquitous language d8: the "developer shell" (the "d" + V8). Natives syntax: special %Function() intrinsics, enabled with --allow-natives-syntax, that poke V8 internals from JS. Trace flags: --trace-* flags that log internal events. :::

What d8 is

enum class ModuleType { kJavaScript, kJSON, kWebAssembly, kText, kBytes, kInvalid };
class SourceGroup {
  bool Execute(Isolate* isolate);
  void StartExecuteInThread();

};

src/d8/d8.h

It runs d8 script.js to execute a file, drops into a REPL when run bare, loads ES modules / JSON / WASM, and can even run scripts on multiple threads (separate isolates) via SourceGroup. Build it with gm.py x64.release d8.

Natives syntax: poke the internals from JS

Run d8 with --allow-natives-syntax and a set of %-prefixed intrinsics become available. These are the fastest way to see V8's internal state on a value:

// d8 --allow-natives-syntax
function add(a, b) { return a + b; }
add(1, 2); add(3, 4);                       // warm it up
%OptimizeFunctionOnNextCall(add);           // force optimization on next call
add(5, 6);
console.log(%GetOptimizationStatus(add));   // inspect tier / status bits

const o = { x: 1, y: 2 };
%DebugPrint(o);                             // dump the object's Map, layout, …
console.log(%HasFastProperties(o));         // fast vs dictionary mode

The intrinsics most relevant to this site:

  • %DebugPrint(x) — print an object's Map, elements kind, and layout. The fastest way to see hidden classes.

  • %HasFastProperties(x) — fast (Map-described) vs dictionary mode.

  • %OptimizeFunctionOnNextCall(f) / %GetOptimizationStatus(f) — drive and inspect tiering.

  • %CollectGarbage(null) — force a GC.

::: warning Internal and unstable Natives syntax is a debug feature. The set of %-functions, their names, and their behavior change without notice, and they are unavailable in normal (non---allow-natives-syntax) execution. Use them to learn, never in real code. :::

Trace flags: watch the engine work

Pass these to d8 (or Node via --v8-options) to log internal events as your code runs — this is how you turn the abstractions on this site into observations:

Flag Shows Related page
--trace-opt / --trace-deopt when functions optimize / why they deopt Deopt, Feedback
--trace-ic inline-cache state transitions per site Inline caches
--print-bytecode the Ignition bytecode emitted Bytecode gen
--print-opt-code the optimized machine code TurboFan
--trace-gc every GC, its kind, and pause time GC overview
--trace-maglev-graph Maglev's IR Maglev
--prof a sampling profile (post-process with tools/)

::: tip A learning loop The tightest way to internalize V8: write a tiny snippet, run it under d8 --allow-natives-syntax --trace-opt --trace-deopt --trace-ic, and watch a function climb the tier ladder, see its ICs go monomorphic, then deliberately break its type stability and watch it deoptimize. Every claim on this site has an observable counterpart here. :::

Other tools in the tree

  • mksnapshot — builds the startup snapshot (a build-time tool).

  • torque — the Torque compiler.

  • tools/ — profiling post-processors (tick processor), the tools/system-analyzer, and more.

  • Inspector protocol — d8 can speak the Chrome DevTools protocol for debugging.

See also