diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index fd3074d0b0c..649f39cac23 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -8,7 +8,8 @@ #![allow(dead_code)] use core::ffi::c_char; -use std::cell::Cell; +use std::cell::{Cell, LazyCell, RefCell}; +use std::collections::HashSet; use std::ffi::CString; use std::io::{stdout, Write}; use std::ops::Deref; @@ -811,6 +812,10 @@ fn in_range(val: T, min: T, max: T) -> Option { } } +thread_local!(static SEEN_POINTERS: LazyCell>> = const { + LazyCell::new(|| RefCell::new(HashSet::new())) +}); + #[allow(unsafe_code)] unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize { match get_dom_class(obj) { @@ -820,7 +825,13 @@ unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize { if dom_object.is_null() { return 0; } - let mut ops = MallocSizeOfOps::new(servo_allocator::usable_size, None, None); + let seen_pointer = + move |ptr| SEEN_POINTERS.with(|pointers| !pointers.borrow_mut().insert(ptr)); + let mut ops = MallocSizeOfOps::new( + servo_allocator::usable_size, + None, + Some(Box::new(seen_pointer)), + ); (v.malloc_size_of)(&mut ops, dom_object) }, Err(_e) => 0, @@ -946,6 +957,7 @@ impl JSContext { #[allow(unsafe_code)] pub(crate) fn get_reports(&self, path_seg: String) -> Vec { + SEEN_POINTERS.with(|pointers| pointers.borrow_mut().clear()); let stats = unsafe { let mut stats = ::std::mem::zeroed(); if !CollectServoSizes(self.0, &mut stats, Some(get_size)) { diff --git a/components/script/timers.rs b/components/script/timers.rs index 60b079ebcf8..875b037533e 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -22,7 +22,7 @@ use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::DomObject; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::Dom; use crate::dom::bindings::str::DOMString; use crate::dom::document::FakeRequestAnimationFrameCallback; use crate::dom::eventsource::EventSourceTimeoutCallback; @@ -40,8 +40,9 @@ use crate::task_source::SendableTaskSource; pub(crate) struct OneshotTimerHandle(i32); #[derive(DenyPublicFields, JSTraceable, MallocSizeOf)] +#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] pub(crate) struct OneshotTimers { - global_scope: DomRoot, + global_scope: Dom, js_timers: JsTimers, next_timer_handle: Cell, timers: DomRefCell>, @@ -121,7 +122,7 @@ impl PartialEq for OneshotTimer { impl OneshotTimers { pub(crate) fn new(global_scope: &GlobalScope) -> OneshotTimers { OneshotTimers { - global_scope: DomRoot::from_ref(global_scope), + global_scope: Dom::from_ref(global_scope), js_timers: JsTimers::default(), next_timer_handle: Cell::new(OneshotTimerHandle(1)), timers: DomRefCell::new(Vec::new()),