Docs

24.1-Engine-Architecture

22.1 Engine Architecture Deep Dive

Understanding how JavaScript engines work internally helps you write more performant code and debug complex issues.


Table of Contents

  1. β€’JavaScript Engine Overview
  2. β€’The Parser
  3. β€’Abstract Syntax Tree (AST)
  4. β€’Bytecode Generation
  5. β€’The Interpreter
  6. β€’JIT Compilation
  7. β€’Optimization Pipeline
  8. β€’Engine Comparison

JavaScript Engine Overview

A JavaScript engine is a program that executes JavaScript code. Modern engines are highly sophisticated, using multiple techniques to achieve near-native performance.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    JAVASCRIPT ENGINE ARCHITECTURE                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚   Source Code: "function add(a, b) { return a + b; }"              β”‚
β”‚                                                                     β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚   β”‚                       PARSING PHASE                          β”‚ β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚ β”‚
β”‚   β”‚  β”‚  Lexer  β”‚ β†’  β”‚ Tokens  β”‚ β†’  β”‚ Parser  β”‚ β†’ AST            β”‚ β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚ β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                              ↓                                      β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚   β”‚                    COMPILATION PHASE                         β”‚ β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚ β”‚
β”‚   β”‚  β”‚  Interpreter  β”‚ ←────→  β”‚ JIT Compiler  β”‚                β”‚ β”‚
β”‚   β”‚  β”‚  (Ignition)   β”‚         β”‚  (TurboFan)   β”‚                β”‚ β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚ β”‚
β”‚   β”‚         ↓                          ↓                        β”‚ β”‚
β”‚   β”‚    Bytecode              Optimized Machine Code             β”‚ β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                              ↓                                      β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚   β”‚                    EXECUTION PHASE                           β”‚ β”‚
β”‚   β”‚           CPU executes bytecode or machine code              β”‚ β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Major JavaScript Engines

EngineBrowser/RuntimeCompanyKey Components
V8Chrome, Node.js, DenoGoogleIgnition + TurboFan
SpiderMonkeyFirefoxMozillaBaseline + IonMonkey
JavaScriptCoreSafariAppleLLInt + DFG + FTL
ChakraLegacy EdgeMicrosoftSimpleJIT + FullJIT

The Parser

The parser converts source code text into a structured representation the engine can work with.

Two-Phase Parsing

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         PARSING PHASES                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  PHASE 1: LEXICAL ANALYSIS (Tokenization)                          β”‚
β”‚  ─────────────────────────────────────────                         β”‚
β”‚                                                                     β”‚
β”‚  Source: "let x = 10 + 5;"                                         β”‚
β”‚                                                                     β”‚
β”‚  Tokens:                                                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”                       β”‚
β”‚  β”‚ let β”‚  x  β”‚  =  β”‚ 10  β”‚  +  β”‚  5  β”‚  ;  β”‚                       β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€                       β”‚
β”‚  β”‚ KWD β”‚ ID  β”‚ OP  β”‚ NUM β”‚ OP  β”‚ NUM β”‚ PUN β”‚                       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚                                                                     β”‚
β”‚  PHASE 2: SYNTACTIC ANALYSIS (Parsing)                             β”‚
β”‚  ─────────────────────────────────────────                         β”‚
β”‚                                                                     β”‚
β”‚  Tokens β†’ Abstract Syntax Tree (AST)                                β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Lazy Parsing (Pre-parsing)

Engines don't parse everything immediatelyβ€”they use lazy parsing for performance:

// Full parse - executed immediately
function greet() {
  console.log('Hello!');
}
greet(); // Called, so fully parsed

// Lazy parse - only pre-parsed initially
function unused() {
  // Complex code here...
  // Not fully parsed until called
  return computeComplexValue();
}
// 'unused' is pre-parsed (syntax checked) but not fully compiled
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         LAZY PARSING                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  EAGER PARSING (Full Parse)                                        β”‚
β”‚  β€’ Function is called immediately                                   β”‚
β”‚  β€’ Top-level code                                                   β”‚
β”‚  β€’ IIFEs (Immediately Invoked Function Expressions)                β”‚
β”‚                                                                     β”‚
β”‚  LAZY PARSING (Pre-Parse)                                          β”‚
β”‚  β€’ Inner functions                                                  β”‚
β”‚  β€’ Functions not immediately called                                 β”‚
β”‚  β€’ Checks syntax, finds variables                                   β”‚
β”‚  β€’ Doesn't generate AST until needed                               β”‚
β”‚                                                                     β”‚
β”‚  Benefits:                                                          β”‚
β”‚  β€’ Faster initial page load                                        β”‚
β”‚  β€’ Lower memory usage                                               β”‚
β”‚  β€’ Parse on demand                                                  β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Abstract Syntax Tree (AST)

The AST is a tree representation of the source code's structure.

Example AST

// Source code
let sum = a + b;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ABSTRACT SYNTAX TREE                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚                        Program                                      β”‚
β”‚                           β”‚                                         β”‚
β”‚                  VariableDeclaration                                β”‚
β”‚                    (kind: "let")                                    β”‚
β”‚                           β”‚                                         β”‚
β”‚                  VariableDeclarator                                 β”‚
β”‚                      /         \                                    β”‚
β”‚               Identifier    BinaryExpression                        β”‚
β”‚              (name: "sum")   (operator: "+")                        β”‚
β”‚                               /           \                         β”‚
β”‚                        Identifier      Identifier                   β”‚
β”‚                       (name: "a")     (name: "b")                   β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

AST Node Types

CategoryNode Types
DeclarationsVariableDeclaration, FunctionDeclaration, ClassDeclaration
ExpressionsBinaryExpression, CallExpression, MemberExpression
StatementsIfStatement, ForStatement, ReturnStatement
LiteralsNumericLiteral, StringLiteral, BooleanLiteral
PatternsObjectPattern, ArrayPattern, RestElement

AST in Action

// You can explore ASTs with tools like AST Explorer
// or programmatically with parsers

// Example: Simple function
function multiply(x, y) {
  return x * y;
}

/*
AST Structure:
{
  type: "FunctionDeclaration",
  id: { type: "Identifier", name: "multiply" },
  params: [
    { type: "Identifier", name: "x" },
    { type: "Identifier", name: "y" }
  ],
  body: {
    type: "BlockStatement",
    body: [{
      type: "ReturnStatement",
      argument: {
        type: "BinaryExpression",
        operator: "*",
        left: { type: "Identifier", name: "x" },
        right: { type: "Identifier", name: "y" }
      }
    }]
  }
}
*/

Bytecode Generation

After parsing, the interpreter generates bytecodeβ€”a low-level, platform-independent representation.

V8 Ignition Bytecode

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     BYTECODE GENERATION                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  JavaScript:                                                        β”‚
β”‚  ──────────                                                        β”‚
β”‚  function add(a, b) {                                               β”‚
β”‚    return a + b;                                                    β”‚
β”‚  }                                                                  β”‚
β”‚                                                                     β”‚
β”‚  Bytecode (Ignition):                                               β”‚
β”‚  ───────────────────                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  Ldar a1          ; Load argument 'a' into accumulator     β”‚    β”‚
β”‚  β”‚  Add a2           ; Add argument 'b' to accumulator        β”‚    β”‚
β”‚  β”‚  Return           ; Return accumulator value               β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β”‚  Bytecode Properties:                                               β”‚
β”‚  β€’ Register-based (uses accumulator)                               β”‚
β”‚  β€’ Compact representation                                           β”‚
β”‚  β€’ Quick to generate                                                β”‚
β”‚  β€’ Portable across architectures                                    β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Common Bytecode Instructions

InstructionDescriptionExample
LdarLoad from register to accumulatorLdar r0
StarStore accumulator to registerStar r1
AddAdd register to accumulatorAdd r2
LdaSmiLoad small integerLdaSmi [42]
CallCall functionCall r0, r1-r3
ReturnReturn from functionReturn
JumpIfFalseConditional jumpJumpIfFalse [offset]

Viewing Bytecode

// In Node.js, you can view bytecode with:
// node --print-bytecode --print-bytecode-filter=functionName script.js

function example(x) {
  if (x > 0) {
    return x * 2;
  }
  return 0;
}

/*
Bytecode for 'example':
  LdaZero                 ; Load 0
  Star r0                 ; Store in r0
  Ldar a0                 ; Load argument x
  TestGreaterThan r0      ; Compare x > 0
  JumpIfFalse [offset]    ; Jump if false
  Ldar a0                 ; Load x
  LdaSmi [2]              ; Load 2
  Mul r0                  ; x * 2
  Return                  ; Return result
  LdaZero                 ; Load 0
  Return                  ; Return 0
*/

The Interpreter

The interpreter executes bytecode directly, providing fast startup.

Ignition (V8's Interpreter)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      IGNITION INTERPRETER                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                    Bytecode Stream                            β”‚ β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”              β”‚ β”‚
β”‚  β”‚  β”‚Ldarβ”‚Starβ”‚Add β”‚Ldarβ”‚Callβ”‚Jumpβ”‚Ret β”‚... β”‚... β”‚              β”‚ β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜              β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                              ↓                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                    Interpreter Loop                           β”‚ β”‚
β”‚  β”‚                                                               β”‚ β”‚
β”‚  β”‚  while (hasMoreBytecodes) {                                   β”‚ β”‚
β”‚  β”‚    bytecode = fetchNextBytecode();                            β”‚ β”‚
β”‚  β”‚    dispatch(bytecode);  // Execute handler                    β”‚ β”‚
β”‚  β”‚    collectTypeFeedback();  // For optimization                β”‚ β”‚
β”‚  β”‚  }                                                            β”‚ β”‚
β”‚  β”‚                                                               β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                              ↓                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                    Type Feedback                              β”‚ β”‚
β”‚  β”‚                                                               β”‚ β”‚
β”‚  β”‚  "add(1, 2)" β†’ Records: both args are SMI (small integers)   β”‚ β”‚
β”‚  β”‚  "obj.x"    β†’ Records: obj has shape X, x at offset 8        β”‚ β”‚
β”‚  β”‚                                                               β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Interpreter vs. Compiler Trade-offs

AspectInterpreterJIT Compiler
Startup timeFast βœ“Slow (compilation)
Execution speedSlowerFast βœ“
Memory usageLower βœ“Higher (code cache)
Best forShort-running codeHot loops

JIT Compilation

Just-In-Time (JIT) compilation converts hot bytecode to optimized machine code.

TurboFan (V8's Optimizing Compiler)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    TURBOFAN OPTIMIZATION PIPELINE                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  1. GRAPH BUILDING                                                  β”‚
β”‚     Bytecode β†’ Sea of Nodes (SSA form)                             β”‚
β”‚                                                                     β”‚
β”‚  2. TYPE INFERENCE                                                  β”‚
β”‚     Use type feedback from Ignition                                 β”‚
β”‚                                                                     β”‚
β”‚  3. OPTIMIZATION PHASES                                             β”‚
β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚     β”‚  β€’ Inlining           (inline function calls)           β”‚    β”‚
β”‚     β”‚  β€’ Escape Analysis    (stack allocate objects)          β”‚    β”‚
β”‚     β”‚  β€’ Loop Optimization  (unrolling, invariant motion)     β”‚    β”‚
β”‚     β”‚  β€’ Dead Code Removal  (eliminate unused code)           β”‚    β”‚
β”‚     β”‚  β€’ Constant Folding   (compute at compile time)         β”‚    β”‚
β”‚     β”‚  β€’ Bounds Check Elim  (remove redundant checks)         β”‚    β”‚
β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β”‚  4. REGISTER ALLOCATION                                             β”‚
β”‚     Map virtual registers to physical CPU registers                 β”‚
β”‚                                                                     β”‚
β”‚  5. CODE GENERATION                                                 β”‚
β”‚     Generate platform-specific machine code (x64, ARM, etc.)       β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

When Does JIT Kick In?

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    HOT CODE DETECTION                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  V8 tracks function execution:                                      β”‚
β”‚                                                                     β”‚
β”‚  function process(data) {                                           β”‚
β”‚    // Called 100 times β†’ still "warm"                               β”‚
β”‚    // Called 1000+ times β†’ HOT! β†’ Optimize!                        β”‚
β”‚  }                                                                  β”‚
β”‚                                                                     β”‚
β”‚  Optimization Triggers:                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  β€’ Loop back-edges (iterations)                            β”‚    β”‚
β”‚  β”‚  β€’ Function call count                                     β”‚    β”‚
β”‚  β”‚  β€’ Time spent in function                                  β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β”‚  Timeline:                                                          β”‚
β”‚  ─────────────────────────────────────────────────────────────►    β”‚
β”‚  β”‚                                                             β”‚    β”‚
β”‚  β”‚  Ignition           β”‚  TurboFan               β”‚              β”‚    β”‚
β”‚  β”‚  (interpreted)      β”‚  (optimized)            β”‚              β”‚    β”‚
β”‚  β”‚  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚  β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“  β”‚              β”‚    β”‚
β”‚  β”‚                     β”‚                         β”‚              β”‚    β”‚
β”‚  β”‚<─── Cold ──────────>β”‚<─────── Hot ──────────>β”‚              β”‚    β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Optimization Pipeline

Speculative Optimization

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   SPECULATIVE OPTIMIZATION                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  function add(a, b) {                                               β”‚
β”‚    return a + b;                                                    β”‚
β”‚  }                                                                  β”‚
β”‚                                                                     β”‚
β”‚  // Ignition collects type feedback:                               β”‚
β”‚  add(1, 2);     // a: SMI, b: SMI                                  β”‚
β”‚  add(3, 4);     // a: SMI, b: SMI                                  β”‚
β”‚  add(5, 6);     // a: SMI, b: SMI                                  β”‚
β”‚  // ... 1000 more calls with integers                              β”‚
β”‚                                                                     β”‚
β”‚  TurboFan ASSUMES: a and b are always integers                     β”‚
β”‚                                                                     β”‚
β”‚  OPTIMIZED CODE:                                                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  ; Skip type checks - we "know" they're integers           β”‚    β”‚
β”‚  β”‚  mov eax, [a]                                              β”‚    β”‚
β”‚  β”‚  add eax, [b]        ; Direct integer addition             β”‚    β”‚
β”‚  β”‚  jo  bailout         ; But... check for overflow           β”‚    β”‚
β”‚  β”‚  ret                                                       β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β”‚  If assumption is WRONG:                                            β”‚
β”‚  add("hello", "world");  // Strings! Assumption broken!            β”‚
β”‚  β†’ DEOPTIMIZATION β†’ Back to Ignition                               β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Deoptimization (Bailout)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      DEOPTIMIZATION                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  What triggers deoptimization?                                      β”‚
β”‚                                                                     β”‚
β”‚  1. TYPE CHANGE                                                     β”‚
β”‚     function calc(x) { return x * 2; }                              β”‚
β”‚     calc(5);     // Optimized for integers                         β”‚
β”‚     calc("5");   // String! Deoptimize!                            β”‚
β”‚                                                                     β”‚
β”‚  2. HIDDEN CLASS CHANGE                                             β”‚
β”‚     function getX(obj) { return obj.x; }                           β”‚
β”‚     // Optimized for specific object shape                         β”‚
β”‚     getX({ x: 1, y: 2 });  // Different shape! Deoptimize!        β”‚
β”‚                                                                     β”‚
β”‚  3. PROTOTYPE CHANGE                                                β”‚
β”‚     Object.prototype.foo = 42;  // Invalidates assumptions         β”‚
β”‚                                                                     β”‚
β”‚  4. ARGUMENTS OBJECT                                                β”‚
β”‚     function f() { return arguments; }  // Hard to optimize        β”‚
β”‚                                                                     β”‚
β”‚  Deoptimization is EXPENSIVE:                                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  β€’ Discards optimized code                                 β”‚    β”‚
β”‚  β”‚  β€’ Reconstructs interpreter state                          β”‚    β”‚
β”‚  β”‚  β€’ May need to re-optimize later                           β”‚    β”‚
β”‚  β”‚  β€’ Causes performance jank                                 β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Engine Comparison

Compilation Tiers

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ENGINE COMPILATION TIERS                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  V8 (Chrome):                                                       β”‚
β”‚  ─────────────                                                     β”‚
β”‚  Source β†’ Parser β†’ Ignition (interpreter) β†’ TurboFan (optimizer)   β”‚
β”‚                           ↓                         ↓               β”‚
β”‚                      Bytecode            Optimized Machine Code     β”‚
β”‚                                                                     β”‚
β”‚  SpiderMonkey (Firefox):                                            β”‚
β”‚  ─────────────────────────                                         β”‚
β”‚  Source β†’ Parser β†’ Baseline (quick JIT) β†’ IonMonkey (optimizer)    β”‚
β”‚                           ↓                         ↓               β”‚
β”‚                    Simple Machine Code    Optimized Machine Code    β”‚
β”‚                                                                     β”‚
β”‚  JavaScriptCore (Safari):                                           β”‚
β”‚  ────────────────────────                                          β”‚
β”‚  Source β†’ Parser β†’ LLInt β†’ Baseline β†’ DFG β†’ FTL                    β”‚
β”‚                      ↓        ↓        ↓      ↓                     β”‚
β”‚                   Interp   Quick    Mid    Full Optimization        β”‚
β”‚                            JIT      JIT                             β”‚
β”‚                                                                     β”‚
β”‚  Tier Comparison:                                                   β”‚
β”‚  ───────────────                                                   β”‚
β”‚  Speed:       Slow ───────────────────────────────────► Fast       β”‚
β”‚  Compile:     Fast ───────────────────────────────────► Slow       β”‚
β”‚                                                                     β”‚
β”‚  LLInt/Ignition β”‚ Baseline β”‚    DFG    β”‚ TurboFan/IonMonkey/FTL   β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Takeaways

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ENGINE ARCHITECTURE SUMMARY                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  1. PARSING                                                         β”‚
β”‚     β€’ Lexer β†’ Tokens β†’ Parser β†’ AST                                β”‚
β”‚     β€’ Lazy parsing for unused functions                             β”‚
β”‚                                                                     β”‚
β”‚  2. BYTECODE                                                        β”‚
β”‚     β€’ Intermediate representation                                    β”‚
β”‚     β€’ Fast to generate, portable                                    β”‚
β”‚     β€’ Executed by interpreter                                        β”‚
β”‚                                                                     β”‚
β”‚  3. INTERPRETER                                                     β”‚
β”‚     β€’ Executes bytecode directly                                    β”‚
β”‚     β€’ Collects type feedback                                        β”‚
β”‚     β€’ Fast startup                                                  β”‚
β”‚                                                                     β”‚
β”‚  4. JIT COMPILER                                                    β”‚
β”‚     β€’ Compiles hot code to machine code                             β”‚
β”‚     β€’ Uses type feedback for speculation                            β”‚
β”‚     β€’ Much faster execution                                          β”‚
β”‚                                                                     β”‚
β”‚  5. DEOPTIMIZATION                                                  β”‚
β”‚     β€’ When assumptions are violated                                  β”‚
β”‚     β€’ Falls back to interpreter                                     β”‚
β”‚     β€’ Avoid by keeping types stable                                 β”‚
β”‚                                                                     β”‚
β”‚  WRITE OPTIMIZATION-FRIENDLY CODE:                                  β”‚
β”‚  β€’ Use consistent types                                             β”‚
β”‚  β€’ Initialize object properties in constructors                     β”‚
β”‚  β€’ Avoid deleting properties                                        β”‚
β”‚  β€’ Avoid changing prototypes                                        β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Next Steps

Continue to 22.2 Hidden Classes & Inline Caching to learn how V8 optimizes property access and what makes code fast or slow.

.1 Engine Architecture - JavaScript Tutorial | DeepML