we (web engine): Experimental web browser project to understand the limits of Claude

Object shapes (hidden classes) for JS engine #136

open opened by pierrelf.com

Summary#

Replace the HashMap<String, Property> object representation with a shape (hidden class) system that tracks object layout transitions. This is the foundational optimization for inline caches and JIT property access.

Background#

Currently, ObjectData in crates/js/src/vm.rs stores properties in a HashMap<String, Property>. Every property access requires a hash lookup and prototype chain walk. A shape system assigns each object a pointer to a shared shape that describes its property layout (names, offsets, attributes), enabling O(1) indexed property access.

Acceptance Criteria#

  • Define a Shape structure that maps property names to fixed slot indices
  • Each shape tracks: property name → slot index, parent shape (transition chain), prototype reference
  • Implement a shape transition table: when a property is added, look up or create a child shape
  • Replace ObjectData.properties: HashMap<String, Property> with:
    • shape: ShapeId (index into a global shape table)
    • slots: Vec<Value> (dense property storage indexed by shape slot offsets)
  • Property attributes (writable, enumerable, configurable) stored in the shape, not per-slot
  • gc_get_property() and gc_set_property() use shape-based lookup: shape lookup → slot index → direct Vec access
  • Prototype chain walk still works (check own shape first, then walk prototype shapes)
  • Dynamic property deletion falls back to a "dictionary mode" (rehash into HashMap) for that object
  • All existing JS tests pass unchanged
  • Add unit tests for shape transitions, property lookup, deletion fallback

Implementation Notes#

  • Add a ShapeTable (arena of shapes) to the Vm struct, shared across all objects
  • Shape transitions should be cached: HashMap<(ShapeId, String), ShapeId> so identical property additions reuse shapes
  • Objects created by the same constructor in the same order will share shapes — this is the key optimization
  • The Traceable impl for objects must trace slot values
  • Consider a ShapeId = u32 newtype for type safety

Dependencies#

None — this is the foundation for inline caches (next issue).

Phase#

Phase 15: Performance

sign up or login to add to the discussion
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:meotu43t6usg4qdwzenk4s2t/sh.tangled.repo.issue/3mi4zwe7hou2g