jit-inline-cache-polymorphism-20260728
The implementation provides a complete Polymorphic Inline Cache (PIC) optimization pass for a JavaScript JIT compiler. The core design mirrors V8's IC system:
Shape System — Each object carries a Shape (hidden class) that tracks property offsets and transitions. When a property is added, the shape transitions to a new child shape, mirroring how V8's Map objects work.
Inline Cache States — Three dispatch tiers based on observed object shapes at a call site: 1. Monomorphic (1 shape): Single shape-guard → direct offset load 2. Polymorphic (2–4 shapes): Cascading shape-ID checks via a move-to-front heuristic 3. Megamorphic (5+ shapes): Dictionary-style slow path using a shape-ID → value cache
Stub Generation — Each IC emits a structured "stub" object containing guards (shape_check), load type (direct_load or prototype_chain_load), and a fallback handler. A real JIT backend lowers these stubs to native code (x86/ARM).
Prototype Chain Lookup — The lookupOffset method on Shape walks the prototype chain of shapes. The runtime doPrototypeChain helper walks parallel JSObject prototype objects with visited-set cycle detection.
Key code from the solution:
// Shape (hidden class) with property map, prototype link, and transition table
class Shape {
constructor(prototype = null) {
this.id = ++shapeIdCounter;
this.properties = new Map(); // name → { offset, writable, ... }
this.prototype = prototype; // parent shape in prototype chain
this.transitions = new Map(); // property name → { shape, offsetName }
}
lookupOffset(name) {
if (this.properties.has(name)) return this.properties.get(name);
if (this.prototype) return this.prototype.lookupOffset(name);
return null;
}
}
// Inline cache with three dispatch states
class InlineCache {
constructor(name) {
this.state = IC_STATE.UNINITIALIZED;
this.monomorphicShape = null;
this.polymorphicShapes = []; // up to 4 shapes
this.megamorphicCache = new Map(); // shapeId → cached value
}
recordAccess(object, propertyName) {
const shape = object.shape;
switch (this.state) {
case IC_STATE.UNINITIALIZED:
this.monomorphicShape = shape;
this.state = IC_STATE.MONOMORPHIC;
break;
case IC_STATE.MONOMORPHIC:
if (!this.monomorphicShape.matches(shape)) {
// Second shape → polymorphic
this.polymorphicShapes = [this.monomorphicShape, shape];
this.monomorphicShape = null;
this.state = IC_STATE.POLYMORPHIC;
}
break;
case IC_STATE.POLYMORPHIC:
// ... checks existing, adds up to 4, then megamorphic
case IC_STATE.MEGAMORPHIC:
this.megamorphicCache.set(shape.id, null);
}
}
generateStub(propertyName) {
// Returns structured IR: guards[], fallback type
}
}
Verified with 12 comprehensive test suites covering all states, transitions, and edge cases: | Test | Scenario | Result | |------|----------|--------| | 1 | Monomorphic IC — single shape, 10+ accesses stays mono | ✓ hitCount=11 | | 2 | Polymorphic (2 shapes) — two hidden classes | ✓ poly state, 2 cached | | 3 | Polymorphic (4 shapes) — max polymorphic capacity | ✓ 4 shapes, re-read correct | | 4 | Megamorphic (6 shapes) — overflow to dictionary | ✓ all values correct | | 5 | Hidden class transitions — adding properties changes shape | ✓ original + new accessible | | 6 | Prototype chain lookups — own + inherited + missing | ✓ y=99, x=10, undefined | | 7 | Stub generation — guards, shape IDs, execution | ✓ monomorphic stub returns 77 | | 8 | JIT integration + V8-style benchmark (1000 shapes) | ✓ megamorphic, sum=15 | | 9 | Move-to-front heuristic — hot shape promoted | ✓ shape[2] at front | | 10 | Megamorphic dictionary — 8 shapes, all correct | ✓ size=8, values correct | | 11 | Shape identity — structurally identical ≠ same shape | ✓ matches works correctly | | 12 | Prototype chain + shape transition — combined | ✓ prototype survives transition | **Edge cases handled:** - `__proto__` name collision avoided (uses `protoObj` property) - `hasOwnProperty` called safely via `Object.prototype.hasOwnProperty.call` - Cycle detection in prototype chain walks - Miss handler fallback when no guard matches ---
{"model": "claude-sonnet-4-20250514", "problem_class": "jit-inline-cache-polymorphism-20260728", "result": "passed", "tests": 12}