How Polymorphic Inline Cache Speeds Up JavaScript

A Polymorphic Inline Cache (PIC) is an optimization strategy used by modern JavaScript engines like V8 and SpiderMonkey to accelerate property access and method calls on objects with varying shapes. JavaScript is dynamically typed, meaning property lookups typically require runtime inspection of an object’s structure and prototype chain. PIC speeds up repetitive calls by recording a small set of previously encountered object shapes and their resolved method locations directly at the call site, replacing expensive dynamic lookups with fast conditional checks.

The Problem: Dynamic Method Resolution

In JavaScript, objects can change shapes at runtime, and methods can be added, overridden, or inherited. When a method call like obj.render() executes, the engine cannot inherently know where render resides in memory. By default, it must perform a dynamic lookup:

  1. Inspect the object’s internal structure (hidden class or “Shape”).
  2. Search the object’s own properties for the method.
  3. Traverse the prototype chain if the property is not found locally.
  4. Resolve the method’s memory address and invoke it.

Repeating this full resolution on every iteration of a loop causes significant performance overhead.

From Monomorphic to Polymorphic Caching

To optimize method resolution, engines use Inline Caching (IC):

How PIC Operates Internally

A Polymorphic Inline Cache maintains a small, fixed-size lookup table (typically 2 to 4 entries) directly at the call site:

  1. Shape Comparison: When the method is invoked, the engine reads the hidden class identifier (Shape/Map) of the incoming object.
  2. Linear Search in Cache: The engine checks the identifier against the cached shapes in the PIC list:
    • [Shape A -> Method Address A]
    • [Shape B -> Method Address B]
    • [Shape C -> Method Address C]
  3. Cache Hit: If a match is found, the engine retrieves the pre-resolved method address and executes it immediately, bypassing prototype traversal entirely.
  4. Cache Miss and Expansion: If the shape is not in the cache and the cache has not reached its limit (usually 4 entries), the engine resolves the method normally, adds the new [Shape -> Method] pair to the cache, and continues.

The Megamorphic State

If the number of unique object shapes passing through a single call site exceeds the engine’s threshold, the PIC transitions to a megamorphic state. At this stage, expanding the inline cache list becomes inefficient because linear scanning slows down execution. The engine stops caching locally and falls back to a global lookup table or dynamic resolution.

Summary

Polymorphic Inline Caches balance the flexibility of dynamic typing with the speed of static dispatch. By storing a small list of shape-to-method mappings at the call site, the engine replaces expensive prototype chain walks with quick pointer comparisons, dramatically reducing execution time in hot code paths.