perf(runtime): delete the prototype-link flags; the ShapeId names its prototype identity kind (Refs #10507) - #11834
Merged
Merged
Conversation
added 4 commits
October 3, 2026 22:15
… prototype With the prototype a fact of the shape (#11815), every reader of OBJECT_META_FLAG_PROTO_DIVERGED was a cache gate whose key already carries the prototype, so the per-instance flag only duplicated the ShapeId: - store plans (field_set_by_name, its tail, the proxy set path) are keyed by (class id, key, receiver prototype bits); - array-subclass dense layouts (array/subclass.rs, subclass_loop_guard.rs) are keyed by (class id, ShapeId) and validated by the receiver word, which carries the ShapeId; - the defineProperty key-add tail (keys_array.rs) replays ShapeId-keyed transition edges; - `x instanceof <class object>` (instanceof/dynamic_dispatch.rs) now asks whether the receiver has a recorded prototype instead. The flag, its funnel write, the class-object-template set/clear and its tests are deleted; bit 0 of ObjectMeta.flags is free. A runtime-wiring link on a function-constructor instance no longer allocates a meta record. Tests: `new F()` and `Object.create(F.prototype)` receivers share one shape; the dense array-subclass test now asserts the receiver moves to another ShapeId across a prototype override and its own element still reads the same (it asserted the old per-instance decline). Refs #10507
…ink flags The user-override and class-evaluation flags (and the process-wide USER_PROTO_OVERRIDE_EVER latch) recorded HOW an object's prototype was set. With the prototype a fact of the shape, every reader now asks the shape what the prototype IS: - "does this instance stand on a prototype other than its class's?" is the shape identity versus the class's implied identity (`object_has_individual_class_prototype`: prototype_override field reads, native_call_method, symbol gets, evaluation-template misses). A compiled class instance linked to its own declaration prototype (runtime wiring of a native-base subclass) takes the class identity, so it keeps the class surface and its class's shapes. - "was a class declaration prototype re-pointed?" compares its recorded [[Prototype]] with its declaration's parent prototype (`decl_prototype_relinked`), behind a latch armed only by user relinks of class-chain links (a declaration prototype, a class object or constructor, a function object); re-pointing an ordinary instance arms nothing. - `instanceof` against a class walks the live chain from the shape when the receiver's identity is not its class's or a class-chain link was relinked; the util.inherits escape hatch is gone (the relink is a shape fact of the prototype it moved). The prototype funnel records no flag and so allocates no meta record: Object.create, `__proto__` and setPrototypeOf receivers carry their prototype in their shape alone. A receiver that already has a meta record keeps the same bits there. ObjectMeta.flags bits 0, 3 and 4 are free. Refs #10507
…e record only for a word Phase 2 made every meta-less receiver read its [[Prototype]] from its shape record and identity word (~50 instructions), where main answered a meta-less non-synthetic receiver with one compare of its class id. qs (+0.75%), commander (+0.29%), g6 (+7.4%), `instanceof` against a class (+21%) and decimal_class paid for it. - A ShapeId carries its prototype identity KIND in bits 20-21: plain (the realm default, a class's declaration prototype, a per-object identity), word (a serial, MIXED or UNIQUE link) or null. Each band mints every kind from its own counter, in alternating 2^20-id granules (page-aligned, so no record memory is spent on the interleave); the compiler's static band is one plain granule. `ShapeSlab::insert` asserts that a plain or null id names exactly that identity. - `object_prototype_word` (now inlined): the meta word, else 0 for a plain id, the born-null header test for a null id, and the record plus identity word (out of line) only for a word id. - `object_has_individual_class_prototype` and the `instanceof` relink check test the kind before any record or registry read; `instanceof` hands the check the receiver it already holds. - `object_proto_id_for` asks the class registry about a declaration prototype only when the recorded prototype is an object of that class. - The inherited-read walks (`read_holder::walk`, `class_link`, `class_read::admitted_next`) read each hop's word once for both the identity check and the hop, not two or three times. - An object marked as a prototype keeps its own [[Prototype]] in its meta record (`keep_prototype_in_record`): a class declaration prototype is linked to its parent's before it has a record. Refs #10507
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (36)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prototype-in-shape phase 2 (Refs #10507). With the prototype in the shape (#11815), the prototype-link flags were bookkeeping for the old two-sources model.
What changed
PROTO_DIVERGED,USER_PROTO_OVERRIDE,CLASS_EVALUATION_PROTOand theUSER_PROTO_OVERRIDE_EVERlatch.Object.create,__proto__andsetPrototypeOfobjects.instanceofwalks the live chain from the shape, and the util.inherits escape hatch is gone.CLASS_CHAIN_RELINKED_EVERstill guards the class-id shortcuts. It goes away with the class-table retirement slices (perf: class prototypes hold real method slots (class-table retirement slice 1); pack relative relocations on Linux #11831 onward).Instructions (main vs this PR)
Verification: runtime 4847/0; codegen lib 1947/0; gap 370 with 0 regressions and 3 fixed; GC-stress seeds match; fmt clean. Verified on base c170908; this branch is the same commits replayed cleanly onto current main.
RSS: Zod is +4 MB on the default link with equal page-fault counts, which looks like huge-page placement (unproven). tsc RSS is −9 MB.