Skip to content

Commit b35b51b

Browse files
Ralph Küpperproggeramlug
authored andcommitted
fix(train): reconcile #9917's unified test-site record with #9970's gating
#9917 collapses the three RegExp.prototype.test proof slots into one CanonicalTestSite behind a single HotKey, but was written before #9970 gated that surface for the no-default-features product build. Merged so both hold: the unified record, carrying #9970's cfg on the struct, its impl, the thread_local and TEST_ACCESSOR_KEY_BIT. Consequences reconciled: - object_static_prototype_known_non_meta is #9917's, and its only caller is regex-engine gated, so it is dead in a product build. Same gate. - The three _SLOT holder entries added for #9893 are stale: the statics no longer exist. Deleted, and a duplicate TEST_WALKS entry removed. The new REGEXP_PROTOTYPE_TEST_SITE needs no entry — the walk reaches it through scan_canonical_test_site_roots_mut, which scan_object_cache_roots_mut calls and reg_scanner! registers. - segments_view's cursor-number store carried GC_STORE_AUDIT(NUMBER), which is not an accepted class, so the marker never satisfied the gate. POINTER_FREE is the class that states what the comment argues.
1 parent 247316b commit b35b51b

3 files changed

Lines changed: 5 additions & 27 deletions

File tree

crates/perry-runtime/src/intl/segments_view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl CursorFields {
139139
#[inline(always)]
140140
unsafe fn set_number(self, index: u32, value: usize) {
141141
debug_assert!((F_BYTE_START..=F_UTF16_LEN).contains(&index));
142-
// GC_STORE_AUDIT(NUMBER): `JSValue::number` cannot carry a heap edge;
142+
// GC_STORE_AUDIT(POINTER_FREE): `JSValue::number` cannot carry a heap edge;
143143
// `cursor_position_fields_are_never_pointer_typed` pins the invariant
144144
// across every product writer.
145145
self.0

crates/perry-runtime/src/object/prototype_chain.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ pub fn object_static_prototype(obj_ptr: usize) -> Option<u64> {
339339
/// [`object_static_prototype`] remains the entry for unclassified receivers
340340
/// and still checks object-owned metadata before consulting this registry.
341341
#[inline]
342+
// #9917 added this for the recorded canonical-test-site proof, whose only
343+
// caller is regex-engine gated; without the feature it is dead in a product
344+
// build. Same gate as the rest of that surface (#9970).
345+
#[cfg(any(test, feature = "regex-engine"))]
342346
pub(crate) fn object_static_prototype_known_non_meta(obj_ptr: usize) -> Option<u64> {
343347
if !OBJECT_PROTOTYPES_NONEMPTY.load(Ordering::Acquire) {
344348
return None;

scripts/gc_runtime_root_holders.json

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -650,32 +650,6 @@
650650
"verdict": "not_a_gc_pointer",
651651
"why": "Megamorphic property-read stub cache, the read twin of WRITE_STUB: 2-way ways of (shape_token, key_bits, slot) plain u64s. The token is a shape id and the slot an index; key_bits are content-derived by construction, because read_stub_key_bits returns short_ascii_sso_bits(key) \u2014 the key's characters packed inline \u2014 and yields None for any key that would otherwise be stored under a pointer. No way holds a heap address, so nothing here keeps an object alive, and a stale entry cannot hit: receiver_shape_token returns None for a receiver with no live shape, and the token identifies the exact key set and order, so a shape change yields a different token."
652652
},
653-
{
654-
"file": "crates/perry-runtime/src/object/regex_proto_thunks.rs",
655-
"name": "REGEXP_PROTOTYPE_PTR_SLOT",
656-
"verdict": "covered_elsewhere",
657-
"why": "#9893: the realm's `RegExp.prototype` address, recorded so the view mode's canonicality proof is three loads instead of a by-name walk. It IS a root and it IS scanned: `object::scan_object_cache_roots_mut` (registered via `reg_scanner!` in gc/mod.rs) visits it with `visit_atomic_i64_slot` beside the iterator-prototype towers, which marks it and rewrites it when the collector moves the prototype. The walk does not reach it because access goes through the `RealmAtomicI64` wrapper's `with_slot`, not a direct static read.",
658-
"scanner": "object::scan_object_cache_roots_mut (crates/perry-runtime/src/object/mod.rs), registered by reg_scanner! in crates/perry-runtime/src/gc/mod.rs"
659-
},
660-
{
661-
"file": "crates/perry-runtime/src/object/regex_proto_thunks.rs",
662-
"name": "REGEXP_PROTOTYPE_TEST_CLOSURE_SLOT",
663-
"verdict": "covered_elsewhere",
664-
"why": "#9893: the canonical `RegExp.prototype.test` closure, NaN-BOXED rather than a bare address, and visited as such \u2014 `scan_object_cache_roots_mut` uses `visit_atomic_nanbox_u64_slot` so the collector rewrites the pointer inside the word. Same wrapper indirection as `REGEXP_PROTOTYPE_PTR_SLOT` above.",
665-
"scanner": "object::scan_object_cache_roots_mut (crates/perry-runtime/src/object/mod.rs), registered by reg_scanner! in crates/perry-runtime/src/gc/mod.rs"
666-
},
667-
{
668-
"file": "crates/perry-runtime/src/object/regex_proto_thunks.rs",
669-
"name": "REGEXP_PROTOTYPE_TEST_INDEX_SLOT",
670-
"verdict": "not_a_gc_pointer",
671-
"why": "#9893: the field INDEX `test` occupies on the prototype \u2014 a `u32` ordinal, not an address, sentinel `u32::MAX`. Nothing for the collector to mark or rewrite."
672-
},
673-
{
674-
"file": "crates/perry-runtime/src/object/regex_proto_thunks.rs",
675-
"name": "REGEXP_PROTOTYPE_TEST_WALKS",
676-
"verdict": "not_a_gc_pointer",
677-
"why": "#9893: how many by-name canonicality walks this process has done \u2014 a plain `u64` count whose whole purpose is to read 1 per realm and thereby prove the fast path is the path being taken. A NUMBER, never an address."
678-
},
679653
{
680654
"file": "crates/perry-runtime/src/object/shapes.rs",
681655
"name": "SHAPE_YOUNG_LOG_SUPPRESSED",

0 commit comments

Comments
 (0)