docs/compiler/concurrency-and-background-compilation.md
This document explains how V8 achieves high performance by offloading compilation and parsing to background threads, and the mechanisms used to keep this concurrent execution safe.
To keep the main thread (which runs JavaScript and handles UI interaction) responsive, V8 offloads as much work as possible to background threads.
V8 can parse JavaScript source code and generate Ignition bytecode on background threads. This means that by the time a script is actually executed, its bytecode may already be prepared.
Both Maglev and TurboFan (including its Turboshaft pipeline) perform their heavy optimization work on background threads.
LocalIsolate and LocalHeapBackground threads cannot safely access the main Isolate or Heap without heavy locking, which would destroy performance. Instead, V8 provides "local" equivalents:
LocalIsolate: A thread-local view of the Isolate. It provides access to a LocalHeap and handles background-safe operations.LocalHeap: A thread-local heap that allows the background thread to allocate objects (in its own Linear Allocation Areas) and manage handles without locking the main heap.JSHeapBroker and HeapRefsA major challenge in background optimization is that the background thread needs to know about the structure of JavaScript objects (Maps, shapes, constants) to optimize effectively. However, reading these objects directly from the background thread is unsafe because:
To solve this, V8 uses the JSHeapBroker and a system of HeapRefs:
HeapRefs: Instead of using direct pointers (Tagged<Object>), optimizing compilers use Refs (e.g., ObjectRef, MapRef, JSFunctionRef).HeapRefs to read the live heap concurrently for most kinds of data, rather than relying on a full snapshot.
NEVER_SERIALIZED and are always read live from the background thread.This approach ensures that the background compiler sees a safe view of the heap data while minimizing the overhead of snapshotting.
Even with isolation, the Garbage Collector occasionally needs to stop all threads to perform a collection. V8 uses a Safepoint mechanism to coordinate this.
Threads running JavaScript or accessing the heap must regularly check if a safepoint has been requested (by calling Safepoint()). When requested, they pause execution until the GC is complete.
Background threads (like a compiler thread) might spend a long time doing pure computation without needing to access the heap.
Parked State: A thread can explicitly "park" itself. Instead of creating a ParkedScope directly (its constructors are private), threads should use ExecuteWhileParked (or similar methods on LocalHeap), which provides a const ParkedScope& witness to the callback. While parked, the thread promises not to access the heap.This allows long-running background tasks to proceed without delaying garbage collection.
src/heap/local-heap.h: Definition of LocalHeap and parking states.src/heap/parked-scope.h: Definition of ParkedScope and related guards.src/compiler/js-heap-broker.h: The heap broker for background optimization.