29506
views
✓ Answered

Why V8 Ditched Sea of Nodes: The Rise of Turboshaft

Asked 2026-05-18 17:57:15 Category: Environment & Energy

V8's optimizing compiler Turbofan once stood out for using the Sea of Nodes (SoN) intermediate representation. However, after years of development, the team started migrating to a more conventional Control-Flow Graph (CFG) IR called Turboshaft. This shift addressed deep-rooted issues and simplified the compiler. Below are key questions answered about this major transition.

What Exactly Is the Sea of Nodes in V8?

The Sea of Nodes (SoN) is an unconventional intermediate representation (IR) where the control flow and data flow are merged into a graph without explicit basic blocks. Turbofan, V8's top-tier optimizing JavaScript compiler, was one of the few production compilers to use SoN. Unlike traditional CFG-based IRs, SoN allowed flexible reordering and elimination of nodes, but it came with high complexity. Node dependencies were defined by edges, making optimizations like global value numbering more powerful yet harder to implement correctly. The graph could grow large, and debugging was challenging. After years of maintenance, the V8 team decided to move back to a CFG-based approach, which is simpler to reason about and easier to optimize for modern hardware.

Why V8 Ditched Sea of Nodes: The Rise of Turboshaft
Source: v8.dev

Why Did V8 Choose to Move Away from Sea of Nodes?

The decision stemmed from multiple practical concerns. First, the SoN architecture made it difficult to introduce new control flow during lowering—a common need when breaking high-level operations into low-level ones. For instance, lowering JSAdd(x,y) to check types and call different addition functions required extra control flow that SoN couldn't gracefully handle without significant workarounds. Second, the SoN pipeline suffered from performance cliffs where small code changes led to massive slowdowns. Third, debugging and optimizing the graph became increasingly labor-intensive as the codebase grew. The team realized that a simpler CFG IR (Turboshaft) would reduce complexity, improve maintainability, and still deliver competitive performance.

What Were the Major Problems with the Predecessor Crankshaft?

Before Turbofan, V8 used Crankshaft, a CFG-based optimizing compiler. It had severe limitations: (1) Excessive hand-written assembly for each supported architecture (x64, ia32, arm, arm64), making adding new operators tedious. (2) It struggled with asm.js optimization, which was crucial for high-performance web apps at the time. (3) Control flow was fixed after graph building—you couldn't introduce new branches during later passes, blocking useful lowerings. (4) Try-catch statements were unsupported, and months of effort failed to add them. (5) Frequent deoptimization loops occurred when speculative assumptions broke, causing repeated reoptimizations with the same assumptions. (6) Many performance cliffs caused 100x slowdowns if certain features were used. These issues drove the creation of Turbofan with SoN, but SoN introduced its own set of problems.

What Is Turboshaft and How Does It Differ from Sea of Nodes?

Turboshaft is a new control-flow graph (CFG) intermediate representation designed to replace Sea of Nodes in V8's JavaScript and WebAssembly pipelines. Unlike SoN, which merges data and control, Turboshaft uses a traditional structure with explicit basic blocks, control edges, and a separate data-flow graph. This makes the compiler's control flow unambiguous and easier to transform. Turboshaft simplifies optimizations like code motion and instruction selection, and it reduces the cognitive load on compiler engineers. The V8 team gradually migrated Turbofan's JavaScript backend to Turboshaft—by now, the entire JS backend uses it. WebAssembly also switched to Turboshaft throughout its pipeline. Two remnants of Sea of Nodes remain: the builtin pipeline (being replaced by Turboshaft) and the JS frontend (being replaced by Maglev, another CFG IR).

What Parts of V8 Still Use Sea of Nodes Today?

As of the latest updates, only two components of Turbofan still rely on Sea of Nodes. The first is the builtin pipeline, which compiles built-in JavaScript functions (like Array.prototype.push). This pipeline is being incrementally replaced by Turboshaft versions. The second is the frontend of the JavaScript pipeline—the part that translates JavaScript bytecode into the Sea of Nodes graph. This frontend is being phased out in favor of Maglev, a new CFG-based intermediate representation designed for quick optimization without heavy speculative assumptions. Once these two replacements are complete, Sea of Nodes will be entirely removed from V8's codebase, ending an era of innovative but complex compiler design.

How Does This Change Affect JavaScript Performance?

The migration from Sea of Nodes to Turboshaft is expected to have a positive impact on both performance and stability. By moving to a simpler CFG IR, V8 reduces the risk of performance cliffs and deoptimization loops that plagued Crankshaft and occasionally Turbofan. The new architecture makes it easier to introduce optimizations like better inlining, type feedback integration, and instruction selection. WebAssembly also benefits from a unified pipeline. Developers may see more consistent performance across different code patterns and fewer sudden slowdowns. Additionally, the simplification lowers the barrier for new contributors and speeds up development of new language features. While the absolute peak performance may not change drastically, the reliability and maintainability gains are significant for the long-term evolution of V8.