Answer an authoritative miss from the builtin-shape probe lane - #2858
Merged
Conversation
A depth-4 chain of shaped prototypes with an ordinary receiver in front, walked by the in operator: AbsentNameMissOverChain pays every level's refusal, DeepHitOverChain resolves on the root as the hit-path control. Every chain level's representation is asserted in GlobalSetup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A JsString probe that misses the shared layout index used to decline into the virtual GetOwnProperty, which redid the key conversion and repeated the same index lookup - at every level of a HasProperty chain walk. When the side dictionary is empty and the type resolves no string names ahead of the layout (derived: it does not override GetInitialOwnStringPropertyKeys), the miss is authoritative and is answered directly. TryProbeBuiltinShapeSlot now distinguishes a true index miss from a declared-but-unanswerable Factory slot; only the former may fast-miss. The derived BuiltinShapeIndexAuthoritative bit rides BuiltinShapeMode: set in InitializeBuiltinShape, cleared on deopt, re-derived on global snapshot restore. Closes sebastienros#2857. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 29, 2026
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.
Fixes #2857.
ProbeOwnProperty's builtin-shape lane could only answer a hit; a miss declined into the virtualGetOwnProperty, which redid the key conversion and repeated the same shape-index lookup — at every level of aHasPropertychain walk. A chain ofJsObjectShapeprototypes therefore answered an absent name measurably slower than the dictionary prototypes it replaced, which WebIDL named-indexer checks (el.attributes['nope']) hit constantly.The fix
A
JsStringprobe that is a true shape-index miss is answeredMissingdirectly when the side dictionary is empty and the type qualifies, gated by a new derivedInternalTypes.BuiltinShapeIndexAuthoritativebit:InitializeBuiltinShapefrom the existing sentinel checkReferenceEquals(GetInitialOwnStringPropertyKeys(), Enumerable.Empty<JsValue>())— the same predicateGetForInStringKeysalready trusts.Function-derived hosts (length/name/prototypefrom fields) andStringInstanceoverride that provider and are excluded automatically; future overriders self-exclude.ArrayInstancekeeps the flag soundly because its ownProbeOwnPropertyinterceptslengthand every canonical index before calling base, and digit-leading names can never be hybrid additions (the write deopts).DeoptBuiltinShape, re-derived on global snapshot restore — a bare|= BuiltinShapeModethere would have permanently lost the lane after one deopt+restore cycle, exactly the capture/restore reuse pattern the lane serves.The trap that ruled out the issue's original diff
TryProbeBuiltinShapeSlotreturnsfalsefor two different reasons: a true index miss, and a declared name whose slot is an unmaterializedFactoryslot. The issue's narrowSharedShapeObjectdiff fired on both — andJsObjectShape.Builder.PerRealmSlot(name, factory)produces exactly such slots, soproto.hasOwnProperty('lazyCtor')on an untouched factory slot would have answeredfalsewhileproto.lazyCtormaterializes fine. The signature now distinguishes the cases (out bool nameDeclared), and only a true index miss may fast-miss; factory declines keep falling through toGetOwnProperty. (TheGlobalObject.AggregateErrorfailure that killed the issue's wide-guard attempt was a factory decline, not an index miss — the 56 lazy intrinsics are generatedFactoryslots.) A mutation check confirms the new tests pin this: reverting the gate to fire on any decline fails bothSharedObjectShapeTestsand the newHostPrototypeShapeTestsfactory-slot fact in Release.Measurements
New
HostPrototypeShapeBenchmarkchain lanes (depth-4 shaped chain, ordinary receiver,in-operator loops; every level's representation asserted inGlobalSetup), default job, idle machine, paired runs:The shaped miss walk goes from +27.6% over dictionary prototypes to parity (+0.6%, CIs touching). The Dictionary row improving too is the derived-flag design's bonus: every miss walk ends at
Object.prototype, which is builtin-shaped and now fast-misses as well.AngleSharp.Js (all DOM prototypes on
JsObjectShape, two independent baseline/fix pairs,LoopOnly-subtracted):NamedIndex(attrs['title'], the WebIDL named-indexer walk) −11.1% / −16.8% across the pairs; every other row within its cross-run noise with sign-flips, andAllocatedbyte-identical on all rows.Validation
Jint.Tests4588/0 (Release and Debug — the Debug run re-verifies every fast miss against the virtualGetOwnPropertyviaAssertBuiltinShapeProbeAgrees, which is wired onto the new return),Jint.Tests.PublicInterface1172/0, Test262 99441/0.🤖 Generated with Claude Code