Summary#
Add inline caches (ICs) to GetPropertyByName and SetPropertyByName bytecode operations. When an object's shape matches a previously seen shape at a given bytecode site, skip the full property lookup and use the cached slot index directly.
Background#
After the shape system is in place, property access can be optimized by caching the (shape, slot_index) pair at each bytecode call site. On subsequent executions, if the object's shape matches the cached shape, the property value is read/written directly from the slot vector — no hash lookup, no prototype walk.
Acceptance Criteria#
- Define an
InlineCachestructure:{ shape_id: Option<ShapeId>, slot_index: u32 }(monomorphic) - Each
Function(bytecode unit) has aVec<InlineCache>indexed by IC slot number - The bytecode compiler assigns IC slot indices to
GetPropertyByNameandSetPropertyByNameinstructions - Extend these opcodes to include an IC index operand (e.g.,
GetPropertyByName dst, obj, name_idx, ic_idx) - VM dispatch for these ops: check
ic.shape_id == obj.shape→ direct slot access (fast path); else full lookup + update IC (slow path) - Support megamorphic fallback: if an IC site sees too many shapes (>4), stop updating and always use slow path
- Optional: polymorphic IC (small array of shape→slot pairs) for 2-4 shapes
- All existing JS tests pass
- Add benchmarks or tests demonstrating IC hit rates on typical code patterns
Implementation Notes#
- IC slots are per-function, not global — each function's bytecode has its own IC vector
- The IC index is a
u16encoded in the instruction stream after the existing operands - On shape miss, do the full lookup, then store the result in the IC for next time
- Prototype chain hits should NOT be cached in the simple IC (only own-property hits)
- Consider adding a
ic_hit_count/ic_miss_countfor profiling (useful for JIT tier-up decisions)
Dependencies#
- Requires: Object shapes (hidden classes) issue
Phase#
Phase 15: Performance