Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog.d/11911-raw-handle-debt-roots.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Rooted the raw-pointer reads that pushed `raw_handle_debt` over its ceiling.
JSON.stringify of a proxy with a function replacer now hands the replacer to
its consumer through the root (`with_const_ptr`) instead of binding a raw
closure pointer, and keeps the replacer result rooted across the key write.
Two test-only reads (private storage cache, eden entry residency) moved into
scoped-pointer closures. The baseline falls from 871 to 869 and
`reflect_support.rs` drops its stale ceiling from 3 to 2.
14 changes: 8 additions & 6 deletions crates/perry-runtime/src/gc/tests/eden_entry_residency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ fn real_full_collection_gives_eden_a_reuse_interval_then_discards_idle_pages() {
);
}
for root in [live, extra_root] {
let string = root.get_raw_const_ptr::<crate::string::StringHeader>();
assert_eq!((*string).byte_len, bytes.len() as u32);
assert_eq!(
std::slice::from_raw_parts(crate::string::string_data(string), bytes.len()),
bytes
);
// The closure only reads the string; nothing here allocates.
root.with_const_ptr(|string: *const crate::string::StringHeader| {
assert_eq!((*string).byte_len, bytes.len() as u32);
assert_eq!(
std::slice::from_raw_parts(crate::string::string_data(string), bytes.len()),
bytes
);
});
}
})
.join()
Expand Down
41 changes: 22 additions & 19 deletions crates/perry-runtime/src/json/stringify_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,22 @@ pub(super) unsafe fn try_stringify(
let member = crate::proxy::js_proxy_get(receiver.get_nanbox_f64(), key.get_nanbox_f64());
let member = super::replacer::apply_to_json_keyed(member, key.get_nanbox_f64());
let member = member_scope.root_nanbox_f64(member);
let replacer = match replacer_root.as_ref() {
Some(root) => Replacer::Function(root.get_raw_const_ptr()),
None => replacer,
};
let member = if let Replacer::Function(f) = replacer {
super::replacer::call_replacer(
f,
key.get_nanbox_f64(),
member.get_nanbox_f64(),
receiver.get_nanbox_f64(),
)
} else {
member.get_nanbox_f64()
let member = match replacer_root.as_ref() {
Some(root) => root.with_const_ptr(|f: *const crate::ClosureHeader| {
super::replacer::call_replacer(
f,
key.get_nanbox_f64(),
member.get_nanbox_f64(),
receiver.get_nanbox_f64(),
)
}),
None => member.get_nanbox_f64(),
};
if !is_array && omitted(member) {
// The replacer result is the value emitted below; keep it rooted across
// the key write and any allocation in the emit.
let member = member_scope.root_nanbox_f64(member);
let member_bits = member.get_nanbox_f64();
if !is_array && omitted(member_bits) {
continue;
}
if !first {
Expand All @@ -141,11 +142,13 @@ pub(super) unsafe fn try_stringify(
buf.push(' ');
}
}
let replacer = match replacer_root.as_ref() {
Some(root) => Replacer::Function(root.get_raw_const_ptr()),
None => replacer,
};
emit_prepared(member, buf, indent, depth + 1, replacer);
let member = member.get_nanbox_f64();
match replacer_root.as_ref() {
Some(root) => root.with_const_ptr(|f: *const crate::ClosureHeader| {
emit_prepared(member, buf, indent, depth + 1, Replacer::Function(f))
}),
None => emit_prepared(member, buf, indent, depth + 1, replacer),
}
}
if !first {
newline(buf, indent, depth);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,13 @@ mod private_storage_cache_tests {
});
let held = scope.root_raw_mut_ptr(crate::object::js_object_alloc(62_641, 0));
let _ = held;
unsafe {
let holder = other.get_raw_mut_ptr::<ObjectHeader>();
// `apply_edits` suppresses moving collection for its whole body.
other.with_mut_ptr(|holder: *mut ObjectHeader| unsafe {
crate::object::key_attrs::apply_edits(
holder,
&[crate::object::key_attrs::AttrsEdit::Private(key.as_bytes())],
);
}
});
assert!(key.set_cached(other_receiver(), 11.0));
assert_eq!(key.get_cached(other_receiver()), Some(11.0));
let first_shape = key.slot.get().unwrap().0;
Expand Down
2 changes: 1 addition & 1 deletion scripts/raw_handle_debt_baseline.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
871
869
2 changes: 1 addition & 1 deletion scripts/raw_handle_debt_files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
4 crates/perry-runtime/src/object/object_ops/from_entries.rs
5 crates/perry-runtime/src/object/object_ops/keys_array.rs
6 crates/perry-runtime/src/object/polymorphic_index.rs
3 crates/perry-runtime/src/object/reflect_support.rs
2 crates/perry-runtime/src/object/reflect_support.rs
2 crates/perry-runtime/src/object/spill.rs
2 crates/perry-runtime/src/object/typed_array_define.rs
3 crates/perry-runtime/src/os.rs
Expand Down
Loading