Engine

V8 is Google’s open-source JavaScript engine, written in C++, responsible for compiling and executing JavaScript code.
- It turns JavaScript source code → machine code that your CPU executes directly.
- It’s fast because it uses Just-In-Time (JIT) compilation and smart optimizations.
Parser & Scanner
- The Scanner tokenizes the JavaScript source (breaks into symbols, identifiers, keywords).
- The Parser turns these tokens into an AST (Abstract Syntax Tree) — a tree-like representation of code structure.
Ignition (Interpreter)
- Ignition is V8’s interpreter.
- It takes the AST and converts it into bytecode — a lightweight, low-level representation of your JS.
- Then, it executes that bytecode.
Bytecode = intermediate form between source code and machine code.
Bytecode of let a = 1 + 2; might look like:
LdaSmi [1]
AddSmi [2]
StaGlobal a
Profiler & Hot Function Detection
While Ignition runs the code, V8 profiles it — meaning it keeps track of:
- Which functions run often (“hot” functions)
- What data types are being used
- How objects are shaped (hidden classes)
When a function runs enough times, it’s marked as hot — and sent to the TurboFan optimizer.
TurboFan (Optimizing JIT Compiler)
- TurboFan compiles hot functions into highly optimized machine code.
- It makes speculative optimizations (based on observed types and patterns).
Hot Function
A hot function is a function that gets executed many times or runs in performance-critical parts of your program — so the engine decides to optimize it into machine code for faster performance.
Why the Concept Exists
JavaScript engines like V8 use JIT (Just-In-Time) compilation:
- Code starts running immediately via an interpreter (Ignition in V8)
- Meanwhile, the engine watches how your code behaves at runtime
- If a function runs many times and behaves predictably (same argument types, same object shapes) → it’s hot
- Then V8 compiles it into optimized machine code using TurboFan
This way:
- Startup is fast (no heavy compilation upfront)
- Performance improves automatically for frequently-used code
Garbage Collector
The V8 engine uses a generational garbage collection strategy to optimize memory management. This approach divides memory into two areas: the young generation and the old generation.
JavaScript manages memory automatically — V8 does this using a Generational Garbage
1. Memory Allocation (Heap)
- When JavaScript objects (like functions, arrays, and objects) are created, they are allocated in the heap memory.
- The young generation is where new objects are allocated. Initially, most objects are created here.
2. Mark-and-Sweep Algorithm
V8 uses a mark-and-sweep algorithm for garbage collection. The process can be broken down into these steps:
Mark Phase
- The garbage collector starts by identifying root objects. These are objects that are directly accessible by the program (e.g., global variables, objects referenced in the call stack, and variables that are part of the active execution context).
- The GC marks all objects that are reachable from the root objects as alive.
- Any object that cannot be reached from the root objects is considered unreachable and eligible for garbage collection.
Sweep Phase
- Once all reachable objects are marked, the garbage collector will sweep through the heap and free the memory of any objects that are not marked as reachable.
- These freed objects are effectively removed from memory, making space for new allocations.
3. Generational Garbage Collection (Young vs Old Generation)
Young Generation:
- This is where newly created objects are allocated. It is designed to quickly collect short-lived objects that will be discarded soon after their creation.
- The young generation is smaller and is collected more frequently. V8's GC uses a process called minor GC to clean up the young generation.
Old Generation
- Objects that survive multiple collections in the young generation are promoted to the old generation. These are objects that have longer lifespans (e.g., global objects, or objects stored for an extended period).
- The old generation is much larger and is collected less frequently, using a major GC.
- When a major GC happens, the garbage collector may scan through the entire heap, including the old generation.
4. Garbage Collection Triggers
Minor GC
- Occurs frequently and focuses on cleaning up the young generation.
- Triggered when the young generation becomes full. It is a relatively quick process because only a small portion of memory is being cleaned.
Major GC
- Occurs less frequently but is more expensive, as it scans the entire heap (young and old generations).
- Triggered when the old generation becomes full or when the system needs to reclaim memory.
5. Mark-Sweep & Compaction
- After marking objects and sweeping unreachable ones, V8 may also compact memory. Compaction involves moving live objects closer together to reduce memory fragmentation.
- The goal of compaction is to make the heap more efficient by minimizing gaps between live objects, improving memory usage.
6. Reference Counting (Used Sparingly)
- Although V8 uses mark-and-sweep primarily, earlier versions of the V8 engine used reference counting. This involved counting the number of references to an object.
- When the reference count drops to zero (i.e., the object is no longer referenced by any variable), it is immediately collected.
- However, reference counting has its downsides (such as inability to detect circular references), so it's used minimally in V8 today.