diff options
author | Samson <16504129+sagudev@users.noreply.github.com> | 2023-08-04 12:17:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-04 10:17:43 +0000 |
commit | 9514f670d12b4d92514c1402d686e694f3f234a5 (patch) | |
tree | cd847449b332ac27b6018fbe8a83a248af020c5a /components/script | |
parent | 66e0d543cfbaecb08ade2e071d6575f9f72f4dbb (diff) | |
download | servo-9514f670d12b4d92514c1402d686e694f3f234a5.tar.gz servo-9514f670d12b4d92514c1402d686e694f3f234a5.zip |
No tracing of nop traceable fields (#29926)
* Add `no_trace` option to JSTraceable derive
* NoTrace wrapper
* Port some types to no_trace schematics
* Fixing my unsafe mistakes (not tracing traceables)
* Add docs & safety guards for no_trace
Safety guards (trait shenanigans) guarantees safety usage of `no_trace`
* Port canvas_traits to no_trace
* Port servo_media to no_trace
* Port net_traits to no_trace
* Port style to no_trace
* Port webgpu to no_trace
* Port script_traits to no_trace
* Port canvas_traits, devtools_traits, embedder_traits, profile_traits to no_trace
* unrooted_must_root lint in seperate file
* Add trace_in_no_trace_lint as script_plugin
* Composable types in must_not_have_traceable
* Introduced HashMapTracedValues wrapper
* `HashMap<NoTrace<K>,V>`->`HashMapTracedValues<K,V>`
* Port rest of servo's types to no_trace
* Port html5ever, euclid, mime and http to no_trace
* Port remaining externals to no_trace
* Port webxr and Arc<Mutex<_>>
* Fix spelling in notrace doc
Diffstat (limited to 'components/script')
160 files changed, 785 insertions, 638 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 839b7be0169..0a8b713ce9d 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -17,7 +17,8 @@ debugmozjs = ['js/debugmozjs'] jitspew = ['js/jitspew'] profilemozjs = ['js/profilemozjs'] unrooted_must_root_lint = ["script_plugins/unrooted_must_root_lint"] -default = ["unrooted_must_root_lint"] +trace_in_no_trace_lint = ["script_plugins/trace_in_no_trace_lint"] +default = ["unrooted_must_root_lint", "trace_in_no_trace_lint"] webgl_backtrace = ["canvas_traits/webgl_backtrace"] js_backtrace = [] refcell_backtrace = ["accountable-refcell"] diff --git a/components/script/animations.rs b/components/script/animations.rs index 49dfe77e1b4..531d941d6f9 100644 --- a/components/script/animations.rs +++ b/components/script/animations.rs @@ -13,6 +13,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::DOMString; +use crate::dom::bindings::trace::NoTrace; use crate::dom::event::Event; use crate::dom::node::{from_untrusted_node_address, window_from_node, Node, NodeDamage}; use crate::dom::transitionevent::TransitionEvent; @@ -35,13 +36,14 @@ use style::selector_parser::PseudoElement; #[unrooted_must_root_lint::must_root] pub(crate) struct Animations { /// The map of nodes to their animation states. + #[no_trace] pub sets: DocumentAnimationSet, /// Whether or not we have animations that are running. has_running_animations: Cell<bool>, /// A list of nodes with in-progress CSS transitions or pending events. - rooted_nodes: DomRefCell<FxHashMap<OpaqueNode, Dom<Node>>>, + rooted_nodes: DomRefCell<FxHashMap<NoTrace<OpaqueNode>, Dom<Node>>>, /// A list of pending animation-related events. pending_events: DomRefCell<Vec<TransitionOrAnimationEvent>>, @@ -81,7 +83,10 @@ impl Animations { let sets = self.sets.sets.read(); let rooted_nodes = self.rooted_nodes.borrow(); - for node in sets.keys().filter_map(|key| rooted_nodes.get(&key.node)) { + for node in sets + .keys() + .filter_map(|key| rooted_nodes.get(&NoTrace(key.node))) + { node.dirty(NodeDamage::NodeStyleDamaged); } @@ -332,7 +337,7 @@ impl Animations { let mut rooted_nodes = self.rooted_nodes.borrow_mut(); for (key, set) in sets.iter() { let opaque_node = key.node; - if rooted_nodes.contains_key(&opaque_node) { + if rooted_nodes.contains_key(&NoTrace(opaque_node)) { continue; } @@ -342,7 +347,7 @@ impl Animations { let address = UntrustedNodeAddress(opaque_node.0 as *const c_void); unsafe { rooted_nodes.insert( - opaque_node, + NoTrace(opaque_node), Dom::from_ref(&*from_untrusted_node_address(address)), ) }; @@ -355,7 +360,7 @@ impl Animations { let pending_events = self.pending_events.borrow(); let nodes: FxHashSet<OpaqueNode> = sets.keys().map(|key| key.node).collect(); self.rooted_nodes.borrow_mut().retain(|node, _| { - nodes.contains(&node) || pending_events.iter().any(|event| event.node == *node) + nodes.contains(&node.0) || pending_events.iter().any(|event| event.node == node.0) }); } @@ -459,7 +464,7 @@ impl Animations { for event in events.into_iter() { // We root the node here to ensure that sending this event doesn't // unroot it as a side-effect. - let node = match self.rooted_nodes.borrow().get(&event.node) { + let node = match self.rooted_nodes.borrow().get(&NoTrace(event.node)) { Some(node) => DomRoot::from_ref(&**node), None => { warn!("Tried to send an event for an unrooted node"); @@ -569,12 +574,15 @@ impl TransitionOrAnimationEventType { /// A transition or animation event. pub struct TransitionOrAnimationEvent { /// The pipeline id of the layout task that sent this message. + #[no_trace] pub pipeline_id: PipelineId, /// The type of transition event this should trigger. pub event_type: TransitionOrAnimationEventType, /// The address of the node which owns this transition. + #[no_trace] pub node: OpaqueNode, /// The pseudo element for this transition or animation, if applicable. + #[no_trace] pub pseudo_element: Option<PseudoElement>, /// The name of the property that is transitioning (in the case of a transition) /// or the name of the animation (in the case of an animation). diff --git a/components/script/body.rs b/components/script/body.rs index 8ac94d09a1e..baa4011062e 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -281,9 +281,11 @@ impl TransmitBodyConnectHandler { #[derive(Clone, JSTraceable, MallocSizeOf)] struct TransmitBodyPromiseHandler { #[ignore_malloc_size_of = "Channels are hard"] + #[no_trace] bytes_sender: IpcSender<BodyChunkResponse>, stream: DomRoot<ReadableStream>, #[ignore_malloc_size_of = "Channels are hard"] + #[no_trace] control_sender: IpcSender<BodyChunkRequest>, } @@ -328,9 +330,11 @@ impl Callback for TransmitBodyPromiseHandler { #[derive(Clone, JSTraceable, MallocSizeOf)] struct TransmitBodyPromiseRejectionHandler { #[ignore_malloc_size_of = "Channels are hard"] + #[no_trace] bytes_sender: IpcSender<BodyChunkResponse>, stream: DomRoot<ReadableStream>, #[ignore_malloc_size_of = "Channels are hard"] + #[no_trace] control_sender: IpcSender<BodyChunkRequest>, } diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index 3dacd34ec48..fc1eff7df8b 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -61,7 +61,7 @@ use style_traits::values::ToCss; #[derive(Clone, JSTraceable, MallocSizeOf)] #[allow(dead_code)] pub(crate) enum CanvasFillOrStrokeStyle { - Color(RGBA), + Color(#[no_trace] RGBA), Gradient(Dom<CanvasGradient>), Pattern(Dom<CanvasPattern>), } @@ -80,22 +80,31 @@ impl CanvasFillOrStrokeStyle { #[derive(Clone, JSTraceable, MallocSizeOf)] pub(crate) struct CanvasContextState { global_alpha: f64, + #[no_trace] global_composition: CompositionOrBlending, image_smoothing_enabled: bool, fill_style: CanvasFillOrStrokeStyle, stroke_style: CanvasFillOrStrokeStyle, line_width: f64, + #[no_trace] line_cap: LineCapStyle, + #[no_trace] line_join: LineJoinStyle, miter_limit: f64, + #[no_trace] transform: Transform2D<f32>, shadow_offset_x: f64, shadow_offset_y: f64, shadow_blur: f64, + #[no_trace] shadow_color: RGBA, + #[no_trace] font_style: Option<Font>, + #[no_trace] text_align: TextAlign, + #[no_trace] text_baseline: TextBaseline, + #[no_trace] direction: Direction, } @@ -131,17 +140,23 @@ impl CanvasContextState { #[derive(JSTraceable, MallocSizeOf)] pub(crate) struct CanvasState { #[ignore_malloc_size_of = "Defined in ipc-channel"] + #[no_trace] ipc_renderer: IpcSender<CanvasMsg>, + #[no_trace] canvas_id: CanvasId, state: DomRefCell<CanvasContextState>, origin_clean: Cell<bool>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] image_cache: Arc<dyn ImageCache>, /// The base URL for resolving CSS image URL values. /// Needed because of https://github.com/servo/servo/issues/17625 + #[no_trace] base_url: ServoUrl, + #[no_trace] origin: ImmutableOrigin, /// Any missing image URLs. + #[no_trace] missing_image_urls: DomRefCell<Vec<ServoUrl>>, saved_states: DomRefCell<Vec<CanvasContextState>>, } diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs index 9e103b91380..7dc2d6201fb 100644 --- a/components/script/document_loader.rs +++ b/components/script/document_loader.rs @@ -17,11 +17,11 @@ use servo_url::ServoUrl; #[derive(Clone, Debug, JSTraceable, MallocSizeOf, PartialEq)] pub enum LoadType { - Image(ServoUrl), - Script(ServoUrl), - Subframe(ServoUrl), - Stylesheet(ServoUrl), - PageSource(ServoUrl), + Image(#[no_trace] ServoUrl), + Script(#[no_trace] ServoUrl), + Subframe(#[no_trace] ServoUrl), + Stylesheet(#[no_trace] ServoUrl), + PageSource(#[no_trace] ServoUrl), Media, } @@ -66,6 +66,7 @@ impl Drop for LoadBlocker { #[derive(JSTraceable, MallocSizeOf)] pub struct DocumentLoader { + #[no_trace] resource_threads: ResourceThreads, blocking_loads: Vec<LoadType>, events_inhibited: bool, diff --git a/components/script/dom/abstractworkerglobalscope.rs b/components/script/dom/abstractworkerglobalscope.rs index a1cab9aca2d..0bf298e1a4e 100644 --- a/components/script/dom/abstractworkerglobalscope.rs +++ b/components/script/dom/abstractworkerglobalscope.rs @@ -20,6 +20,7 @@ use devtools_traits::DevtoolScriptControlMsg; /// Worker object will remain alive. #[derive(Clone, JSTraceable)] pub struct SendableWorkerScriptChan { + #[no_trace] pub sender: Sender<DedicatedWorkerScriptMsg>, pub worker: TrustedWorkerAddress, } @@ -46,6 +47,7 @@ impl ScriptChan for SendableWorkerScriptChan { /// Worker object will remain alive. #[derive(Clone, JSTraceable)] pub struct WorkerThreadWorkerChan { + #[no_trace] pub sender: Sender<DedicatedWorkerScriptMsg>, pub worker: TrustedWorkerAddress, } diff --git a/components/script/dom/analysernode.rs b/components/script/dom/analysernode.rs index 568d2b120e8..7a83ca0052e 100644 --- a/components/script/dom/analysernode.rs +++ b/components/script/dom/analysernode.rs @@ -31,6 +31,7 @@ use servo_media::audio::node::AudioNodeInit; pub struct AnalyserNode { node: AudioNode, #[ignore_malloc_size_of = "Defined in servo-media"] + #[no_trace] engine: DomRefCell<AnalysisEngine>, } diff --git a/components/script/dom/animationevent.rs b/components/script/dom/animationevent.rs index cde3d466da3..053801631c5 100644 --- a/components/script/dom/animationevent.rs +++ b/components/script/dom/animationevent.rs @@ -20,6 +20,7 @@ use servo_atoms::Atom; #[dom_struct] pub struct AnimationEvent { event: Event, + #[no_trace] animation_name: Atom, elapsed_time: Finite<f32>, pseudo_element: DOMString, diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 9c4b221f6f3..2ad3d60bbbd 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -27,7 +27,9 @@ use style::values::GenericAtomIdent; #[dom_struct] pub struct Attr { node_: Node, + #[no_trace] identifier: AttrIdentifier, + #[no_trace] value: DomRefCell<AttrValue>, /// the element that owns this attribute. diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index bad4bf87141..29623fee6a2 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -50,6 +50,7 @@ pub struct AudioBuffer { /// Aggregates the data from js_channels. /// This is Some<T> iff the buffers in js_channels are detached. #[ignore_malloc_size_of = "servo_media"] + #[no_trace] shared_channels: DomRefCell<Option<ServoMediaAudioBuffer>>, /// https://webaudio.github.io/web-audio-api/#dom-audiobuffer-samplerate sample_rate: f32, diff --git a/components/script/dom/audionode.rs b/components/script/dom/audionode.rs index 841b99d2d8f..5df6d7a76b1 100644 --- a/components/script/dom/audionode.rs +++ b/components/script/dom/audionode.rs @@ -33,6 +33,7 @@ pub const MAX_CHANNEL_COUNT: u32 = 32; pub struct AudioNode { eventtarget: EventTarget, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] node_id: NodeId, context: Dom<BaseAudioContext>, number_of_inputs: u32, diff --git a/components/script/dom/audioparam.rs b/components/script/dom/audioparam.rs index dd0e72f7bcf..99f64d765f6 100644 --- a/components/script/dom/audioparam.rs +++ b/components/script/dom/audioparam.rs @@ -23,8 +23,10 @@ pub struct AudioParam { reflector_: Reflector, context: Dom<BaseAudioContext>, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] node: NodeId, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] param: ParamType, automation_rate: Cell<AutomationRate>, default_value: f32, diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 0b193b25e29..20180d8a939 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -82,6 +82,7 @@ struct DecodeResolver { pub struct BaseAudioContext { eventtarget: EventTarget, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] audio_context_impl: Arc<Mutex<AudioContext>>, /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination destination: MutNullableDom<AudioDestinationNode>, diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 8efa7b09ecf..2eaad330108 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -40,43 +40,11 @@ use crate::dom::gpubuffer::GPUBufferState; use crate::dom::gpucanvascontext::WebGPUContextId; use crate::dom::gpucommandencoder::GPUCommandEncoderState; use crate::dom::htmlimageelement::SourceSet; -use crate::dom::htmlmediaelement::{HTMLMediaElementFetchContext, MediaFrameRenderer}; -use crate::dom::identityhub::Identities; +use crate::dom::htmlmediaelement::HTMLMediaElementFetchContext; use crate::script_runtime::{ContextForRequestInterrupt, StreamConsumer}; use crate::script_thread::IncompleteParserContexts; use crate::task::TaskBox; -use app_units::Au; -use canvas_traits::canvas::{ - CanvasGradientStop, CanvasId, LinearGradientStyle, RadialGradientStyle, -}; -use canvas_traits::canvas::{ - CompositionOrBlending, Direction, LineCapStyle, LineJoinStyle, RepetitionStyle, TextAlign, - TextBaseline, -}; -use canvas_traits::webgl::WebGLVertexArrayId; -use canvas_traits::webgl::{ - ActiveAttribInfo, ActiveUniformBlockInfo, ActiveUniformInfo, GlType, TexDataType, TexFormat, -}; -use canvas_traits::webgl::{GLLimits, WebGLQueryId, WebGLSamplerId}; -use canvas_traits::webgl::{WebGLBufferId, WebGLChan, WebGLContextId, WebGLError}; -use canvas_traits::webgl::{WebGLFramebufferId, WebGLMsgSender, WebGLPipeline, WebGLProgramId}; -use canvas_traits::webgl::{WebGLReceiver, WebGLRenderbufferId, WebGLSLVersion, WebGLSender}; -use canvas_traits::webgl::{WebGLShaderId, WebGLSyncId, WebGLTextureId, WebGLVersion}; -use content_security_policy::CspList; -use crossbeam_channel::{Receiver, Sender}; -use cssparser::RGBA; -use devtools_traits::{CSSError, TimelineMarkerType, WorkerId}; -use embedder_traits::{EventLoopWaker, MediaMetadata}; -use encoding_rs::{Decoder, Encoding}; -use euclid::default::{Point2D, Rect, Rotation3D, Transform2D}; -use euclid::Length as EuclidLength; -use html5ever::buffer_queue::BufferQueue; -use html5ever::{LocalName, Namespace, Prefix, QualName}; -use http::header::HeaderMap; -use http::Method; -use http::StatusCode; use indexmap::IndexMap; -use ipc_channel::ipc::{IpcReceiver, IpcSender}; use js::glue::{CallObjectTracer, CallScriptTracer, CallStringTracer, CallValueTracer}; use js::jsapi::{ GCTraceKindToAscii, Heap, JSObject, JSScript, JSString, JSTracer, JobQueue, TraceKind, @@ -86,56 +54,14 @@ use js::rust::{GCMethods, Handle, Runtime, Stencil}; use js::typedarray::TypedArray; use js::typedarray::TypedArrayElement; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; -use media::WindowGLContext; -use metrics::{InteractiveMetrics, InteractiveWindow}; -use mime::Mime; -use msg::constellation_msg::{ - BlobId, BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId, - MessagePortRouterId, PipelineId, TopLevelBrowsingContextId, -}; -use msg::constellation_msg::{ServiceWorkerId, ServiceWorkerRegistrationId}; -use net_traits::filemanager_thread::RelativePos; -use net_traits::image::base::{Image, ImageMetadata}; -use net_traits::image_cache::{ImageCache, PendingImageId}; -use net_traits::request::{CredentialsMode, ParserMetadata, Referrer, Request, RequestBuilder}; -use net_traits::response::HttpsState; -use net_traits::response::{Response, ResponseBody}; -use net_traits::storage_thread::StorageType; -use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceFetchTiming, ResourceThreads}; -use parking_lot::{Mutex as ParkMutex, RwLock}; -use profile_traits::mem::ProfilerChan as MemProfilerChan; -use profile_traits::time::ProfilerChan as TimeProfilerChan; -use script_layout_interface::message::PendingRestyle; -use script_layout_interface::rpc::LayoutRPC; -use script_layout_interface::StyleAndOpaqueLayoutData; -use script_traits::serializable::BlobImpl; -use script_traits::transferable::MessagePortImpl; -use script_traits::{ - DocumentActivity, DrawAPaintImageResult, MediaSessionActionType, ScriptToConstellationChan, - TimerEventId, TimerSource, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, - WindowSizeType, -}; -use selectors::matching::ElementSelectorFlags; -use serde::{Deserialize, Serialize}; +use parking_lot::RwLock; use servo_arc::Arc as ServoArc; -use servo_atoms::Atom; -use servo_media::audio::analyser_node::AnalysisEngine; -use servo_media::audio::buffer_source_node::AudioBuffer; -use servo_media::audio::context::AudioContext; -use servo_media::audio::graph::NodeId; -use servo_media::audio::panner_node::{DistanceModel, PanningModel}; -use servo_media::audio::param::ParamType; -use servo_media::player::audio::AudioRenderer; -use servo_media::player::video::VideoFrame; -use servo_media::player::Player; -use servo_media::streams::registry::MediaStreamId; -use servo_media::streams::MediaStreamType; -use servo_media::webrtc::WebRtcController; -use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; use std::borrow::Cow; use std::cell::{Cell, RefCell, UnsafeCell}; +use std::collections::hash_map::RandomState; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; +use std::fmt::Display; use std::hash::{BuildHasher, Hash}; use std::mem; use std::num::NonZeroU64; @@ -143,42 +69,16 @@ use std::ops::{Deref, DerefMut, Range}; use std::path::PathBuf; use std::rc::Rc; use std::sync::atomic::{AtomicBool, AtomicUsize}; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::thread::JoinHandle; use std::time::{Instant, SystemTime}; -use style::animation::DocumentAnimationSet; -use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; use style::author_styles::AuthorStyles; -use style::context::QuirksMode; -use style::dom::OpaqueNode; -use style::element_state::*; -use style::media_queries::MediaList; -use style::properties::style_structs::Font; -use style::properties::PropertyDeclarationBlock; -use style::selector_parser::{PseudoElement, Snapshot}; -use style::shared_lock::{Locked as StyleLocked, SharedRwLock as StyleSharedRwLock}; use style::stylesheet_set::{AuthorStylesheetSet, DocumentStylesheetSet}; -use style::stylesheets::keyframes_rule::Keyframe; -use style::stylesheets::{CssRules, FontFaceRule, KeyframesRule, MediaRule, Stylesheet}; -use style::stylesheets::{ImportRule, NamespaceRule, StyleRule, SupportsRule}; -use style::stylist::CascadeData; -use style::values::specified::Length; use tendril::fmt::UTF8; use tendril::stream::LossyDecoder; -use tendril::{StrTendril, TendrilSink}; -use time::{Duration, Timespec, Tm}; -use uuid::Uuid; -use webgpu::{ - wgpu::command::{ComputePass, RenderBundleEncoder, RenderPass}, - WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer, - WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice, - WebGPUPipelineLayout, WebGPUQueue, WebGPURenderBundle, WebGPURenderPipeline, WebGPUSampler, - WebGPUShaderModule, WebGPUTexture, WebGPUTextureView, -}; -use webrender_api::{DocumentId, ExternalImageId, ImageKey}; -use webxr_api::{Finger, Hand, Ray, View}; +use tendril::TendrilSink; +use webxr_api::{Finger, Hand}; -unsafe_no_jsmanaged_fields!(Tm); unsafe_no_jsmanaged_fields!(JoinHandle<()>); /// A trait to allow tracing (only) DOM objects. @@ -187,40 +87,159 @@ pub unsafe trait JSTraceable { unsafe fn trace(&self, trc: *mut JSTracer); } -unsafe_no_jsmanaged_fields!(Box<dyn TaskBox>, Box<dyn EventLoopWaker>); +/// Wrapper type for nop traceble +/// +/// SAFETY: Inner type must not impl JSTraceable +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[trace_in_no_trace_lint::must_not_have_traceable] +pub struct NoTrace<T>(pub T); -unsafe_no_jsmanaged_fields!(IncompleteParserContexts); +impl<T: Display> Display for NoTrace<T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} -unsafe_no_jsmanaged_fields!(MessagePortImpl); -unsafe_no_jsmanaged_fields!(MessagePortId); -unsafe_no_jsmanaged_fields!(MessagePortRouterId); +impl<T> From<T> for NoTrace<T> { + fn from(item: T) -> Self { + Self(item) + } +} -unsafe_no_jsmanaged_fields!(ServiceWorkerId); -unsafe_no_jsmanaged_fields!(ServiceWorkerRegistrationId); +#[allow(unsafe_code)] +unsafe impl<T> JSTraceable for NoTrace<T> { + #[inline] + unsafe fn trace(&self, _: *mut ::js::jsapi::JSTracer) {} +} -unsafe_no_jsmanaged_fields!(BroadcastChannelRouterId); +impl<T: MallocSizeOf> MallocSizeOf for NoTrace<T> { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.0.size_of(ops) + } +} -unsafe_no_jsmanaged_fields!(BlobId); -unsafe_no_jsmanaged_fields!(BlobImpl); +/// HashMap wrapper, that has non-jsmanaged keys +/// +/// Not all methods are reexposed, but you can access inner type via .0 +#[trace_in_no_trace_lint::must_not_have_traceable(0)] +#[derive(Clone, Debug)] +pub struct HashMapTracedValues<K, V, S = RandomState>(pub HashMap<K, V, S>); -unsafe_no_jsmanaged_fields!(CSSError); +impl<K, V, S: Default> Default for HashMapTracedValues<K, V, S> { + fn default() -> Self { + Self(Default::default()) + } +} + +impl<K, V> HashMapTracedValues<K, V, RandomState> { + /// Wrapper for HashMap::new() + #[inline] + #[must_use] + pub fn new() -> HashMapTracedValues<K, V, RandomState> { + Self(HashMap::new()) + } +} -unsafe_no_jsmanaged_fields!(&'static Encoding); +impl<K, V, S> HashMapTracedValues<K, V, S> { + #[inline] + pub fn iter(&self) -> std::collections::hash_map::Iter<'_, K, V> { + self.0.iter() + } -unsafe_no_jsmanaged_fields!(Decoder); + #[inline] + pub fn drain(&mut self) -> std::collections::hash_map::Drain<'_, K, V> { + self.0.drain() + } -unsafe_no_jsmanaged_fields!(Reflector); + #[inline] + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} -unsafe_no_jsmanaged_fields!(Duration); +impl<K, V, S> HashMapTracedValues<K, V, S> +where + K: Eq + Hash, + S: BuildHasher, +{ + #[inline] + pub fn insert(&mut self, k: K, v: V) -> Option<V> { + self.0.insert(k, v) + } -unsafe_no_jsmanaged_fields!(TexDataType, TexFormat); + #[inline] + pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> + where + K: std::borrow::Borrow<Q>, + Q: Hash + Eq, + { + self.0.get(k) + } + + #[inline] + pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> + where + K: std::borrow::Borrow<Q>, + Q: Hash + Eq, + { + self.0.get_mut(k) + } + + #[inline] + pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool + where + K: std::borrow::Borrow<Q>, + Q: Hash + Eq, + { + self.0.contains_key(k) + } + + #[inline] + pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> + where + K: std::borrow::Borrow<Q>, + Q: Hash + Eq, + { + self.0.remove(k) + } + + #[inline] + pub fn entry(&mut self, key: K) -> std::collections::hash_map::Entry<'_, K, V> { + self.0.entry(key) + } +} + +impl<K, V, S> MallocSizeOf for HashMapTracedValues<K, V, S> +where + K: Eq + Hash + MallocSizeOf, + V: MallocSizeOf, + S: BuildHasher, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.0.size_of(ops) + } +} + +#[allow(unsafe_code)] +unsafe impl<K, V: JSTraceable, S> JSTraceable for HashMapTracedValues<K, V, S> { + #[inline] + unsafe fn trace(&self, trc: *mut ::js::jsapi::JSTracer) { + for v in self.0.values() { + v.trace(trc); + } + } +} + +unsafe_no_jsmanaged_fields!(Box<dyn TaskBox>); + +unsafe_no_jsmanaged_fields!(IncompleteParserContexts); + +unsafe_no_jsmanaged_fields!(Reflector); unsafe_no_jsmanaged_fields!(*mut JobQueue); unsafe_no_jsmanaged_fields!(Cow<'static, str>); -unsafe_no_jsmanaged_fields!(CspList); - /// Trace a `JSScript`. pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut JSScript>) { unsafe { @@ -519,164 +538,28 @@ unsafe impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, } } -unsafe_no_jsmanaged_fields!(ActiveAttribInfo); -unsafe_no_jsmanaged_fields!(ActiveUniformInfo); -unsafe_no_jsmanaged_fields!(ActiveUniformBlockInfo); -unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, Uuid, char); +unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, char); unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64); unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); unsafe_no_jsmanaged_fields!(NonZeroU64); unsafe_no_jsmanaged_fields!(Error); -unsafe_no_jsmanaged_fields!(ServoUrl, ImmutableOrigin, MutableOrigin); -unsafe_no_jsmanaged_fields!(Image, ImageMetadata, dyn ImageCache, PendingImageId); -unsafe_no_jsmanaged_fields!(Metadata); -unsafe_no_jsmanaged_fields!(NetworkError); -unsafe_no_jsmanaged_fields!(Atom, Prefix, LocalName, Namespace, QualName); unsafe_no_jsmanaged_fields!(TrustedPromise); -unsafe_no_jsmanaged_fields!(PropertyDeclarationBlock); -unsafe_no_jsmanaged_fields!(Font); -// These three are interdependent, if you plan to put jsmanaged data -// in one of these make sure it is propagated properly to containing structs -unsafe_no_jsmanaged_fields!(DocumentActivity, WindowSizeData, WindowSizeType); -unsafe_no_jsmanaged_fields!( - BrowsingContextId, - HistoryStateId, - PipelineId, - TopLevelBrowsingContextId -); -unsafe_no_jsmanaged_fields!(TimerEventId, TimerSource); -unsafe_no_jsmanaged_fields!(TimelineMarkerType); -unsafe_no_jsmanaged_fields!(WorkerId); -unsafe_no_jsmanaged_fields!(BufferQueue, QuirksMode, StrTendril); + unsafe_no_jsmanaged_fields!(Runtime); unsafe_no_jsmanaged_fields!(ContextForRequestInterrupt); -unsafe_no_jsmanaged_fields!(HeaderMap, Method); unsafe_no_jsmanaged_fields!(WindowProxyHandler); -unsafe_no_jsmanaged_fields!(UntrustedNodeAddress, OpaqueNode); -unsafe_no_jsmanaged_fields!(LengthOrPercentageOrAuto); -unsafe_no_jsmanaged_fields!(RGBA); -unsafe_no_jsmanaged_fields!(StorageType); -unsafe_no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle); -unsafe_no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending); -unsafe_no_jsmanaged_fields!(TextAlign, TextBaseline, Direction); -unsafe_no_jsmanaged_fields!(RepetitionStyle); -unsafe_no_jsmanaged_fields!(WebGLError, GLLimits, GlType); -unsafe_no_jsmanaged_fields!(TimeProfilerChan); -unsafe_no_jsmanaged_fields!(MemProfilerChan); -unsafe_no_jsmanaged_fields!(PseudoElement); -unsafe_no_jsmanaged_fields!(Length); -unsafe_no_jsmanaged_fields!(ElementSelectorFlags); -unsafe_no_jsmanaged_fields!(ElementState); unsafe_no_jsmanaged_fields!(DOMString); -unsafe_no_jsmanaged_fields!(Mime); -unsafe_no_jsmanaged_fields!(AttrIdentifier); -unsafe_no_jsmanaged_fields!(AttrValue); -unsafe_no_jsmanaged_fields!(Snapshot); -unsafe_no_jsmanaged_fields!(PendingRestyle); -unsafe_no_jsmanaged_fields!(Stylesheet); -unsafe_no_jsmanaged_fields!(HttpsState); -unsafe_no_jsmanaged_fields!(Request); -unsafe_no_jsmanaged_fields!(RequestBuilder); -unsafe_no_jsmanaged_fields!(StyleSharedRwLock); unsafe_no_jsmanaged_fields!(USVString); -unsafe_no_jsmanaged_fields!(Referrer); -unsafe_no_jsmanaged_fields!(ReferrerPolicy); -unsafe_no_jsmanaged_fields!(CredentialsMode); -unsafe_no_jsmanaged_fields!(ParserMetadata); -unsafe_no_jsmanaged_fields!(Response); -unsafe_no_jsmanaged_fields!(ResponseBody); -unsafe_no_jsmanaged_fields!(ResourceThreads); -unsafe_no_jsmanaged_fields!(StatusCode); unsafe_no_jsmanaged_fields!(SystemTime); unsafe_no_jsmanaged_fields!(Instant); -unsafe_no_jsmanaged_fields!(RelativePos); -unsafe_no_jsmanaged_fields!(StyleAndOpaqueLayoutData); unsafe_no_jsmanaged_fields!(PathBuf); -unsafe_no_jsmanaged_fields!(DrawAPaintImageResult); -unsafe_no_jsmanaged_fields!(DocumentId); -unsafe_no_jsmanaged_fields!(ImageKey); -unsafe_no_jsmanaged_fields!(ExternalImageId); -unsafe_no_jsmanaged_fields!(WebGLBufferId); -unsafe_no_jsmanaged_fields!(WebGLChan); -unsafe_no_jsmanaged_fields!(WebGLFramebufferId); -unsafe_no_jsmanaged_fields!(WebGLMsgSender); -unsafe_no_jsmanaged_fields!(WebGLPipeline); -unsafe_no_jsmanaged_fields!(WebGLProgramId); -unsafe_no_jsmanaged_fields!(WebGLQueryId); -unsafe_no_jsmanaged_fields!(WebGLRenderbufferId); -unsafe_no_jsmanaged_fields!(WebGLSamplerId); -unsafe_no_jsmanaged_fields!(WebGLShaderId); -unsafe_no_jsmanaged_fields!(WebGLSyncId); -unsafe_no_jsmanaged_fields!(WebGLTextureId); -unsafe_no_jsmanaged_fields!(WebGLVertexArrayId); -unsafe_no_jsmanaged_fields!(WebGLVersion); -unsafe_no_jsmanaged_fields!(WebGLSLVersion); -unsafe_no_jsmanaged_fields!(Arc<ParkMutex<Identities>>); -unsafe_no_jsmanaged_fields!(WebGPU); -unsafe_no_jsmanaged_fields!(WebGPUAdapter); -unsafe_no_jsmanaged_fields!(WebGPUBuffer); -unsafe_no_jsmanaged_fields!(WebGPUBindGroup); -unsafe_no_jsmanaged_fields!(WebGPUBindGroupLayout); -unsafe_no_jsmanaged_fields!(WebGPUComputePipeline); -unsafe_no_jsmanaged_fields!(WebGPURenderPipeline); -unsafe_no_jsmanaged_fields!(WebGPURenderBundle); -unsafe_no_jsmanaged_fields!(WebGPUPipelineLayout); -unsafe_no_jsmanaged_fields!(WebGPUQueue); -unsafe_no_jsmanaged_fields!(WebGPUShaderModule); -unsafe_no_jsmanaged_fields!(WebGPUSampler); -unsafe_no_jsmanaged_fields!(WebGPUTexture); -unsafe_no_jsmanaged_fields!(WebGPUTextureView); unsafe_no_jsmanaged_fields!(WebGPUContextId); -unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer); -unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder); -unsafe_no_jsmanaged_fields!(WebGPUDevice); -unsafe_no_jsmanaged_fields!(Option<RenderPass>); -unsafe_no_jsmanaged_fields!(Option<RenderBundleEncoder>); -unsafe_no_jsmanaged_fields!(Option<ComputePass>); unsafe_no_jsmanaged_fields!(GPUBufferState); unsafe_no_jsmanaged_fields!(GPUCommandEncoderState); unsafe_no_jsmanaged_fields!(Range<u64>); -unsafe_no_jsmanaged_fields!(MediaList); -unsafe_no_jsmanaged_fields!( - webxr_api::Registry, - webxr_api::Session, - webxr_api::Frame, - webxr_api::LayerId, - webxr_api::InputSource, - webxr_api::InputId, - webxr_api::Joint, - webxr_api::HitTestId, - webxr_api::HitTestResult -); -unsafe_no_jsmanaged_fields!(ScriptToConstellationChan); -unsafe_no_jsmanaged_fields!(InteractiveMetrics); -unsafe_no_jsmanaged_fields!(InteractiveWindow); -unsafe_no_jsmanaged_fields!(CanvasId); unsafe_no_jsmanaged_fields!(SourceSet); -unsafe_no_jsmanaged_fields!(AudioBuffer); -unsafe_no_jsmanaged_fields!(Arc<Mutex<AudioContext>>); -unsafe_no_jsmanaged_fields!(NodeId); -unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType); -unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn Player>>); -unsafe_no_jsmanaged_fields!(WebRtcController); -unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType); -unsafe_no_jsmanaged_fields!(Mutex<MediaFrameRenderer>); -unsafe_no_jsmanaged_fields!(ResourceFetchTiming); -unsafe_no_jsmanaged_fields!(Timespec); unsafe_no_jsmanaged_fields!(HTMLMediaElementFetchContext); -unsafe_no_jsmanaged_fields!(Rotation3D<f64>, Transform2D<f32>); -unsafe_no_jsmanaged_fields!(Point2D<f32>, Rect<Au>); -unsafe_no_jsmanaged_fields!(Rect<f32>); -unsafe_no_jsmanaged_fields!(CascadeData); -unsafe_no_jsmanaged_fields!(WindowGLContext); -unsafe_no_jsmanaged_fields!(VideoFrame); -unsafe_no_jsmanaged_fields!(WebGLContextId); -unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn AudioRenderer>>); -unsafe_no_jsmanaged_fields!(MediaSessionActionType); -unsafe_no_jsmanaged_fields!(MediaMetadata); -unsafe_no_jsmanaged_fields!(WebrenderIpcSender); unsafe_no_jsmanaged_fields!(StreamConsumer); -unsafe_no_jsmanaged_fields!(DocumentAnimationSet); unsafe_no_jsmanaged_fields!(Stencil); unsafe impl<'a> JSTraceable for &'a str { @@ -693,24 +576,6 @@ unsafe impl<A, B> JSTraceable for fn(A) -> B { } } -unsafe impl<T> JSTraceable for IpcSender<T> -where - T: for<'de> Deserialize<'de> + Serialize, -{ - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - -// Safe thanks to the Send bound. -unsafe impl JSTraceable for Box<dyn LayoutRPC + Send + 'static> { - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - unsafe impl JSTraceable for () { #[inline] unsafe fn trace(&self, _: *mut JSTracer) { @@ -718,16 +583,6 @@ unsafe impl JSTraceable for () { } } -unsafe impl<T> JSTraceable for IpcReceiver<T> -where - T: for<'de> Deserialize<'de> + Serialize, -{ - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - unsafe impl<T: DomObject> JSTraceable for Trusted<T> { #[inline] unsafe fn trace(&self, _: *mut JSTracer) { @@ -735,197 +590,6 @@ unsafe impl<T: DomObject> JSTraceable for Trusted<T> { } } -unsafe impl<T: Send> JSTraceable for Receiver<T> { - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T: Send> JSTraceable for Sender<T> { - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T: Send> JSTraceable for WebGLReceiver<T> -where - T: for<'de> Deserialize<'de> + Serialize, -{ - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T: Send> JSTraceable for WebGLSender<T> -where - T: for<'de> Deserialize<'de> + Serialize, -{ - #[inline] - unsafe fn trace(&self, _: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<U> JSTraceable for euclid::Vector2D<f32, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T, U> JSTraceable for euclid::Scale<f32, T, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T, U> JSTraceable for euclid::RigidTransform3D<f32, T, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T, U> JSTraceable for euclid::RigidTransform3D<f64, T, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T, U> JSTraceable for euclid::Transform3D<f32, T, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T, U> JSTraceable for euclid::Transform3D<f64, T, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<T> JSTraceable for EuclidLength<u64, T> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<U> JSTraceable for euclid::Size2D<i32, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<U> JSTraceable for euclid::Size2D<f32, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<U> JSTraceable for euclid::Size2D<u32, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<U> JSTraceable for euclid::Rect<i32, U> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<Space> JSTraceable for Ray<Space> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl<Eye> JSTraceable for View<Eye> { - #[inline] - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing - } -} - -unsafe impl JSTraceable for StyleLocked<FontFaceRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<CssRules> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<Keyframe> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<KeyframesRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<ImportRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<SupportsRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<MediaRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<NamespaceRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<StyleRule> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<PropertyDeclarationBlock> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - -unsafe impl JSTraceable for StyleLocked<MediaList> { - unsafe fn trace(&self, _trc: *mut JSTracer) { - // Do nothing. - } -} - unsafe impl<T> JSTraceable for TypedArray<T, Box<Heap<*mut JSObject>>> where T: TypedArrayElement, diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index b2127f071a0..a6599d3ac99 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -34,6 +34,7 @@ use uuid::Uuid; #[dom_struct] pub struct Blob { reflector_: Reflector, + #[no_trace] blob_id: BlobId, } diff --git a/components/script/dom/broadcastchannel.rs b/components/script/dom/broadcastchannel.rs index 458ed299e85..dd5149c1203 100644 --- a/components/script/dom/broadcastchannel.rs +++ b/components/script/dom/broadcastchannel.rs @@ -22,6 +22,7 @@ pub struct BroadcastChannel { eventtarget: EventTarget, name: DOMString, closed: Cell<bool>, + #[no_trace] id: Uuid, } diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index 3671df678af..e404998b004 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -22,13 +22,14 @@ use dom_struct::dom_struct; pub struct CanvasGradient { reflector_: Reflector, style: CanvasGradientStyle, + #[no_trace] stops: DomRefCell<Vec<CanvasGradientStop>>, } #[derive(Clone, JSTraceable, MallocSizeOf)] pub enum CanvasGradientStyle { - Linear(LinearGradientStyle), - Radial(RadialGradientStyle), + Linear(#[no_trace] LinearGradientStyle), + Radial(#[no_trace] RadialGradientStyle), } impl CanvasGradient { diff --git a/components/script/dom/canvaspattern.rs b/components/script/dom/canvaspattern.rs index 3557f646ab9..5472598ea28 100644 --- a/components/script/dom/canvaspattern.rs +++ b/components/script/dom/canvaspattern.rs @@ -15,6 +15,7 @@ use euclid::default::Size2D; pub struct CanvasPattern { reflector_: Reflector, surface_data: Vec<u8>, + #[no_trace] surface_size: Size2D<u32>, repeat_x: bool, repeat_y: bool, diff --git a/components/script/dom/client.rs b/components/script/dom/client.rs index 2768ee7c9ba..178f6bfba8c 100644 --- a/components/script/dom/client.rs +++ b/components/script/dom/client.rs @@ -18,9 +18,11 @@ use uuid::Uuid; pub struct Client { reflector_: Reflector, active_worker: MutNullableDom<ServiceWorker>, + #[no_trace] url: ServoUrl, frame_type: FrameType, #[ignore_malloc_size_of = "Defined in uuid"] + #[no_trace] id: Uuid, } diff --git a/components/script/dom/cssfontfacerule.rs b/components/script/dom/cssfontfacerule.rs index 8e2349a0429..679ec525383 100644 --- a/components/script/dom/cssfontfacerule.rs +++ b/components/script/dom/cssfontfacerule.rs @@ -17,6 +17,7 @@ use style::stylesheets::FontFaceRule; pub struct CSSFontFaceRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] fontfacerule: Arc<Locked<FontFaceRule>>, } diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs index af0b969058c..f89f58126de 100644 --- a/components/script/dom/cssgroupingrule.rs +++ b/components/script/dom/cssgroupingrule.rs @@ -20,6 +20,7 @@ use style::stylesheets::CssRules as StyleCssRules; pub struct CSSGroupingRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] rules: Arc<Locked<StyleCssRules>>, rulelist: MutNullableDom<CSSRuleList>, } diff --git a/components/script/dom/cssimportrule.rs b/components/script/dom/cssimportrule.rs index 52fbe62c2bd..e2da2a04378 100644 --- a/components/script/dom/cssimportrule.rs +++ b/components/script/dom/cssimportrule.rs @@ -17,6 +17,7 @@ use style::stylesheets::ImportRule; pub struct CSSImportRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] import_rule: Arc<Locked<ImportRule>>, } diff --git a/components/script/dom/csskeyframerule.rs b/components/script/dom/csskeyframerule.rs index 281fc4b8e5e..9ab465e79a4 100644 --- a/components/script/dom/csskeyframerule.rs +++ b/components/script/dom/csskeyframerule.rs @@ -20,6 +20,7 @@ use style::stylesheets::keyframes_rule::Keyframe; pub struct CSSKeyframeRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] keyframerule: Arc<Locked<Keyframe>>, style_decl: MutNullableDom<CSSStyleDeclaration>, } diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index aa2be337022..52a25a52dd0 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -24,6 +24,7 @@ use style::values::KeyframesName; pub struct CSSKeyframesRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] keyframesrule: Arc<Locked<KeyframesRule>>, rulelist: MutNullableDom<CSSRuleList>, } diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index ca2bdd4d447..cc18fc46797 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -25,6 +25,7 @@ use style_traits::{ParsingMode, ToCss}; pub struct CSSMediaRule { cssconditionrule: CSSConditionRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] mediarule: Arc<Locked<MediaRule>>, medialist: MutNullableDom<MediaList>, } diff --git a/components/script/dom/cssnamespacerule.rs b/components/script/dom/cssnamespacerule.rs index 3a15c7d5ffd..d03da04b116 100644 --- a/components/script/dom/cssnamespacerule.rs +++ b/components/script/dom/cssnamespacerule.rs @@ -18,6 +18,7 @@ use style::stylesheets::NamespaceRule; pub struct CSSNamespaceRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] namespacerule: Arc<Locked<NamespaceRule>>, } diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 41101afd625..a2cc459d94c 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -34,6 +34,7 @@ pub struct CSSStyleDeclaration { reflector_: Reflector, owner: CSSStyleOwner, readonly: bool, + #[no_trace] pseudo: Option<PseudoElement>, } @@ -43,7 +44,9 @@ pub enum CSSStyleOwner { Element(Dom<Element>), CSSRule( Dom<CSSRule>, - #[ignore_malloc_size_of = "Arc"] Arc<Locked<PropertyDeclarationBlock>>, + #[ignore_malloc_size_of = "Arc"] + #[no_trace] + Arc<Locked<PropertyDeclarationBlock>>, ), } diff --git a/components/script/dom/cssstylerule.rs b/components/script/dom/cssstylerule.rs index f81f30ab258..007a98a7592 100644 --- a/components/script/dom/cssstylerule.rs +++ b/components/script/dom/cssstylerule.rs @@ -26,6 +26,7 @@ use style::stylesheets::{Origin, StyleRule}; pub struct CSSStyleRule { cssrule: CSSRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] stylerule: Arc<Locked<StyleRule>>, style_decl: MutNullableDom<CSSStyleDeclaration>, } diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index dda321be153..e8de2ef3add 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -26,6 +26,7 @@ pub struct CSSStyleSheet { owner: MutNullableDom<Element>, rulelist: MutNullableDom<CSSRuleList>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] style_stylesheet: Arc<StyleStyleSheet>, origin_clean: Cell<bool>, } diff --git a/components/script/dom/csssupportsrule.rs b/components/script/dom/csssupportsrule.rs index 8a028e9efb2..0eaa1f9d53a 100644 --- a/components/script/dom/csssupportsrule.rs +++ b/components/script/dom/csssupportsrule.rs @@ -23,6 +23,7 @@ use style_traits::{ParsingMode, ToCss}; pub struct CSSSupportsRule { cssconditionrule: CSSConditionRule, #[ignore_malloc_size_of = "Arc"] + #[no_trace] supportsrule: Arc<Locked<SupportsRule>>, } diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index 153b1d206fc..df458ec90c3 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -43,12 +43,14 @@ use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue}; use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue}; use js::rust::{HandleObject, HandleValue, MutableHandleValue}; use std::cell::Cell; -use std::collections::{HashMap, VecDeque}; +use std::collections::VecDeque; use std::mem; use std::ops::Deref; use std::ptr; use std::rc::Rc; +use super::bindings::trace::HashMapTracedValues; + /// <https://dom.spec.whatwg.org/#concept-element-custom-element-state> #[derive(Clone, Copy, Eq, JSTraceable, MallocSizeOf, PartialEq)] pub enum CustomElementState { @@ -72,12 +74,12 @@ pub struct CustomElementRegistry { window: Dom<Window>, #[ignore_malloc_size_of = "Rc"] - when_defined: DomRefCell<HashMap<LocalName, Rc<Promise>>>, + when_defined: DomRefCell<HashMapTracedValues<LocalName, Rc<Promise>>>, element_definition_is_running: Cell<bool>, #[ignore_malloc_size_of = "Rc"] - definitions: DomRefCell<HashMap<LocalName, Rc<CustomElementDefinition>>>, + definitions: DomRefCell<HashMapTracedValues<LocalName, Rc<CustomElementDefinition>>>, } impl CustomElementRegistry { @@ -85,9 +87,9 @@ impl CustomElementRegistry { CustomElementRegistry { reflector_: Reflector::new(), window: Dom::from_ref(window), - when_defined: DomRefCell::new(HashMap::new()), + when_defined: DomRefCell::new(HashMapTracedValues::new()), element_definition_is_running: Cell::new(false), - definitions: DomRefCell::new(HashMap::new()), + definitions: DomRefCell::new(HashMapTracedValues::new()), } } @@ -101,7 +103,7 @@ impl CustomElementRegistry { /// Cleans up any active promises /// <https://github.com/servo/servo/issues/15318> pub fn teardown(&self) { - self.when_defined.borrow_mut().clear() + self.when_defined.borrow_mut().0.clear() } /// <https://html.spec.whatwg.org/multipage/#look-up-a-custom-element-definition> @@ -112,6 +114,7 @@ impl CustomElementRegistry { ) -> Option<Rc<CustomElementDefinition>> { self.definitions .borrow() + .0 .values() .find(|definition| { // Step 4-5 @@ -127,6 +130,7 @@ impl CustomElementRegistry { ) -> Option<Rc<CustomElementDefinition>> { self.definitions .borrow() + .0 .values() .find(|definition| definition.constructor.callback() == constructor.get()) .cloned() @@ -497,8 +501,10 @@ pub enum ConstructionStackEntry { /// <https://html.spec.whatwg.org/multipage/#custom-element-definition> #[derive(Clone, JSTraceable, MallocSizeOf)] pub struct CustomElementDefinition { + #[no_trace] pub name: LocalName, + #[no_trace] pub local_name: LocalName, #[ignore_malloc_size_of = "Rc"] diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index acd2942b1a8..956634856ce 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -182,6 +182,7 @@ pub struct DedicatedWorkerGlobalScope { #[ignore_malloc_size_of = "Defined in std"] task_queue: TaskQueue<DedicatedWorkerScriptMsg>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] own_sender: Sender<DedicatedWorkerScriptMsg>, #[ignore_malloc_size_of = "Trusted<T> has unclear ownership like Dom<T>"] worker: DomRefCell<Option<TrustedWorkerAddress>>, @@ -189,11 +190,14 @@ pub struct DedicatedWorkerGlobalScope { /// Sender to the parent thread. parent_sender: Box<dyn ScriptChan + Send>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] image_cache: Arc<dyn ImageCache>, + #[no_trace] browsing_context: Option<BrowsingContextId>, /// A receiver of control messages, /// currently only used to signal shutdown. #[ignore_malloc_size_of = "Channels are hard"] + #[no_trace] control_receiver: Receiver<DedicatedWorkerControlMsg>, } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d816428684b..aa7a2057503 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -176,6 +176,8 @@ use url::Host; use uuid::Uuid; use webrender_api::units::DeviceIntRect; +use super::bindings::trace::{HashMapTracedValues, NoTrace}; + /// The number of times we are allowed to see spurious `requestAnimationFrame()` calls before /// falling back to fake ones. /// @@ -235,21 +237,26 @@ pub struct Document { window: Dom<Window>, implementation: MutNullableDom<DOMImplementation>, #[ignore_malloc_size_of = "type from external crate"] + #[no_trace] content_type: Mime, last_modified: Option<String>, + #[no_trace] encoding: Cell<&'static Encoding>, has_browsing_context: bool, is_html_document: bool, + #[no_trace] activity: Cell<DocumentActivity>, + #[no_trace] url: DomRefCell<ServoUrl>, #[ignore_malloc_size_of = "defined in selectors"] + #[no_trace] quirks_mode: Cell<QuirksMode>, /// Caches for the getElement methods - id_map: DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, - name_map: DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, - tag_map: DomRefCell<HashMap<LocalName, Dom<HTMLCollection>>>, - tagns_map: DomRefCell<HashMap<QualName, Dom<HTMLCollection>>>, - classes_map: DomRefCell<HashMap<Vec<Atom>, Dom<HTMLCollection>>>, + id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, + name_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, + tag_map: DomRefCell<HashMapTracedValues<LocalName, Dom<HTMLCollection>>>, + tagns_map: DomRefCell<HashMapTracedValues<QualName, Dom<HTMLCollection>>>, + classes_map: DomRefCell<HashMapTracedValues<Vec<Atom>, Dom<HTMLCollection>>>, images: MutNullableDom<HTMLCollection>, embeds: MutNullableDom<HTMLCollection>, links: MutNullableDom<HTMLCollection>, @@ -259,6 +266,7 @@ pub struct Document { applets: MutNullableDom<HTMLCollection>, /// Lock use for style attributes and author-origin stylesheet objects in this document. /// Can be acquired once for accessing many objects. + #[no_trace] style_shared_lock: StyleSharedRwLock, /// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed. stylesheets: DomRefCell<DocumentStylesheetSet<StyleSheetInDocument>>, @@ -309,7 +317,7 @@ pub struct Document { appropriate_template_contents_owner_document: MutNullableDom<Document>, /// Information on elements needing restyle to ship over to the layout thread when the /// time comes. - pending_restyles: DomRefCell<HashMap<Dom<Element>, PendingRestyle>>, + pending_restyles: DomRefCell<HashMap<Dom<Element>, NoTrace<PendingRestyle>>>, /// This flag will be true if layout suppressed a reflow attempt that was /// needed in order for the page to be painted. needs_paint: Cell<bool>, @@ -328,10 +336,13 @@ pub struct Document { unload_event_start: Cell<u64>, unload_event_end: Cell<u64>, /// <https://html.spec.whatwg.org/multipage/#concept-document-https-state> + #[no_trace] https_state: Cell<HttpsState>, /// The document's origin. + #[no_trace] origin: MutableOrigin, /// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states + #[no_trace] referrer_policy: Cell<Option<ReferrerPolicy>>, /// <https://html.spec.whatwg.org/multipage/#dom-document-referrer> referrer: Option<String>, @@ -339,6 +350,7 @@ pub struct Document { target_element: MutNullableDom<Element>, /// <https://w3c.github.io/uievents/#event-type-dblclick> #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] last_click_info: DomRefCell<Option<(Instant, Point2D<f32>)>>, /// <https://html.spec.whatwg.org/multipage/#ignore-destructive-writes-counter> ignore_destructive_writes_counter: Cell<u32>, @@ -362,8 +374,10 @@ pub struct Document { /// whenever any element with the same ID as the form attribute /// is inserted or removed from the document. /// See https://html.spec.whatwg.org/multipage/#form-owner - form_id_listener_map: DomRefCell<HashMap<Atom, HashSet<Dom<Element>>>>, + form_id_listener_map: DomRefCell<HashMapTracedValues<Atom, HashSet<Dom<Element>>>>, + #[no_trace] interactive_time: DomRefCell<InteractiveMetrics>, + #[no_trace] tti_window: DomRefCell<InteractiveWindow>, /// RAII canceller for Fetch canceller: FetchCanceller, @@ -399,11 +413,13 @@ pub struct Document { /// hosting the media controls UI. media_controls: DomRefCell<HashMap<String, Dom<ShadowRoot>>>, /// List of all WebGL context IDs that need flushing. - dirty_webgl_contexts: DomRefCell<HashMap<WebGLContextId, Dom<WebGLRenderingContext>>>, + dirty_webgl_contexts: + DomRefCell<HashMapTracedValues<WebGLContextId, Dom<WebGLRenderingContext>>>, /// List of all WebGPU context IDs that need flushing. dirty_webgpu_contexts: DomRefCell<HashMap<WebGPUContextId, Dom<GPUCanvasContext>>>, /// https://html.spec.whatwg.org/multipage/#concept-document-csp-list #[ignore_malloc_size_of = "Defined in rust-content-security-policy"] + #[no_trace] csp_list: DomRefCell<Option<CspList>>, /// https://w3c.github.io/slection-api/#dfn-selection selection: MutNullableDom<Selection>, @@ -2865,11 +2881,11 @@ impl Document { .for_each(|(_, context)| context.send_swap_chain_present()); } - pub fn id_map(&self) -> Ref<HashMap<Atom, Vec<Dom<Element>>>> { + pub fn id_map(&self) -> Ref<HashMapTracedValues<Atom, Vec<Dom<Element>>>> { self.id_map.borrow() } - pub fn name_map(&self) -> Ref<HashMap<Atom, Vec<Dom<Element>>>> { + pub fn name_map(&self) -> Ref<HashMapTracedValues<Atom, Vec<Dom<Element>>>> { self.name_map.borrow() } } @@ -3071,15 +3087,15 @@ impl Document { url: DomRefCell::new(url), // https://dom.spec.whatwg.org/#concept-document-quirks quirks_mode: Cell::new(QuirksMode::NoQuirks), - id_map: DomRefCell::new(HashMap::new()), - name_map: DomRefCell::new(HashMap::new()), + id_map: DomRefCell::new(HashMapTracedValues::new()), + name_map: DomRefCell::new(HashMapTracedValues::new()), // https://dom.spec.whatwg.org/#concept-document-encoding encoding: Cell::new(encoding), is_html_document: is_html_document == IsHTMLDocument::HTMLDocument, activity: Cell::new(activity), - tag_map: DomRefCell::new(HashMap::new()), - tagns_map: DomRefCell::new(HashMap::new()), - classes_map: DomRefCell::new(HashMap::new()), + tag_map: DomRefCell::new(HashMapTracedValues::new()), + tagns_map: DomRefCell::new(HashMapTracedValues::new()), + classes_map: DomRefCell::new(HashMapTracedValues::new()), images: Default::default(), embeds: Default::default(), links: Default::default(), @@ -3164,7 +3180,7 @@ impl Document { shadow_roots: DomRefCell::new(HashSet::new()), shadow_roots_styles_changed: Cell::new(false), media_controls: DomRefCell::new(HashMap::new()), - dirty_webgl_contexts: DomRefCell::new(HashMap::new()), + dirty_webgl_contexts: DomRefCell::new(HashMapTracedValues::new()), dirty_webgpu_contexts: DomRefCell::new(HashMap::new()), csp_list: DomRefCell::new(None), selection: MutNullableDom::new(None), @@ -3494,8 +3510,10 @@ impl Document { pub fn ensure_pending_restyle(&self, el: &Element) -> RefMut<PendingRestyle> { let map = self.pending_restyles.borrow_mut(); RefMut::map(map, |m| { - m.entry(Dom::from_ref(el)) - .or_insert_with(PendingRestyle::new) + &mut m + .entry(Dom::from_ref(el)) + .or_insert_with(|| NoTrace(PendingRestyle::new())) + .0 }) } @@ -3864,7 +3882,7 @@ impl Document { return None; } node.note_dirty_descendants(); - Some((node.to_trusted_node_address(), restyle)) + Some((node.to_trusted_node_address(), restyle.0)) }) .collect() } @@ -4838,6 +4856,7 @@ impl DocumentMethods for Document { // Step 4. #[derive(JSTraceable, MallocSizeOf)] struct DocumentNamedGetter { + #[no_trace] name: Atom, } impl CollectionFilter for DocumentNamedGetter { @@ -4878,7 +4897,7 @@ impl DocumentMethods for Document { let mut names_with_first_named_element_map: HashMap<&Atom, &Element> = HashMap::new(); let name_map = self.name_map.borrow(); - for (name, elements) in &*name_map { + for (name, elements) in &(*name_map).0 { if name.is_empty() { continue; } @@ -4890,7 +4909,7 @@ impl DocumentMethods for Document { } } let id_map = self.id_map.borrow(); - for (id, elements) in &*id_map { + for (id, elements) in &(*id_map).0 { if id.is_empty() { continue; } @@ -5367,6 +5386,7 @@ impl PendingInOrderScriptVec { #[unrooted_must_root_lint::must_root] struct PendingScript { element: Dom<HTMLScriptElement>, + // TODO(sagudev): could this be all no_trace? load: Option<ScriptResult>, } diff --git a/components/script/dom/documentfragment.rs b/components/script/dom/documentfragment.rs index 8f35a0d8781..f2455f61130 100644 --- a/components/script/dom/documentfragment.rs +++ b/components/script/dom/documentfragment.rs @@ -19,14 +19,15 @@ use crate::dom::window::Window; use dom_struct::dom_struct; use js::rust::HandleObject; use servo_atoms::Atom; -use std::collections::HashMap; + +use super::bindings::trace::HashMapTracedValues; // https://dom.spec.whatwg.org/#documentfragment #[dom_struct] pub struct DocumentFragment { node: Node, /// Caches for the getElement methods - id_map: DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, + id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, } impl DocumentFragment { @@ -34,7 +35,7 @@ impl DocumentFragment { pub fn new_inherited(document: &Document) -> DocumentFragment { DocumentFragment { node: Node::new_inherited(document), - id_map: DomRefCell::new(HashMap::new()), + id_map: DomRefCell::new(HashMapTracedValues::new()), } } @@ -63,7 +64,7 @@ impl DocumentFragment { Ok(DocumentFragment::new_with_proto(&document, proto)) } - pub fn id_map(&self) -> &DomRefCell<HashMap<Atom, Vec<Dom<Element>>>> { + pub fn id_map(&self) -> &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>> { &self.id_map } } diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 5ed1e19f0ab..14e4774c55b 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -17,17 +17,19 @@ use script_layout_interface::message::{NodesFromPointQueryType, QueryMsg}; use script_traits::UntrustedNodeAddress; use servo_arc::Arc; use servo_atoms::Atom; -use std::collections::HashMap; use std::fmt; use style::invalidation::media_queries::{MediaListKey, ToMediaListKey}; use style::media_queries::MediaList; use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard}; use style::stylesheets::{Stylesheet, StylesheetContents}; +use super::bindings::trace::HashMapTracedValues; + #[derive(Clone, JSTraceable, MallocSizeOf)] #[unrooted_must_root_lint::must_root] pub struct StyleSheetInDocument { #[ignore_malloc_size_of = "Arc"] + #[no_trace] pub sheet: Arc<Stylesheet>, pub owner: Dom<Element>, } @@ -247,7 +249,7 @@ impl DocumentOrShadowRoot { /// Remove any existing association between the provided id/name and any elements in this document. pub fn unregister_named_element( &self, - id_map: &DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, + id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, to_unregister: &Element, id: &Atom, ) { @@ -275,7 +277,7 @@ impl DocumentOrShadowRoot { /// Associate an element present in this document with the provided id/name. pub fn register_named_element( &self, - id_map: &DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, + id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, element: &Element, id: &Atom, root: DomRoot<Node>, diff --git a/components/script/dom/dommatrixreadonly.rs b/components/script/dom/dommatrixreadonly.rs index cd0cdb058a1..f6cc458b618 100644 --- a/components/script/dom/dommatrixreadonly.rs +++ b/components/script/dom/dommatrixreadonly.rs @@ -34,6 +34,7 @@ use style::parser::ParserContext; #[allow(non_snake_case)] pub struct DOMMatrixReadOnly { reflector_: Reflector, + #[no_trace] matrix: DomRefCell<Transform3D<f64>>, is2D: Cell<bool>, } diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs index 70b306d223b..1e01cea8070 100644 --- a/components/script/dom/domtokenlist.rs +++ b/components/script/dom/domtokenlist.rs @@ -19,7 +19,9 @@ use style::str::HTML_SPACE_CHARACTERS; pub struct DOMTokenList { reflector_: Reflector, element: Dom<Element>, + #[no_trace] local_name: LocalName, + #[no_trace] supported_tokens: Option<Vec<Atom>>, } diff --git a/components/script/dom/dynamicmoduleowner.rs b/components/script/dom/dynamicmoduleowner.rs index 50fc71fbd79..67f83442d8f 100644 --- a/components/script/dom/dynamicmoduleowner.rs +++ b/components/script/dom/dynamicmoduleowner.rs @@ -13,7 +13,7 @@ use uuid::Uuid; /// An unique id for dynamic module #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)] -pub struct DynamicModuleId(pub Uuid); +pub struct DynamicModuleId(#[no_trace] pub Uuid); #[dom_struct] pub struct DynamicModuleOwner { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 7408147893f..3304e23cb64 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -149,23 +149,31 @@ use xml5ever::serialize::TraversalScope::IncludeNode as XmlIncludeNode; #[dom_struct] pub struct Element { node: Node, + #[no_trace] local_name: LocalName, tag_name: TagName, + #[no_trace] namespace: Namespace, + #[no_trace] prefix: DomRefCell<Option<Prefix>>, attrs: DomRefCell<Vec<Dom<Attr>>>, + #[no_trace] id_attribute: DomRefCell<Option<Atom>>, + #[no_trace] is: DomRefCell<Option<LocalName>>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] style_attribute: DomRefCell<Option<Arc<Locked<PropertyDeclarationBlock>>>>, attr_list: MutNullableDom<NamedNodeMap>, class_list: MutNullableDom<DOMTokenList>, + #[no_trace] state: Cell<ElementState>, /// These flags are set by the style system to indicate the that certain /// operations may require restyling this element or its descendants. The /// flags are not atomic, so the style system takes care of only set them /// when it has exclusive access to the element. #[ignore_malloc_size_of = "bitflags defined in rust-selectors"] + #[no_trace] selector_flags: Cell<ElementSelectorFlags>, rare_data: DomRefCell<Option<Box<ElementRareData>>>, } @@ -3673,6 +3681,7 @@ impl<'a> AttributeMutation<'a> { /// owner changes. #[derive(JSTraceable, MallocSizeOf)] struct TagName { + #[no_trace] ptr: DomRefCell<Option<LocalName>>, } diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index c5a5835521f..78a409ce507 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -39,6 +39,7 @@ pub struct Event { reflector_: Reflector, current_target: MutNullableDom<EventTarget>, target: MutNullableDom<EventTarget>, + #[no_trace] type_: DomRefCell<Atom>, phase: Cell<EventPhase>, canceled: Cell<EventDefault>, diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index f451545f491..57d8a84df8b 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -60,7 +60,9 @@ enum ReadyState { #[dom_struct] pub struct EventSource { eventtarget: EventTarget, + #[no_trace] url: ServoUrl, + #[no_trace] request: DomRefCell<Option<RequestBuilder>>, last_event_id: DomRefCell<DOMString>, reconnection_time: Cell<u64>, @@ -647,6 +649,7 @@ pub struct EventSourceTimeoutCallback { #[ignore_malloc_size_of = "Because it is non-owning"] event_source: Trusted<EventSource>, #[ignore_malloc_size_of = "Because it is non-owning"] + #[no_trace] action_sender: ipc::IpcSender<FetchResponseMsg>, } diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 919cf43b4fc..dde317955cc 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -44,7 +44,6 @@ use libc::c_char; use servo_atoms::Atom; use servo_url::ServoUrl; use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::collections::HashMap; use std::default::Default; use std::ffi::CString; use std::hash::BuildHasherDefault; @@ -52,6 +51,8 @@ use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::Rc; +use super::bindings::trace::HashMapTracedValues; + #[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)] pub enum CommonEventHandler { EventHandler(#[ignore_malloc_size_of = "Rc"] Rc<EventHandlerNonNull>), @@ -81,6 +82,7 @@ pub enum ListenerPhase { #[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)] struct InternalRawUncompiledHandler { source: DOMString, + #[no_trace] url: ServoUrl, line: usize, } @@ -344,7 +346,7 @@ impl EventListeners { #[dom_struct] pub struct EventTarget { reflector_: Reflector, - handlers: DomRefCell<HashMap<Atom, EventListeners, BuildHasherDefault<FnvHasher>>>, + handlers: DomRefCell<HashMapTracedValues<Atom, EventListeners, BuildHasherDefault<FnvHasher>>>, } impl EventTarget { diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs index 811a7e01b42..a1905965bc3 100644 --- a/components/script/dom/fakexrdevice.rs +++ b/components/script/dom/fakexrdevice.rs @@ -38,8 +38,10 @@ use webxr_api::{ pub struct FakeXRDevice { reflector: Reflector, #[ignore_malloc_size_of = "defined in ipc-channel"] + #[no_trace] sender: IpcSender<MockDeviceMsg>, #[ignore_malloc_size_of = "defined in webxr-api"] + #[no_trace] next_input_id: Cell<InputId>, } diff --git a/components/script/dom/fakexrinputcontroller.rs b/components/script/dom/fakexrinputcontroller.rs index 5699fa5d747..047729b96f6 100644 --- a/components/script/dom/fakexrinputcontroller.rs +++ b/components/script/dom/fakexrinputcontroller.rs @@ -23,8 +23,10 @@ use webxr_api::{ pub struct FakeXRInputController { reflector: Reflector, #[ignore_malloc_size_of = "defined in ipc-channel"] + #[no_trace] sender: IpcSender<MockDeviceMsg>, #[ignore_malloc_size_of = "defined in webxr-api"] + #[no_trace] id: InputId, } diff --git a/components/script/dom/formdata.rs b/components/script/dom/formdata.rs index af810e2d888..aa889522f5e 100644 --- a/components/script/dom/formdata.rs +++ b/components/script/dom/formdata.rs @@ -20,10 +20,12 @@ use html5ever::LocalName; use js::rust::HandleObject; use script_traits::serializable::BlobImpl; +use super::bindings::trace::NoTrace; + #[dom_struct] pub struct FormData { reflector_: Reflector, - data: DomRefCell<Vec<(LocalName, FormDatum)>>, + data: DomRefCell<Vec<(NoTrace<LocalName>, FormDatum)>>, } impl FormData { @@ -31,8 +33,8 @@ impl FormData { let data = match form_datums { Some(data) => data .iter() - .map(|datum| (LocalName::from(datum.name.as_ref()), datum.clone())) - .collect::<Vec<(LocalName, FormDatum)>>(), + .map(|datum| (NoTrace(LocalName::from(datum.name.as_ref())), datum.clone())) + .collect::<Vec<(NoTrace<LocalName>, FormDatum)>>(), None => Vec::new(), }; @@ -87,7 +89,7 @@ impl FormDataMethods for FormData { self.data .borrow_mut() - .push((LocalName::from(name.0), datum)); + .push((NoTrace(LocalName::from(name.0)), datum)); } #[allow(unrooted_must_root)] @@ -101,14 +103,14 @@ impl FormDataMethods for FormData { self.data .borrow_mut() - .push((LocalName::from(name.0), datum)); + .push((NoTrace(LocalName::from(name.0)), datum)); } // https://xhr.spec.whatwg.org/#dom-formdata-delete fn Delete(&self, name: USVString) { self.data .borrow_mut() - .retain(|(datum_name, _)| datum_name != &LocalName::from(name.0.clone())); + .retain(|(datum_name, _)| datum_name.0 != LocalName::from(name.0.clone())); } // https://xhr.spec.whatwg.org/#dom-formdata-get @@ -116,7 +118,7 @@ impl FormDataMethods for FormData { self.data .borrow() .iter() - .filter(|(datum_name, _)| datum_name == &LocalName::from(name.0.clone())) + .filter(|(datum_name, _)| datum_name.0 == LocalName::from(name.0.clone())) .next() .map(|(_, datum)| match &datum.value { FormDatumValue::String(ref s) => { @@ -131,12 +133,12 @@ impl FormDataMethods for FormData { self.data .borrow() .iter() - .filter_map(|datum| { - if datum.0 != LocalName::from(name.0.clone()) { + .filter_map(|(datum_name, datum)| { + if datum_name.0 != LocalName::from(name.0.clone()) { return None; } - Some(match &datum.1.value { + Some(match &datum.value { FormDatumValue::String(ref s) => { FileOrUSVString::USVString(USVString(s.to_string())) }, @@ -151,7 +153,7 @@ impl FormDataMethods for FormData { self.data .borrow() .iter() - .any(|(datum_name, _0)| datum_name == &LocalName::from(name.0.clone())) + .any(|(datum_name, _0)| datum_name.0 == LocalName::from(name.0.clone())) } // https://xhr.spec.whatwg.org/#dom-formdata-set @@ -159,10 +161,10 @@ impl FormDataMethods for FormData { let mut data = self.data.borrow_mut(); let local_name = LocalName::from(name.0.clone()); - data.retain(|(datum_name, _)| datum_name != &local_name); + data.retain(|(datum_name, _)| datum_name.0 != local_name); data.push(( - local_name, + NoTrace(local_name), FormDatum { ty: DOMString::from("string"), name: DOMString::from(name.0), @@ -177,10 +179,10 @@ impl FormDataMethods for FormData { let mut data = self.data.borrow_mut(); let local_name = LocalName::from(name.0.clone()); - data.retain(|(datum_name, _)| datum_name != &local_name); + data.retain(|(datum_name, _)| datum_name.0 != local_name); data.push(( - LocalName::from(name.0.clone()), + NoTrace(LocalName::from(name.0.clone())), FormDatum { ty: DOMString::from("file"), name: DOMString::from(name.0), diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index b03915997e5..ed082c0f4b9 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -129,6 +129,8 @@ use time::{get_time, Timespec}; use uuid::Uuid; use webgpu::{identity::WebGPUOpResult, ErrorScopeId, WebGPUDevice}; +use super::bindings::trace::HashMapTracedValues; + #[derive(JSTraceable)] pub struct AutoCloseWorker { /// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-closing @@ -137,6 +139,7 @@ pub struct AutoCloseWorker { join_handle: Option<JoinHandle<()>>, /// A sender of control messages, /// currently only used to signal shutdown. + #[no_trace] control_sender: Sender<DedicatedWorkerControlMsg>, /// The context to request an interrupt on the worker thread. context: ContextForRequestInterrupt, @@ -187,13 +190,15 @@ pub struct GlobalScope { blob_state: DomRefCell<BlobState>, /// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-registration-object-map> - registration_map: - DomRefCell<HashMap<ServiceWorkerRegistrationId, Dom<ServiceWorkerRegistration>>>, + registration_map: DomRefCell< + HashMapTracedValues<ServiceWorkerRegistrationId, Dom<ServiceWorkerRegistration>>, + >, /// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-object-map> - worker_map: DomRefCell<HashMap<ServiceWorkerId, Dom<ServiceWorker>>>, + worker_map: DomRefCell<HashMapTracedValues<ServiceWorkerId, Dom<ServiceWorker>>>, /// Pipeline id associated with this global. + #[no_trace] pipeline_id: PipelineId, /// A flag to indicate whether the developer tools has requested @@ -206,28 +211,33 @@ pub struct GlobalScope { /// module map is used when importing JavaScript modules /// https://html.spec.whatwg.org/multipage/#concept-settings-object-module-map #[ignore_malloc_size_of = "mozjs"] - module_map: DomRefCell<HashMap<ServoUrl, Rc<ModuleTree>>>, + module_map: DomRefCell<HashMapTracedValues<ServoUrl, Rc<ModuleTree>>>, #[ignore_malloc_size_of = "mozjs"] inline_module_map: DomRefCell<HashMap<ScriptId, Rc<ModuleTree>>>, /// For providing instructions to an optional devtools server. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>, /// For sending messages to the memory profiler. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] mem_profiler_chan: profile_mem::ProfilerChan, /// For sending messages to the time profiler. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] time_profiler_chan: profile_time::ProfilerChan, /// A handle for communicating messages to the constellation thread. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] script_to_constellation_chan: ScriptToConstellationChan, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] scheduler_chan: IpcSender<TimerSchedulerMsg>, /// <https://html.spec.whatwg.org/multipage/#in-error-reporting-mode> @@ -235,6 +245,7 @@ pub struct GlobalScope { /// Associated resource threads for use by DOM objects like XMLHttpRequest, /// including resource_thread, filemanager_thread and storage_thread + #[no_trace] resource_threads: ResourceThreads, /// The mechanism by which time-outs and intervals are scheduled. @@ -245,9 +256,11 @@ pub struct GlobalScope { init_timers: Cell<bool>, /// The origin of the globalscope + #[no_trace] origin: MutableOrigin, /// https://html.spec.whatwg.org/multipage/#concept-environment-creation-url + #[no_trace] creation_url: Option<ServoUrl>, /// A map for storing the previous permission state read results. @@ -296,16 +309,18 @@ pub struct GlobalScope { /// Identity Manager for WebGPU resources #[ignore_malloc_size_of = "defined in wgpu"] + #[no_trace] gpu_id_hub: Arc<Mutex<Identities>>, /// WebGPU devices - gpu_devices: DomRefCell<HashMap<WebGPUDevice, Dom<GPUDevice>>>, + gpu_devices: DomRefCell<HashMapTracedValues<WebGPUDevice, Dom<GPUDevice>>>, // https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute #[ignore_malloc_size_of = "mozjs"] frozen_supported_performance_entry_types: DomRefCell<Option<Heap<JSVal>>>, /// currect https state (from previous request) + #[no_trace] https_state: Cell<HttpsState>, /// The stack of active group labels for the Console APIs. @@ -379,6 +394,7 @@ pub struct BlobInfo { /// The weak ref to the corresponding DOM object. tracker: BlobTracker, /// The data and logic backing the DOM object. + #[no_trace] blob_impl: BlobImpl, /// Whether this blob has an outstanding URL, /// <https://w3c.github.io/FileAPI/#url>. @@ -389,7 +405,7 @@ pub struct BlobInfo { #[derive(JSTraceable, MallocSizeOf)] pub enum BlobState { /// A map of managed blobs. - Managed(HashMap<BlobId, BlobInfo>), + Managed(HashMapTracedValues<BlobId, BlobInfo>), /// This global is not managing any blobs at this time. UnManaged, } @@ -412,6 +428,7 @@ pub struct ManagedMessagePort { /// The option is needed to take out the port-impl /// as part of its transferring steps, /// without having to worry about rooting the dom-port. + #[no_trace] port_impl: Option<MessagePortImpl>, /// We keep ports pending when they are first transfer-received, /// and only add them, and ask the constellation to complete the transfer, @@ -430,7 +447,7 @@ pub enum BroadcastChannelState { /// of https://html.spec.whatwg.org/multipage/#dom-broadcastchannel-postmessage /// requires keeping track of creation order, hence the queue. Managed( - BroadcastChannelRouterId, + #[no_trace] BroadcastChannelRouterId, /// The map of channel-name to queue of channels, in order of creation. HashMap<DOMString, VecDeque<Dom<BroadcastChannel>>>, ), @@ -444,8 +461,8 @@ pub enum BroadcastChannelState { pub enum MessagePortState { /// The message-port router id for this global, and a map of managed ports. Managed( - MessagePortRouterId, - HashMap<MessagePortId, ManagedMessagePort>, + #[no_trace] MessagePortRouterId, + HashMapTracedValues<MessagePortId, ManagedMessagePort>, ), /// This global is not managing any ports at this time. UnManaged, @@ -739,8 +756,8 @@ impl GlobalScope { blob_state: DomRefCell::new(BlobState::UnManaged), eventtarget: EventTarget::new_inherited(), crypto: Default::default(), - registration_map: DomRefCell::new(HashMap::new()), - worker_map: DomRefCell::new(HashMap::new()), + registration_map: DomRefCell::new(HashMapTracedValues::new()), + worker_map: DomRefCell::new(HashMapTracedValues::new()), pipeline_id, devtools_wants_updates: Default::default(), console_timers: DomRefCell::new(Default::default()), @@ -766,7 +783,7 @@ impl GlobalScope { is_headless, user_agent, gpu_id_hub, - gpu_devices: DomRefCell::new(HashMap::new()), + gpu_devices: DomRefCell::new(HashMapTracedValues::new()), frozen_supported_performance_entry_types: DomRefCell::new(Default::default()), https_state: Cell::new(HttpsState::None), console_group_stack: DomRefCell::new(Vec::new()), @@ -789,7 +806,7 @@ impl GlobalScope { if let MessagePortState::Managed(_router_id, message_ports) = &*self.message_port_state.borrow() { - return message_ports.contains_key(port_id); + return message_ports.contains_key(&*port_id); } false } @@ -976,7 +993,7 @@ impl GlobalScope { &mut *self.message_port_state.borrow_mut() { for (port_id, entangled_id) in &[(port1, port2), (port2, port1)] { - match message_ports.get_mut(&port_id) { + match message_ports.get_mut(&*port_id) { None => { return warn!("entangled_ports called on a global not managing the port."); }, @@ -1017,7 +1034,7 @@ impl GlobalScope { &mut *self.message_port_state.borrow_mut() { let mut port_impl = message_ports - .remove(&port_id) + .remove(&*port_id) .map(|ref mut managed_port| { managed_port .port_impl @@ -1040,7 +1057,7 @@ impl GlobalScope { if let MessagePortState::Managed(_id, message_ports) = &mut *self.message_port_state.borrow_mut() { - let message_buffer = match message_ports.get_mut(&port_id) { + let message_buffer = match message_ports.get_mut(&*port_id) { None => panic!("start_message_port called on a unknown port."), Some(managed_port) => { if let Some(port_impl) = managed_port.port_impl.as_mut() { @@ -1073,7 +1090,7 @@ impl GlobalScope { if let MessagePortState::Managed(_id, message_ports) = &mut *self.message_port_state.borrow_mut() { - match message_ports.get_mut(&port_id) { + match message_ports.get_mut(&*port_id) { None => panic!("close_message_port called on an unknown port."), Some(managed_port) => { if let Some(port_impl) = managed_port.port_impl.as_mut() { @@ -1306,7 +1323,7 @@ impl GlobalScope { .collect(); for id in to_be_added.iter() { let managed_port = message_ports - .get_mut(&id) + .get_mut(&*id) .expect("Collected port-id to match an entry"); if !managed_port.pending { panic!("Only pending ports should be found in to_be_added") @@ -1472,7 +1489,8 @@ impl GlobalScope { }), ); let router_id = MessagePortRouterId::new(); - *current_state = MessagePortState::Managed(router_id.clone(), HashMap::new()); + *current_state = + MessagePortState::Managed(router_id.clone(), HashMapTracedValues::new()); let _ = self .script_to_constellation_chan() .send(ScriptMsg::NewMessagePortRouter( @@ -1551,7 +1569,7 @@ impl GlobalScope { match &mut *blob_state { BlobState::UnManaged => { - let mut blobs_map = HashMap::new(); + let mut blobs_map = HashMapTracedValues::new(); blobs_map.insert(blob_id, blob_info); *blob_state = BlobState::Managed(blobs_map); }, @@ -1593,7 +1611,7 @@ impl GlobalScope { fn perform_a_blob_garbage_collection_checkpoint(&self) { let mut blob_state = self.blob_state.borrow_mut(); if let BlobState::Managed(blobs_map) = &mut *blob_state { - blobs_map.retain(|_id, blob_info| { + blobs_map.0.retain(|_id, blob_info| { let garbage_collected = match &blob_info.tracker { BlobTracker::File(weak) => weak.root().is_none(), BlobTracker::Blob(weak) => weak.root().is_none(), @@ -1644,7 +1662,7 @@ impl GlobalScope { let blob_state = self.blob_state.borrow(); if let BlobState::Managed(blobs_map) = &*blob_state { let blob_info = blobs_map - .get(blob_id) + .get(&blob_id) .expect("get_blob_bytes for an unknown blob."); match blob_info.blob_impl.blob_data() { BlobData::Sliced(ref parent, ref rel_pos) => { @@ -1671,7 +1689,7 @@ impl GlobalScope { let blob_state = self.blob_state.borrow(); if let BlobState::Managed(blobs_map) = &*blob_state { let blob_info = blobs_map - .get(blob_id) + .get(&blob_id) .expect("get_blob_bytes_non_sliced called for a unknown blob."); match blob_info.blob_impl.blob_data() { BlobData::File(ref f) => { @@ -1709,7 +1727,7 @@ impl GlobalScope { let blob_state = self.blob_state.borrow(); if let BlobState::Managed(blobs_map) = &*blob_state { let blob_info = blobs_map - .get(blob_id) + .get(&blob_id) .expect("get_blob_bytes_or_file_id for an unknown blob."); match blob_info.blob_impl.blob_data() { BlobData::Sliced(ref parent, ref rel_pos) => { @@ -1745,7 +1763,7 @@ impl GlobalScope { let blob_state = self.blob_state.borrow(); if let BlobState::Managed(blobs_map) = &*blob_state { let blob_info = blobs_map - .get(blob_id) + .get(&blob_id) .expect("get_blob_bytes_non_sliced_or_file_id called for a unknown blob."); match blob_info.blob_impl.blob_data() { BlobData::File(ref f) => match f.get_cache() { @@ -1767,7 +1785,7 @@ impl GlobalScope { let blob_state = self.blob_state.borrow(); if let BlobState::Managed(blobs_map) = &*blob_state { let blob_info = blobs_map - .get(blob_id) + .get(&blob_id) .expect("get_blob_type_string called for a unknown blob."); blob_info.blob_impl.type_string() } else { @@ -1781,7 +1799,7 @@ impl GlobalScope { if let BlobState::Managed(blobs_map) = &*blob_state { let parent = { let blob_info = blobs_map - .get(blob_id) + .get(&blob_id) .expect("get_blob_size called for a unknown blob."); match blob_info.blob_impl.blob_data() { BlobData::Sliced(ref parent, ref rel_pos) => { @@ -1803,7 +1821,9 @@ impl GlobalScope { rel_pos.to_abs_range(parent_size as usize).len() as u64 }, None => { - let blob_info = blobs_map.get(blob_id).expect("Blob whose size is unknown."); + let blob_info = blobs_map + .get(&blob_id) + .expect("Blob whose size is unknown."); match blob_info.blob_impl.blob_data() { BlobData::File(ref f) => f.get_size(), BlobData::Memory(ref v) => v.len() as u64, @@ -1823,7 +1843,7 @@ impl GlobalScope { if let BlobState::Managed(blobs_map) = &mut *blob_state { let parent = { let blob_info = blobs_map - .get_mut(blob_id) + .get_mut(&blob_id) .expect("get_blob_url_id called for a unknown blob."); // Keep track of blobs with outstanding URLs. @@ -1849,13 +1869,13 @@ impl GlobalScope { }; let parent_size = rel_pos.to_abs_range(parent_size as usize).len() as u64; let blob_info = blobs_map - .get_mut(blob_id) + .get_mut(&blob_id) .expect("Blob whose url is requested is unknown."); self.create_sliced_url_id(blob_info, &parent_file_id, &rel_pos, parent_size) }, None => { let blob_info = blobs_map - .get_mut(blob_id) + .get_mut(&blob_id) .expect("Blob whose url is requested is unknown."); self.promote(blob_info, /* set_valid is */ true) }, @@ -2206,7 +2226,7 @@ impl GlobalScope { self.module_map.borrow_mut().insert(url, Rc::new(module)); } - pub fn get_module_map(&self) -> &DomRefCell<HashMap<ServoUrl, Rc<ModuleTree>>> { + pub fn get_module_map(&self) -> &DomRefCell<HashMapTracedValues<ServoUrl, Rc<ModuleTree>>> { &self.module_map } diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index ce82e4ec4a3..e87f0589c51 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -26,10 +26,12 @@ use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, WebGPURe pub struct GPUAdapter { reflector_: Reflector, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, name: DOMString, #[ignore_malloc_size_of = "mozjs"] extensions: Heap<*mut JSObject>, + #[no_trace] adapter: WebGPUAdapter, } diff --git a/components/script/dom/gpubindgroup.rs b/components/script/dom/gpubindgroup.rs index 394cf41e915..d25cf7fa5bd 100644 --- a/components/script/dom/gpubindgroup.rs +++ b/components/script/dom/gpubindgroup.rs @@ -16,7 +16,9 @@ use webgpu::{WebGPUBindGroup, WebGPUDevice}; pub struct GPUBindGroup { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] bind_group: WebGPUBindGroup, + #[no_trace] device: WebGPUDevice, layout: Dom<GPUBindGroupLayout>, } diff --git a/components/script/dom/gpubindgrouplayout.rs b/components/script/dom/gpubindgrouplayout.rs index ce794269359..87442c1d744 100644 --- a/components/script/dom/gpubindgrouplayout.rs +++ b/components/script/dom/gpubindgrouplayout.rs @@ -15,6 +15,7 @@ use webgpu::WebGPUBindGroupLayout; pub struct GPUBindGroupLayout { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] bind_group_layout: WebGPUBindGroupLayout, } diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 83dd27b47d9..0d528812a96 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -59,9 +59,11 @@ pub struct GPUBufferMapInfo { pub struct GPUBuffer { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] + #[no_trace] channel: WebGPU, label: DomRefCell<Option<USVString>>, state: Cell<GPUBufferState>, + #[no_trace] buffer: WebGPUBuffer, device: Dom<GPUDevice>, size: GPUSize64, diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs index 9679479394e..e1fac360758 100644 --- a/components/script/dom/gpucanvascontext.rs +++ b/components/script/dom/gpucanvascontext.rs @@ -37,11 +37,14 @@ pub struct WebGPUContextId(pub u64); pub struct GPUCanvasContext { reflector_: Reflector, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, canvas: Dom<HTMLCanvasElement>, + #[no_trace] size: Cell<Size2D<u32>>, swap_chain: DomRefCell<Option<Dom<GPUSwapChain>>>, #[ignore_malloc_size_of = "Defined in webrender"] + #[no_trace] webrender_image: Cell<Option<webrender_api::ImageKey>>, context_id: WebGPUContextId, } diff --git a/components/script/dom/gpucommandbuffer.rs b/components/script/dom/gpucommandbuffer.rs index eb6ede84c26..633dcb9cc6a 100644 --- a/components/script/dom/gpucommandbuffer.rs +++ b/components/script/dom/gpucommandbuffer.rs @@ -26,8 +26,10 @@ impl Hash for DomRoot<GPUBuffer> { pub struct GPUCommandBuffer { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] + #[no_trace] channel: WebGPU, label: DomRefCell<Option<USVString>>, + #[no_trace] command_buffer: WebGPUCommandBuffer, buffers: DomRefCell<HashSet<Dom<GPUBuffer>>>, } diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs index 60eabbf1973..30eb4c91ba9 100644 --- a/components/script/dom/gpucommandencoder.rs +++ b/components/script/dom/gpucommandencoder.rs @@ -44,8 +44,10 @@ pub enum GPUCommandEncoderState { pub struct GPUCommandEncoder { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] + #[no_trace] channel: WebGPU, label: DomRefCell<Option<USVString>>, + #[no_trace] encoder: webgpu::WebGPUCommandEncoder, buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>, state: DomRefCell<GPUCommandEncoderState>, diff --git a/components/script/dom/gpucomputepassencoder.rs b/components/script/dom/gpucomputepassencoder.rs index f0f4325ae6d..c9b807ae6ac 100644 --- a/components/script/dom/gpucomputepassencoder.rs +++ b/components/script/dom/gpucomputepassencoder.rs @@ -22,9 +22,11 @@ use webgpu::{ pub struct GPUComputePassEncoder { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] + #[no_trace] channel: WebGPU, label: DomRefCell<Option<USVString>>, #[ignore_malloc_size_of = "defined in wgpu-core"] + #[no_trace] compute_pass: DomRefCell<Option<ComputePass>>, command_encoder: Dom<GPUCommandEncoder>, } diff --git a/components/script/dom/gpucomputepipeline.rs b/components/script/dom/gpucomputepipeline.rs index 604af2373e0..cf325837663 100644 --- a/components/script/dom/gpucomputepipeline.rs +++ b/components/script/dom/gpucomputepipeline.rs @@ -19,7 +19,9 @@ use webgpu::{WebGPUBindGroupLayout, WebGPUComputePipeline}; pub struct GPUComputePipeline { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] compute_pipeline: WebGPUComputePipeline, + #[no_trace] bind_group_layouts: Vec<WebGPUBindGroupLayout>, device: Dom<GPUDevice>, } diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index 5ea21eac5de..054a0ecb8e7 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -108,6 +108,7 @@ struct ScopeContext { pub struct GPUDevice { eventtarget: EventTarget, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, adapter: Dom<GPUAdapter>, #[ignore_malloc_size_of = "mozjs"] @@ -115,6 +116,7 @@ pub struct GPUDevice { #[ignore_malloc_size_of = "Because it is non-owning"] limits: GPULimits, label: DomRefCell<Option<USVString>>, + #[no_trace] device: webgpu::WebGPUDevice, default_queue: Dom<GPUQueue>, scope_context: DomRefCell<ScopeContext>, diff --git a/components/script/dom/gpupipelinelayout.rs b/components/script/dom/gpupipelinelayout.rs index 563d0ca9220..4a28fcf4a6c 100644 --- a/components/script/dom/gpupipelinelayout.rs +++ b/components/script/dom/gpupipelinelayout.rs @@ -15,7 +15,9 @@ use webgpu::{WebGPUBindGroupLayout, WebGPUPipelineLayout}; pub struct GPUPipelineLayout { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] pipeline_layout: WebGPUPipelineLayout, + #[no_trace] bind_group_layouts: Vec<WebGPUBindGroupLayout>, } diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs index ca571371c8c..e2a9e99b90b 100644 --- a/components/script/dom/gpuqueue.rs +++ b/components/script/dom/gpuqueue.rs @@ -27,9 +27,11 @@ use webgpu::{identity::WebGPUOpResult, wgt, WebGPU, WebGPUQueue, WebGPURequest}; pub struct GPUQueue { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] + #[no_trace] channel: WebGPU, device: DomRefCell<Option<Dom<GPUDevice>>>, label: DomRefCell<Option<USVString>>, + #[no_trace] queue: WebGPUQueue, } diff --git a/components/script/dom/gpurenderbundle.rs b/components/script/dom/gpurenderbundle.rs index 5c020f8f697..c39559ed62c 100644 --- a/components/script/dom/gpurenderbundle.rs +++ b/components/script/dom/gpurenderbundle.rs @@ -15,8 +15,11 @@ use webgpu::{WebGPU, WebGPUDevice, WebGPURenderBundle}; pub struct GPURenderBundle { reflector_: Reflector, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, + #[no_trace] device: WebGPUDevice, + #[no_trace] render_bundle: WebGPURenderBundle, label: DomRefCell<Option<USVString>>, } diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs index 722afdebc0e..b261af6d857 100644 --- a/components/script/dom/gpurenderbundleencoder.rs +++ b/components/script/dom/gpurenderbundleencoder.rs @@ -24,9 +24,11 @@ use webgpu::{ pub struct GPURenderBundleEncoder { reflector_: Reflector, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, device: Dom<GPUDevice>, #[ignore_malloc_size_of = "defined in wgpu-core"] + #[no_trace] render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>, label: DomRefCell<Option<USVString>>, } diff --git a/components/script/dom/gpurenderpassencoder.rs b/components/script/dom/gpurenderpassencoder.rs index ac7424b1999..0bcbda00b23 100644 --- a/components/script/dom/gpurenderpassencoder.rs +++ b/components/script/dom/gpurenderpassencoder.rs @@ -25,9 +25,11 @@ use webgpu::{ pub struct GPURenderPassEncoder { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] + #[no_trace] channel: WebGPU, label: DomRefCell<Option<USVString>>, #[ignore_malloc_size_of = "defined in wgpu-core"] + #[no_trace] render_pass: DomRefCell<Option<RenderPass>>, command_encoder: Dom<GPUCommandEncoder>, } diff --git a/components/script/dom/gpurenderpipeline.rs b/components/script/dom/gpurenderpipeline.rs index 9914b1d3114..76bbd76330e 100644 --- a/components/script/dom/gpurenderpipeline.rs +++ b/components/script/dom/gpurenderpipeline.rs @@ -19,7 +19,9 @@ use webgpu::{WebGPUBindGroupLayout, WebGPURenderPipeline}; pub struct GPURenderPipeline { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] render_pipeline: WebGPURenderPipeline, + #[no_trace] bind_group_layouts: Vec<WebGPUBindGroupLayout>, device: Dom<GPUDevice>, } diff --git a/components/script/dom/gpusampler.rs b/components/script/dom/gpusampler.rs index 23395ee058c..473ac28c3b7 100644 --- a/components/script/dom/gpusampler.rs +++ b/components/script/dom/gpusampler.rs @@ -15,8 +15,10 @@ use webgpu::{WebGPUDevice, WebGPUSampler}; pub struct GPUSampler { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] device: WebGPUDevice, compare_enable: bool, + #[no_trace] sampler: WebGPUSampler, } diff --git a/components/script/dom/gpushadermodule.rs b/components/script/dom/gpushadermodule.rs index c4f20124ea8..5eff0c9cbb3 100644 --- a/components/script/dom/gpushadermodule.rs +++ b/components/script/dom/gpushadermodule.rs @@ -15,6 +15,7 @@ use webgpu::WebGPUShaderModule; pub struct GPUShaderModule { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] shader_module: WebGPUShaderModule, } diff --git a/components/script/dom/gpuswapchain.rs b/components/script/dom/gpuswapchain.rs index 9b8e9aab588..18a5fe29696 100644 --- a/components/script/dom/gpuswapchain.rs +++ b/components/script/dom/gpuswapchain.rs @@ -18,6 +18,7 @@ use webrender_api::ImageKey; pub struct GPUSwapChain { reflector_: Reflector, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, label: DomRefCell<Option<USVString>>, context: Dom<GPUCanvasContext>, diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs index b473e52eaae..6f27f4cbc6d 100644 --- a/components/script/dom/gputexture.rs +++ b/components/script/dom/gputexture.rs @@ -29,10 +29,12 @@ use webgpu::{ #[dom_struct] pub struct GPUTexture { reflector_: Reflector, + #[no_trace] texture: WebGPUTexture, label: DomRefCell<Option<USVString>>, device: Dom<GPUDevice>, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] channel: WebGPU, #[ignore_malloc_size_of = "defined in webgpu"] texture_size: GPUExtent3DDict, diff --git a/components/script/dom/gputextureview.rs b/components/script/dom/gputextureview.rs index af346d92250..1300079422f 100644 --- a/components/script/dom/gputextureview.rs +++ b/components/script/dom/gputextureview.rs @@ -16,6 +16,7 @@ use webgpu::WebGPUTextureView; pub struct GPUTextureView { reflector_: Reflector, label: DomRefCell<Option<USVString>>, + #[no_trace] texture_view: WebGPUTextureView, texture: Dom<GPUTexture>, } diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs index a2e2d4acdac..32d0ed36d40 100644 --- a/components/script/dom/headers.rs +++ b/components/script/dom/headers.rs @@ -25,6 +25,7 @@ pub struct Headers { reflector_: Reflector, guard: Cell<Guard>, #[ignore_malloc_size_of = "Defined in hyper"] + #[no_trace] header_list: DomRefCell<HyperHeaders>, } diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs index 663499da38f..f527d38a915 100644 --- a/components/script/dom/history.rs +++ b/components/script/dom/history.rs @@ -42,6 +42,7 @@ pub struct History { window: Dom<Window>, #[ignore_malloc_size_of = "mozjs"] state: Heap<JSVal>, + #[no_trace] state_id: Cell<Option<HistoryStateId>>, } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index aca8e99b95a..d52ab647509 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -42,6 +42,7 @@ use style::attr::AttrValue; pub struct HTMLAnchorElement { htmlelement: HTMLElement, rel_list: MutNullableDom<DOMTokenList>, + #[no_trace] url: DomRefCell<Option<ServoUrl>>, } diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index f1eb1fdd706..02a225fb9b6 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -164,7 +164,9 @@ impl HTMLCollection { #[derive(JSTraceable, MallocSizeOf)] struct HtmlDocumentFilter { + #[no_trace] qualified_name: LocalName, + #[no_trace] ascii_lower_qualified_name: LocalName, } impl CollectionFilter for HtmlDocumentFilter { @@ -216,6 +218,7 @@ impl HTMLCollection { ) -> DomRoot<HTMLCollection> { #[derive(JSTraceable, MallocSizeOf)] struct TagNameNSFilter { + #[no_trace] qname: QualName, } impl CollectionFilter for TagNameNSFilter { @@ -245,6 +248,7 @@ impl HTMLCollection { ) -> DomRoot<HTMLCollection> { #[derive(JSTraceable, MallocSizeOf)] struct ClassNameFilter { + #[no_trace] classes: Vec<Atom>, } impl CollectionFilter for ClassNameFilter { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 7594026046c..9a1cdc40555 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -76,11 +76,12 @@ use style::element_state::ElementState; use style::str::split_html_space_chars; use crate::dom::bindings::codegen::UnionTypes::RadioNodeListOrElement; -use std::collections::HashMap; use time::{now, Duration, Tm}; use crate::dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods}; +use super::bindings::trace::{HashMapTracedValues, NoTrace}; + #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] pub struct GenerationId(u32); @@ -93,7 +94,7 @@ pub struct HTMLFormElement { elements: DomOnceCell<HTMLFormControlsCollection>, generation_id: Cell<GenerationId>, controls: DomRefCell<Vec<Dom<Element>>>, - past_names_map: DomRefCell<HashMap<Atom, (Dom<Element>, Tm)>>, + past_names_map: DomRefCell<HashMapTracedValues<Atom, (Dom<Element>, NoTrace<Tm>)>>, firing_submission_events: Cell<bool>, rel_list: MutNullableDom<DOMTokenList>, } @@ -116,7 +117,7 @@ impl HTMLFormElement { elements: Default::default(), generation_id: Cell::new(GenerationId(0)), controls: DomRefCell::new(Vec::new()), - past_names_map: DomRefCell::new(HashMap::new()), + past_names_map: DomRefCell::new(HashMapTracedValues::new()), firing_submission_events: Cell::new(false), rel_list: Default::default(), } @@ -441,7 +442,7 @@ impl HTMLFormElementMethods for HTMLFormElement { name, ( Dom::from_ref(&*element_node.downcast::<Element>().unwrap()), - now(), + NoTrace(now()), ), ); @@ -555,7 +556,7 @@ impl HTMLFormElementMethods for HTMLFormElement { let entry = SourcedName { name: key.clone(), element: DomRoot::from_ref(&*val.0), - source: SourcedNameSource::Past(now() - val.1), // calculate difference now()-val.1 to find age + source: SourcedNameSource::Past(now() - val.1 .0), // calculate difference now()-val.1 to find age }; sourced_names_vec.push(entry); } @@ -1336,7 +1337,7 @@ impl HTMLFormElement { // changes form owner, then its entries must be removed // from that map." let mut past_names_map = self.past_names_map.borrow_mut(); - past_names_map.retain(|_k, v| v.0 != control); + past_names_map.0.retain(|_k, v| v.0 != control); } self.update_validity(); } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index e0fe53317ce..55c515d8c1d 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -71,10 +71,15 @@ enum ProcessingMode { #[dom_struct] pub struct HTMLIFrameElement { htmlelement: HTMLElement, + #[no_trace] top_level_browsing_context_id: Cell<Option<TopLevelBrowsingContextId>>, + #[no_trace] browsing_context_id: Cell<Option<BrowsingContextId>>, + #[no_trace] pipeline_id: Cell<Option<PipelineId>>, + #[no_trace] pending_pipeline_id: Cell<Option<PipelineId>>, + #[no_trace] about_blank_pipeline_id: Cell<Option<PipelineId>>, sandbox: MutNullableDom<DOMTokenList>, sandbox_allowance: Cell<Option<SandboxAllowance>>, diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 1598dbd7e2d..cd6e27537e5 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -142,12 +142,16 @@ enum ImageRequestPhase { #[unrooted_must_root_lint::must_root] struct ImageRequest { state: State, + #[no_trace] parsed_url: Option<ServoUrl>, source_url: Option<USVString>, blocker: Option<LoadBlocker>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] image: Option<Arc<Image>>, + #[no_trace] metadata: Option<ImageMetadata>, + #[no_trace] final_url: Option<ServoUrl>, current_pixel_density: Option<f64>, } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index f0e16612c90..16bbbac21e4 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -255,6 +255,7 @@ pub struct HTMLInputElement { maxlength: Cell<i32>, minlength: Cell<i32>, #[ignore_malloc_size_of = "#7193"] + #[no_trace] textinput: DomRefCell<TextInput<ScriptToConstellationChan>>, // https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag value_dirty: Cell<bool>, diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 5b8ed9e2250..6b833d6473a 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -57,6 +57,7 @@ pub struct HTMLLinkElement { htmlelement: HTMLElement, rel_list: MutNullableDom<DOMTokenList>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] stylesheet: DomRefCell<Option<Arc<Stylesheet>>>, cssom_stylesheet: MutNullableDom<CSSStyleSheet>, diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 2d404cf2d49..5fae503be08 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -333,10 +333,13 @@ pub struct HTMLMediaElement { #[ignore_malloc_size_of = "promises are hard"] in_flight_play_promises_queue: DomRefCell<VecDeque<(Box<[Rc<Promise>]>, ErrorResult)>>, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] player: DomRefCell<Option<Arc<Mutex<dyn Player>>>>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] video_renderer: Arc<Mutex<MediaFrameRenderer>>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] audio_renderer: DomRefCell<Option<Arc<Mutex<dyn AudioRenderer>>>>, /// https://html.spec.whatwg.org/multipage/#show-poster-flag show_poster: Cell<bool>, @@ -353,9 +356,11 @@ pub struct HTMLMediaElement { /// https://html.spec.whatwg.org/multipage/#dom-media-muted muted: Cell<bool>, /// URL of the media resource, if any. + #[no_trace] resource_url: DomRefCell<Option<ServoUrl>>, /// URL of the media resource, if the resource is set through the src_object attribute and it /// is a blob. + #[no_trace] blob_url: DomRefCell<Option<ServoUrl>>, /// https://html.spec.whatwg.org/multipage/#dom-media-played #[ignore_malloc_size_of = "Rc"] @@ -368,6 +373,7 @@ pub struct HTMLMediaElement { text_tracks_list: MutNullableDom<TextTrackList>, /// Time of last timeupdate notification. #[ignore_malloc_size_of = "Defined in time"] + #[no_trace] next_timeupdate_event: Cell<Timespec>, /// Latest fetch request context. current_fetch_context: DomRefCell<Option<HTMLMediaElementFetchContext>>, @@ -379,6 +385,7 @@ pub struct HTMLMediaElement { /// keeping a whitelist of media controls identifiers. media_controls_id: DomRefCell<Option<String>>, #[ignore_malloc_size_of = "Defined in other crates"] + #[no_trace] player_context: WindowGLContext, } @@ -2471,6 +2478,7 @@ pub enum MediaElementMicrotask { ResourceSelectionTask { elem: DomRoot<HTMLMediaElement>, generation_id: u32, + #[no_trace] base_url: ServoUrl, }, PauseIfNotInDocumentTask { diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs index a6f78b6ec70..348e52d9ee2 100755 --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs @@ -27,6 +27,7 @@ use std::default::Default; pub struct HTMLObjectElement { htmlelement: HTMLElement, #[ignore_malloc_size_of = "Arc"] + #[no_trace] image: DomRefCell<Option<Arc<Image>>>, form_owner: MutNullableDom<HTMLFormElement>, validity_state: MutNullableDom<ValidityState>, diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index e7e520e56bd..8889f6ad696 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -13,6 +13,7 @@ use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::settings_stack::AutoEntryScript; use crate::dom::bindings::str::{DOMString, USVString}; +use crate::dom::bindings::trace::NoTrace; use crate::dom::document::Document; use crate::dom::element::{ cors_setting_for_element, referrer_policy_for_element, reflect_cross_origin_attribute, @@ -117,9 +118,9 @@ unsafe extern "C" fn off_thread_compilation_callback( let compiled_script = FinishOffThreadStencil(*cx, token.0, ptr::null_mut()); let load = if compiled_script.is_null() { - Err(NetworkError::Internal( + Err(NoTrace(NetworkError::Internal( "Off-thread compilation failed.".into(), - )) + ))) } else { let script_text = DOMString::from(script); let code = SourceCode::Compiled(CompiledSourceCode { @@ -144,7 +145,7 @@ unsafe extern "C" fn off_thread_compilation_callback( /// An unique id for script element. #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)] -pub struct ScriptId(Uuid); +pub struct ScriptId(#[no_trace] Uuid); #[dom_struct] pub struct HTMLScriptElement { @@ -257,6 +258,7 @@ pub enum SourceCode { pub struct ScriptOrigin { #[ignore_malloc_size_of = "Rc is hard"] code: SourceCode, + #[no_trace] url: ServoUrl, external: bool, fetch_options: ScriptFetchOptions, @@ -326,7 +328,7 @@ fn finish_fetching_a_classic_script( document.finish_load(LoadType::Script(url)); } -pub type ScriptResult = Result<ScriptOrigin, NetworkError>; +pub type ScriptResult = Result<ScriptOrigin, NoTrace<NetworkError>>; /// The context required for asynchronously loading an external script source. struct ClassicContext { @@ -400,7 +402,7 @@ impl FetchResponseListener for ClassicContext { &*self.elem.root(), self.kind.clone(), self.url.clone(), - Err(err.clone()), + Err(NoTrace(err.clone())), ); return; }, diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 6dd0ee24ab4..e2ffb441f73 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -34,6 +34,7 @@ use style_traits::ParsingMode; pub struct HTMLStyleElement { htmlelement: HTMLElement, #[ignore_malloc_size_of = "Arc"] + #[no_trace] stylesheet: DomRefCell<Option<Arc<Stylesheet>>>, cssom_stylesheet: MutNullableDom<CSSStyleSheet>, /// <https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts> diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index db21db49b18..6ff51963348 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -49,6 +49,7 @@ use style::element_state::ElementState; pub struct HTMLTextAreaElement { htmlelement: HTMLElement, #[ignore_malloc_size_of = "#7193"] + #[no_trace] textinput: DomRefCell<TextInput<ScriptToConstellationChan>>, placeholder: DomRefCell<DOMString>, // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index 4a288607be7..45e843d0efc 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -60,6 +60,7 @@ pub struct HTMLVideoElement { load_blocker: DomRefCell<Option<LoadBlocker>>, /// A copy of the last frame #[ignore_malloc_size_of = "VideoFrame"] + #[no_trace] last_frame: DomRefCell<Option<VideoFrame>>, } diff --git a/components/script/dom/medialist.rs b/components/script/dom/medialist.rs index 772c508fc04..87a318ddbe2 100644 --- a/components/script/dom/medialist.rs +++ b/components/script/dom/medialist.rs @@ -24,6 +24,7 @@ pub struct MediaList { reflector_: Reflector, parent_stylesheet: Dom<CSSStyleSheet>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] media_queries: Arc<Locked<StyleMediaList>>, } diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs index 48080f95adf..57140c8cb6f 100644 --- a/components/script/dom/mediaquerylist.rs +++ b/components/script/dom/mediaquerylist.rs @@ -27,6 +27,7 @@ pub enum MediaQueryListMatchState { pub struct MediaQueryList { eventtarget: EventTarget, document: Dom<Document>, + #[no_trace] media_query_list: MediaList, last_match_state: Cell<Option<bool>>, } diff --git a/components/script/dom/mediasession.rs b/components/script/dom/mediasession.rs index 49112ba921b..edd73158acc 100644 --- a/components/script/dom/mediasession.rs +++ b/components/script/dom/mediasession.rs @@ -26,20 +26,23 @@ use embedder_traits::MediaMetadata as EmbedderMediaMetadata; use embedder_traits::MediaSessionEvent; use script_traits::MediaSessionActionType; use script_traits::ScriptMsg; -use std::collections::HashMap; use std::rc::Rc; +use super::bindings::trace::HashMapTracedValues; + #[dom_struct] pub struct MediaSession { reflector_: Reflector, /// https://w3c.github.io/mediasession/#dom-mediasession-metadata #[ignore_malloc_size_of = "defined in embedder_traits"] + #[no_trace] metadata: DomRefCell<Option<EmbedderMediaMetadata>>, /// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate playback_state: DomRefCell<MediaSessionPlaybackState>, /// https://w3c.github.io/mediasession/#supported-media-session-actions #[ignore_malloc_size_of = "Rc"] - action_handlers: DomRefCell<HashMap<MediaSessionActionType, Rc<MediaSessionActionHandler>>>, + action_handlers: + DomRefCell<HashMapTracedValues<MediaSessionActionType, Rc<MediaSessionActionHandler>>>, /// The media instance controlled by this media session. /// For now only HTMLMediaElements are controlled by media sessions. media_instance: MutNullableDom<HTMLMediaElement>, @@ -52,7 +55,7 @@ impl MediaSession { reflector_: Reflector::new(), metadata: DomRefCell::new(None), playback_state: DomRefCell::new(MediaSessionPlaybackState::None), - action_handlers: DomRefCell::new(HashMap::new()), + action_handlers: DomRefCell::new(HashMapTracedValues::new()), media_instance: Default::default(), }; media_session diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs index c5178b3682b..729dbfc5cce 100644 --- a/components/script/dom/mediastreamtrack.rs +++ b/components/script/dom/mediastreamtrack.rs @@ -16,8 +16,10 @@ use servo_media::streams::MediaStreamType; pub struct MediaStreamTrack { eventtarget: EventTarget, #[ignore_malloc_size_of = "defined in servo-media"] + #[no_trace] id: MediaStreamId, #[ignore_malloc_size_of = "defined in servo-media"] + #[no_trace] ty: MediaStreamType, } diff --git a/components/script/dom/messageport.rs b/components/script/dom/messageport.rs index fee7c75a9eb..3035cc5bcd4 100644 --- a/components/script/dom/messageport.rs +++ b/components/script/dom/messageport.rs @@ -33,7 +33,9 @@ use std::rc::Rc; /// The MessagePort used in the DOM. pub struct MessagePort { eventtarget: EventTarget, + #[no_trace] message_port_id: MessagePortId, + #[no_trace] entangled_port: RefCell<Option<MessagePortId>>, detached: Cell<bool>, } diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 137ccbc7673..670b058b0ba 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -43,6 +43,7 @@ pub struct MouseEvent { button: Cell<i16>, buttons: Cell<u16>, related_target: MutNullableDom<EventTarget>, + #[no_trace] point_in_target: Cell<Option<Point2D<f32>>>, } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 943a0eaaa1a..a4913faa683 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -151,6 +151,7 @@ pub struct Node { /// Style+Layout information. #[ignore_malloc_size_of = "trait object"] + #[no_trace] style_and_layout_data: DomRefCell<Option<Box<StyleAndOpaqueLayoutData>>>, } diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs index d7ec1808323..b8286e5f0ea 100644 --- a/components/script/dom/nodelist.rs +++ b/components/script/dom/nodelist.rs @@ -392,6 +392,7 @@ pub enum RadioListMode { pub struct RadioList { form: Dom<HTMLFormElement>, mode: RadioListMode, + #[no_trace] name: Atom, } diff --git a/components/script/dom/paintrenderingcontext2d.rs b/components/script/dom/paintrenderingcontext2d.rs index af9f5cd01b3..bdda5fc934e 100644 --- a/components/script/dom/paintrenderingcontext2d.rs +++ b/components/script/dom/paintrenderingcontext2d.rs @@ -35,6 +35,7 @@ use style_traits::DevicePixel; #[dom_struct] pub struct PaintRenderingContext2D { context: CanvasRenderingContext2D, + #[no_trace] device_pixel_ratio: Cell<Scale<f32, CSSPixel, DevicePixel>>, } diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs index 25bdeeb5ca3..ab16d75a672 100644 --- a/components/script/dom/paintworkletglobalscope.rs +++ b/components/script/dom/paintworkletglobalscope.rs @@ -55,7 +55,6 @@ use servo_config::pref; use servo_url::ServoUrl; use std::cell::Cell; use std::collections::hash_map::Entry; -use std::collections::HashMap; use std::ptr::null_mut; use std::rc::Rc; use std::sync::Arc; @@ -66,6 +65,8 @@ use style_traits::CSSPixel; use style_traits::DevicePixel; use style_traits::SpeculativePainter; +use super::bindings::trace::HashMapTracedValues; + /// <https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope> #[dom_struct] pub struct PaintWorkletGlobalScope { @@ -73,23 +74,29 @@ pub struct PaintWorkletGlobalScope { worklet_global: WorkletGlobalScope, /// The image cache #[ignore_malloc_size_of = "Arc"] + #[no_trace] image_cache: Arc<dyn ImageCache>, /// <https://drafts.css-houdini.org/css-paint-api/#paint-definitions> - paint_definitions: DomRefCell<HashMap<Atom, Box<PaintDefinition>>>, + paint_definitions: DomRefCell<HashMapTracedValues<Atom, Box<PaintDefinition>>>, /// <https://drafts.css-houdini.org/css-paint-api/#paint-class-instances> #[ignore_malloc_size_of = "mozjs"] - paint_class_instances: DomRefCell<HashMap<Atom, Box<Heap<JSVal>>>>, + paint_class_instances: DomRefCell<HashMapTracedValues<Atom, Box<Heap<JSVal>>>>, /// The most recent name the worklet was called with + #[no_trace] cached_name: DomRefCell<Atom>, /// The most recent size the worklet was drawn at + #[no_trace] cached_size: Cell<Size2D<f32, CSSPixel>>, /// The most recent device pixel ratio the worklet was drawn at + #[no_trace] cached_device_pixel_ratio: Cell<Scale<f32, CSSPixel, DevicePixel>>, /// The most recent properties the worklet was drawn at + #[no_trace] cached_properties: DomRefCell<Vec<(Atom, String)>>, /// The most recent arguments the worklet was drawn at cached_arguments: DomRefCell<Vec<String>>, /// The most recent result + #[no_trace] cached_result: DomRefCell<DrawAPaintImageResult>, } diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs index 3d1b4d6d112..48b572da260 100644 --- a/components/script/dom/pannernode.rs +++ b/components/script/dom/pannernode.rs @@ -42,8 +42,10 @@ pub struct PannerNode { orientation_y: Dom<AudioParam>, orientation_z: Dom<AudioParam>, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] panning_model: Cell<PanningModel>, #[ignore_malloc_size_of = "servo_media"] + #[no_trace] distance_model: Cell<DistanceModel>, ref_distance: Cell<f64>, max_distance: Cell<f64>, diff --git a/components/script/dom/raredata.rs b/components/script/dom/raredata.rs index 9d4a82d63d6..1a4916f1694 100644 --- a/components/script/dom/raredata.rs +++ b/components/script/dom/raredata.rs @@ -47,7 +47,9 @@ pub struct ElementRareData { pub custom_element_state: CustomElementState, /// The "name" content attribute; not used as frequently as id, but used /// in named getter loops so it's worth looking up quickly when present + #[no_trace] pub name_attribute: Option<Atom>, /// The client rect reported by layout. + #[no_trace] pub client_rect: Option<LayoutValue<Rect<i32>>>, } diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index da9b57aab13..26234e7ab68 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -48,6 +48,7 @@ use std::str::FromStr; #[dom_struct] pub struct Request { reflector_: Reflector, + #[no_trace] request: DomRefCell<NetTraitsRequest>, body_stream: MutNullableDom<ReadableStream>, headers: MutNullableDom<Headers>, diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index dbfd1653fd6..bf4d858c9c3 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -40,10 +40,13 @@ pub struct Response { headers_reflector: MutNullableDom<Headers>, /// `None` can be considered a StatusCode of `0`. #[ignore_malloc_size_of = "Defined in hyper"] + #[no_trace] status: DomRefCell<Option<StatusCode>>, raw_status: DomRefCell<Option<(u16, Vec<u8>)>>, response_type: DomRefCell<DOMResponseType>, + #[no_trace] url: DomRefCell<Option<ServoUrl>>, + #[no_trace] url_list: DomRefCell<Vec<ServoUrl>>, /// The stream of https://fetch.spec.whatwg.org/#body. body_stream: MutNullableDom<ReadableStream>, diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index df954136867..93600b4f209 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -59,6 +59,7 @@ use std::rc::Rc; pub struct RTCPeerConnection { eventtarget: EventTarget, #[ignore_malloc_size_of = "defined in servo-media"] + #[no_trace] controller: DomRefCell<Option<WebRtcController>>, closed: Cell<bool>, // Helps track state changes between the time createOffer/createAnswer diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs index bcbdd158a40..b01fc2a1d97 100644 --- a/components/script/dom/serviceworker.rs +++ b/components/script/dom/serviceworker.rs @@ -34,8 +34,10 @@ pub type TrustedServiceWorkerAddress = Trusted<ServiceWorker>; pub struct ServiceWorker { eventtarget: EventTarget, script_url: DomRefCell<String>, + #[no_trace] scope_url: ServoUrl, state: Cell<ServiceWorkerState>, + #[no_trace] worker_id: ServiceWorkerId, } diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index cbd38c0fc42..fff0f9b9ddc 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -131,6 +131,7 @@ pub enum MixedMessage { #[derive(Clone, JSTraceable)] pub struct ServiceWorkerChan { + #[no_trace] pub sender: Sender<ServiceWorkerScriptMsg>, } @@ -150,16 +151,16 @@ impl ScriptChan for ServiceWorkerChan { } } -unsafe_no_jsmanaged_fields!(TaskQueue<ServiceWorkerScriptMsg>); - #[dom_struct] pub struct ServiceWorkerGlobalScope { workerglobalscope: WorkerGlobalScope, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] task_queue: TaskQueue<ServiceWorkerScriptMsg>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] own_sender: Sender<ServiceWorkerScriptMsg>, /// A port on which a single "time-out" message can be received, @@ -167,16 +168,20 @@ pub struct ServiceWorkerGlobalScope { /// while still draining the task-queue // and running all enqueued, and not cancelled, tasks. #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] time_out_port: Receiver<Instant>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] swmanager_sender: IpcSender<ServiceWorkerMsg>, + #[no_trace] scope_url: ServoUrl, /// A receiver of control messages, /// currently only used to signal shutdown. #[ignore_malloc_size_of = "Channels are hard"] + #[no_trace] control_receiver: Receiver<ServiceWorkerControlMsg>, } diff --git a/components/script/dom/serviceworkerregistration.rs b/components/script/dom/serviceworkerregistration.rs index 0c1734b41cc..d9438880f7b 100644 --- a/components/script/dom/serviceworkerregistration.rs +++ b/components/script/dom/serviceworkerregistration.rs @@ -28,11 +28,13 @@ pub struct ServiceWorkerRegistration { installing: DomRefCell<Option<Dom<ServiceWorker>>>, waiting: DomRefCell<Option<Dom<ServiceWorker>>>, navigation_preload: MutNullableDom<NavigationPreloadManager>, + #[no_trace] scope: ServoUrl, navigation_preload_enabled: Cell<bool>, navigation_preload_header_value: DomRefCell<Option<ByteString>>, update_via_cache: ServiceWorkerUpdateViaCache, uninstalling: Cell<bool>, + #[no_trace] registration_id: ServiceWorkerRegistrationId, } diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs index 9a76278b178..6a87458d9f1 100644 --- a/components/script/dom/servoparser/async_html.rs +++ b/components/script/dom/servoparser/async_html.rs @@ -43,6 +43,7 @@ type ParseNodeId = usize; #[derive(Clone, JSTraceable, MallocSizeOf)] pub struct ParseNode { id: ParseNodeId, + #[no_trace] qual_name: Option<QualName>, } @@ -54,6 +55,7 @@ enum NodeOrText { #[derive(JSTraceable, MallocSizeOf)] struct Attribute { + #[no_trace] name: QualName, value: String, } @@ -67,6 +69,7 @@ enum ParseOperation { CreateElement { node: ParseNodeId, + #[no_trace] name: QualName, attrs: Vec<Attribute>, current_line: u64, @@ -130,6 +133,7 @@ enum ParseOperation { SetQuirksMode { #[ignore_malloc_size_of = "Defined in style"] + #[no_trace] mode: ServoQuirksMode, }, } @@ -200,11 +204,14 @@ fn create_buffer_queue(mut buffers: VecDeque<SendTendril<UTF8>>) -> BufferQueue pub struct Tokenizer { document: Dom<Document>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] receiver: Receiver<ToTokenizerMsg>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] html_tokenizer_sender: Sender<ToHtmlTokenizerMsg>, #[ignore_malloc_size_of = "Defined in std"] nodes: HashMap<ParseNodeId, Dom<Node>>, + #[no_trace] url: ServoUrl, parsing_algorithm: ParsingAlgorithm, } diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index ba114366aa2..44d0c3de1df 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -95,9 +95,11 @@ pub struct ServoParser { network_decoder: DomRefCell<Option<NetworkDecoder>>, /// Input received from network. #[ignore_malloc_size_of = "Defined in html5ever"] + #[no_trace] network_input: DomRefCell<BufferQueue>, /// Input received from script. Used only to support document.write(). #[ignore_malloc_size_of = "Defined in html5ever"] + #[no_trace] script_input: DomRefCell<BufferQueue>, /// The tokenizer of this parser. tokenizer: DomRefCell<Tokenizer>, @@ -116,6 +118,7 @@ pub struct ServoParser { // building the DOM. https://github.com/servo/servo/pull/19203 prefetch_tokenizer: DomRefCell<prefetch::Tokenizer>, #[ignore_malloc_size_of = "Defined in html5ever"] + #[no_trace] prefetch_input: DomRefCell<BufferQueue>, } @@ -1046,6 +1049,7 @@ fn insert( #[derive(JSTraceable, MallocSizeOf)] #[unrooted_must_root_lint::must_root] pub struct Sink { + #[no_trace] base_url: ServoUrl, document: Dom<Document>, current_line: u64, @@ -1401,6 +1405,7 @@ impl NetworkDecoder { #[derive(Default, JSTraceable)] struct NetworkSink { + #[no_trace] output: StrTendril, } diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs index 4de7e765b0c..f328b417bd0 100644 --- a/components/script/dom/servoparser/prefetch.rs +++ b/components/script/dom/servoparser/prefetch.rs @@ -75,12 +75,19 @@ impl Tokenizer { #[derive(JSTraceable)] struct PrefetchSink { + #[no_trace] origin: ImmutableOrigin, + #[no_trace] pipeline_id: PipelineId, + #[no_trace] document_url: ServoUrl, + #[no_trace] base_url: Option<ServoUrl>, + #[no_trace] referrer: Referrer, + #[no_trace] referrer_policy: Option<ReferrerPolicy>, + #[no_trace] resource_threads: ResourceThreads, prefetching: bool, } diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 8d8ad0dc7ba..10746abe10b 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -24,6 +24,7 @@ use servo_url::ServoUrl; #[dom_struct] pub struct Storage { reflector_: Reflector, + #[no_trace] storage_type: StorageType, } diff --git a/components/script/dom/stylepropertymapreadonly.rs b/components/script/dom/stylepropertymapreadonly.rs index 3881bfcdd87..f64c9cfc54a 100644 --- a/components/script/dom/stylepropertymapreadonly.rs +++ b/components/script/dom/stylepropertymapreadonly.rs @@ -12,14 +12,15 @@ use crate::dom::globalscope::GlobalScope; use dom_struct::dom_struct; use servo_atoms::Atom; use std::cmp::Ordering; -use std::collections::HashMap; use std::iter::Iterator; use style::custom_properties; +use super::bindings::trace::HashMapTracedValues; + #[dom_struct] pub struct StylePropertyMapReadOnly { reflector: Reflector, - entries: HashMap<Atom, Dom<CSSStyleValue>>, + entries: HashMapTracedValues<Atom, Dom<CSSStyleValue>>, } impl StylePropertyMapReadOnly { @@ -29,7 +30,7 @@ impl StylePropertyMapReadOnly { { StylePropertyMapReadOnly { reflector: Reflector::new(), - entries: entries.into_iter().collect(), + entries: HashMapTracedValues(entries.into_iter().collect()), } } @@ -78,6 +79,7 @@ impl StylePropertyMapReadOnlyMethods for StylePropertyMapReadOnly { fn GetProperties(&self) -> Vec<DOMString> { let mut result: Vec<DOMString> = self .entries + .0 .keys() .map(|key| DOMString::from(&**key)) .collect(); diff --git a/components/script/dom/textdecoder.rs b/components/script/dom/textdecoder.rs index 67d9d8790ea..dad1568a293 100644 --- a/components/script/dom/textdecoder.rs +++ b/components/script/dom/textdecoder.rs @@ -22,10 +22,12 @@ use std::cell::{Cell, RefCell}; #[allow(non_snake_case)] pub struct TextDecoder { reflector_: Reflector, + #[no_trace] encoding: &'static Encoding, fatal: bool, ignoreBOM: bool, #[ignore_malloc_size_of = "defined in encoding_rs"] + #[no_trace] decoder: RefCell<Decoder>, in_stream: RefCell<Vec<u8>>, do_not_flush: Cell<bool>, diff --git a/components/script/dom/transitionevent.rs b/components/script/dom/transitionevent.rs index ab32fefc1c3..cba2856b57e 100644 --- a/components/script/dom/transitionevent.rs +++ b/components/script/dom/transitionevent.rs @@ -21,6 +21,7 @@ use servo_atoms::Atom; #[dom_struct] pub struct TransitionEvent { event: Event, + #[no_trace] property_name: Atom, elapsed_time: Finite<f32>, pseudo_element: DOMString, diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index fe3631e93fb..9868ba0655b 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -28,6 +28,7 @@ pub struct URL { reflector_: Reflector, // https://url.spec.whatwg.org/#concept-url-url + #[no_trace] url: DomRefCell<ServoUrl>, // https://url.spec.whatwg.org/#dom-url-searchparams diff --git a/components/script/dom/vertexarrayobject.rs b/components/script/dom/vertexarrayobject.rs index fcf6461e2a8..eef71e32a86 100644 --- a/components/script/dom/vertexarrayobject.rs +++ b/components/script/dom/vertexarrayobject.rs @@ -17,6 +17,7 @@ use std::cell::Cell; #[unrooted_must_root_lint::must_root] pub struct VertexArrayObject { context: Dom<WebGLRenderingContext>, + #[no_trace] id: Option<WebGLVertexArrayId>, ever_bound: Cell<bool>, is_deleted: Cell<bool>, diff --git a/components/script/dom/webgl_extensions/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs index 97e5900960f..4873b3638e8 100644 --- a/components/script/dom/webgl_extensions/extensions.rs +++ b/components/script/dom/webgl_extensions/extensions.rs @@ -82,6 +82,7 @@ struct WebGLExtensionFeatures { gl_extensions: FnvHashSet<String>, disabled_tex_types: FnvHashSet<GLenum>, not_filterable_tex_types: FnvHashSet<GLenum>, + #[no_trace] effective_tex_internal_formats: FnvHashMap<TexFormatType, TexFormat>, /// WebGL Hint() targets enabled by extensions. hint_targets: FnvHashSet<GLenum>, @@ -166,8 +167,11 @@ impl WebGLExtensionFeatures { pub struct WebGLExtensions { extensions: DomRefCell<HashMap<String, Box<dyn WebGLExtensionWrapper>>>, features: DomRefCell<WebGLExtensionFeatures>, + #[no_trace] webgl_version: WebGLVersion, + #[no_trace] api_type: GlType, + #[no_trace] glsl_version: WebGLSLVersion, } @@ -466,5 +470,5 @@ impl WebGLExtensions { } // Helper structs -#[derive(Eq, Hash, JSTraceable, MallocSizeOf, PartialEq)] +#[derive(Eq, Hash, MallocSizeOf, PartialEq)] struct TexFormatType(TexFormat, u32); diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index f81270d8240..7deb030e6c6 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -24,6 +24,7 @@ fn target_is_copy_buffer(target: u32) -> bool { #[dom_struct] pub struct WebGLBuffer { webgl_object: WebGLObject, + #[no_trace] id: WebGLBufferId, /// The target to which this buffer was bound the first time target: Cell<Option<u32>>, diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 8172b1b6c4e..021ebb0fd0c 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -87,7 +87,9 @@ pub enum WebGLFramebufferAttachmentRoot { #[dom_struct] pub struct WebGLFramebuffer { webgl_object: WebGLObject, + #[no_trace] webgl_version: WebGLVersion, + #[no_trace] id: WebGLFramebufferId, target: Cell<Option<u32>>, is_deleted: Cell<bool>, diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 88cecf0296f..3ea2e6afef4 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -26,6 +26,7 @@ use std::cell::Cell; #[dom_struct] pub struct WebGLProgram { webgl_object: WebGLObject, + #[no_trace] id: WebGLProgramId, is_in_use: Cell<bool>, marked_for_deletion: Cell<bool>, @@ -34,8 +35,11 @@ pub struct WebGLProgram { link_generation: Cell<u64>, fragment_shader: MutNullableDom<WebGLShader>, vertex_shader: MutNullableDom<WebGLShader>, + #[no_trace] active_attribs: DomRefCell<Box<[ActiveAttribInfo]>>, + #[no_trace] active_uniforms: DomRefCell<Box<[ActiveUniformInfo]>>, + #[no_trace] active_uniform_blocks: DomRefCell<Box<[ActiveUniformBlockInfo]>>, transform_feedback_varyings_length: Cell<i32>, transform_feedback_mode: Cell<i32>, diff --git a/components/script/dom/webglquery.rs b/components/script/dom/webglquery.rs index 454fe72954e..c971d8442ff 100644 --- a/components/script/dom/webglquery.rs +++ b/components/script/dom/webglquery.rs @@ -18,6 +18,7 @@ use std::cell::Cell; #[dom_struct] pub struct WebGLQuery { webgl_object: WebGLObject, + #[no_trace] gl_id: WebGLQueryId, gl_target: Cell<Option<u32>>, marked_for_deletion: Cell<bool>, diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index 204fe9ab46e..6fe3d06d7fd 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -22,6 +22,7 @@ use std::cell::Cell; #[dom_struct] pub struct WebGLRenderbuffer { webgl_object: WebGLObject, + #[no_trace] id: WebGLRenderbufferId, ever_bound: Cell<bool>, is_deleted: Cell<bool>, diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 9a2b561adae..cedbbd5cc7e 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -166,13 +166,18 @@ pub struct WebGLRenderingContext { #[ignore_malloc_size_of = "Channels are hard"] webgl_sender: WebGLMessageSender, #[ignore_malloc_size_of = "Defined in webrender"] + #[no_trace] webrender_image: ImageKey, + #[no_trace] webgl_version: WebGLVersion, + #[no_trace] glsl_version: WebGLSLVersion, #[ignore_malloc_size_of = "Defined in surfman"] + #[no_trace] limits: GLLimits, canvas: Dom<HTMLCanvasElement>, #[ignore_malloc_size_of = "Defined in canvas_traits"] + #[no_trace] last_error: Cell<Option<WebGLError>>, texture_packing_alignment: Cell<u8>, texture_unpacking_settings: Cell<TextureUnpacking>, @@ -190,6 +195,7 @@ pub struct WebGLRenderingContext { current_scissor: Cell<(i32, i32, u32, u32)>, #[ignore_malloc_size_of = "Because it's small"] current_clear_color: Cell<(f32, f32, f32, f32)>, + #[no_trace] size: Cell<Size2D<u32>>, extension_manager: WebGLExtensions, capabilities: Capabilities, @@ -198,6 +204,7 @@ pub struct WebGLRenderingContext { default_vao_webgl2: DomOnceCell<WebGLVertexArrayObject>, current_vao_webgl2: MutNullableDom<WebGLVertexArrayObject>, textures: Textures, + #[no_trace] api_type: GlType, } @@ -4886,7 +4893,9 @@ pub enum TexSource { #[derive(JSTraceable)] pub struct WebGLCommandSender { + #[no_trace] sender: WebGLChan, + #[no_trace] waker: Option<Box<dyn EventLoopWaker>>, } @@ -4906,8 +4915,10 @@ impl WebGLCommandSender { #[derive(JSTraceable, MallocSizeOf)] pub(crate) struct WebGLMessageSender { + #[no_trace] sender: WebGLMsgSender, #[ignore_malloc_size_of = "traits are cumbersome"] + #[no_trace] waker: Option<Box<dyn EventLoopWaker>>, } diff --git a/components/script/dom/webglsampler.rs b/components/script/dom/webglsampler.rs index 063decffe8f..ec68328fab9 100644 --- a/components/script/dom/webglsampler.rs +++ b/components/script/dom/webglsampler.rs @@ -16,6 +16,7 @@ use std::cell::Cell; #[dom_struct] pub struct WebGLSampler { webgl_object: WebGLObject, + #[no_trace] gl_id: WebGLSamplerId, marked_for_deletion: Cell<bool>, } diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index 3f5f6c1cf43..ad61db47a5a 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -33,6 +33,7 @@ pub enum ShaderCompilationStatus { #[dom_struct] pub struct WebGLShader { webgl_object: WebGLObject, + #[no_trace] id: WebGLShaderId, gl_type: u32, source: DomRefCell<DOMString>, diff --git a/components/script/dom/webglsync.rs b/components/script/dom/webglsync.rs index a6288f69c1e..c26eb839eed 100644 --- a/components/script/dom/webglsync.rs +++ b/components/script/dom/webglsync.rs @@ -17,6 +17,7 @@ use std::cell::Cell; #[dom_struct] pub struct WebGLSync { webgl_object: WebGLObject, + #[no_trace] sync_id: WebGLSyncId, marked_for_deletion: Cell<bool>, client_wait_status: Cell<Option<u32>>, diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index ccb005cc393..b4562e36e76 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -48,6 +48,7 @@ jsmanaged_array!(MAX_LEVEL_COUNT * MAX_FACE_COUNT); #[dom_struct] pub struct WebGLTexture { webgl_object: WebGLObject, + #[no_trace] id: WebGLTextureId, /// The target to which this texture was bound the first time target: Cell<Option<u32>>, @@ -532,7 +533,9 @@ pub struct ImageInfo { width: u32, height: u32, depth: u32, + #[no_trace] internal_format: TexFormat, + #[no_trace] data_type: Option<TexDataType>, } @@ -581,6 +584,7 @@ pub enum TexCompressionValidation { #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf)] pub struct TexCompression { + #[no_trace] pub format: TexFormat, pub bytes_per_block: u8, pub block_width: u8, diff --git a/components/script/dom/webgluniformlocation.rs b/components/script/dom/webgluniformlocation.rs index 153b2e651ba..a579743399b 100644 --- a/components/script/dom/webgluniformlocation.rs +++ b/components/script/dom/webgluniformlocation.rs @@ -14,7 +14,9 @@ use dom_struct::dom_struct; pub struct WebGLUniformLocation { reflector_: Reflector, id: i32, + #[no_trace] context_id: WebGLContextId, + #[no_trace] program_id: WebGLProgramId, link_generation: u64, size: Option<i32>, diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 5b5815f90c3..75b30001d21 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -101,11 +101,13 @@ fn fail_the_websocket_connection( #[dom_struct] pub struct WebSocket { eventtarget: EventTarget, + #[no_trace] url: ServoUrl, ready_state: Cell<WebSocketRequestState>, buffered_amount: Cell<u64>, clearing_buffer: Cell<bool>, //Flag to tell if there is a running thread to clear buffered_amount #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] sender: IpcSender<WebSocketDomAction>, binary_type: Cell<BinaryType>, protocol: DomRefCell<String>, //Subprotocol selected by server diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 705d976c97e..65dc4118583 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -157,6 +157,8 @@ use url::Position; use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel}; use webrender_api::{DocumentId, ExternalScrollId}; +use super::bindings::trace::HashMapTracedValues; + /// Current state of the window object #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)] enum WindowState { @@ -199,8 +201,10 @@ pub struct Window { task_manager: TaskManager, navigator: MutNullableDom<Navigator>, #[ignore_malloc_size_of = "Arc"] + #[no_trace] image_cache: Arc<dyn ImageCache>, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] image_cache_chan: Sender<ImageCacheMsg>, window_proxy: MutNullableDom<WindowProxy>, document: MutNullableDom<Document>, @@ -217,14 +221,18 @@ pub struct Window { /// For sending timeline markers. Will be ignored if /// no devtools server + #[no_trace] devtools_markers: DomRefCell<HashSet<TimelineMarkerType>>, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] devtools_marker_sender: DomRefCell<Option<IpcSender<Option<TimelineMarker>>>>, /// Pending resize event, if any. + #[no_trace] resize_event: Cell<Option<(WindowSizeData, WindowSizeType)>>, /// Parent id associated with this page, if any. + #[no_trace] parent_info: Option<PipelineId>, /// Global static data related to the DOM. @@ -239,23 +247,28 @@ pub struct Window { /// This channel shouldn't be accessed directly, but through `Window::layout_chan()`, /// which returns `None` if there's no layout thread anymore. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] layout_chan: Sender<Msg>, /// A handle to perform RPC calls into the layout, quickly. #[ignore_malloc_size_of = "trait objects are hard"] + #[no_trace] layout_rpc: Box<dyn LayoutRPC + Send + 'static>, /// The current size of the window, in pixels. + #[no_trace] window_size: Cell<WindowSizeData>, /// A handle for communicating messages to the bluetooth thread. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] bluetooth_thread: IpcSender<BluetoothRequest>, bluetooth_extra_permission_data: BluetoothExtraPermissionData, /// An enlarged rectangle around the page contents visible in the viewport, used /// to prevent creating display list items for content that is far away from the viewport. + #[no_trace] page_clip_rect: Cell<UntypedRect<Au>>, /// Flag to suppress reflows. The first reflow will come either with @@ -268,16 +281,19 @@ pub struct Window { /// A channel for communicating results of async scripts back to the webdriver server #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] webdriver_script_chan: DomRefCell<Option<IpcSender<WebDriverJSResult>>>, /// The current state of the window object current_state: Cell<WindowState>, + #[no_trace] current_viewport: Cell<UntypedRect<Au>>, error_reporter: CSSErrorReporter, /// A list of scroll offsets for each scrollable element. + #[no_trace] scroll_offsets: DomRefCell<HashMap<OpaqueNode, Vector2D<f32, LayoutPixel>>>, /// All the MediaQueryLists we need to update @@ -287,16 +303,18 @@ pub struct Window { /// A handle for communicating messages to the WebGL thread, if available. #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] webgl_chan: Option<WebGLChan>, #[ignore_malloc_size_of = "defined in webxr"] + #[no_trace] webxr_registry: webxr_api::Registry, /// All of the elements that have an outstanding image request that was /// initiated by layout during a reflow. They are stored in the script thread /// to ensure that the element can be marked dirty when the image data becomes /// available at some point in the future. - pending_layout_images: DomRefCell<HashMap<PendingImageId, Vec<Dom<Node>>>>, + pending_layout_images: DomRefCell<HashMapTracedValues<PendingImageId, Vec<Dom<Node>>>>, /// Directory to store unminified scripts for this window if unminify-js /// opt is enabled. @@ -311,6 +329,7 @@ pub struct Window { paint_worklet: MutNullableDom<Worklet>, /// The Webrender Document id associated with this window. #[ignore_malloc_size_of = "defined in webrender_api"] + #[no_trace] webrender_document: DocumentId, /// Flag to identify whether mutation observers are present(true)/absent(false) @@ -318,6 +337,7 @@ pub struct Window { /// Webrender API Sender #[ignore_malloc_size_of = "Wraps an IpcSender"] + #[no_trace] webrender_api_sender: WebrenderIpcSender, /// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete. @@ -348,10 +368,12 @@ pub struct Window { /// Window's GL context from application #[ignore_malloc_size_of = "defined in script_thread"] + #[no_trace] player_context: WindowGLContext, /// A mechanism to force the compositor to process events. #[ignore_malloc_size_of = "traits are cumbersome"] + #[no_trace] event_loop_waker: Option<Box<dyn EventLoopWaker>>, visible: Cell<bool>, @@ -1469,6 +1491,7 @@ impl WindowMethods for Window { // Step 4. #[derive(JSTraceable, MallocSizeOf)] struct WindowNamedGetter { + #[no_trace] name: Atom, } impl CollectionFilter for WindowNamedGetter { @@ -1509,7 +1532,7 @@ impl WindowMethods for Window { let document = self.Document(); let name_map = document.name_map(); - for (name, elements) in &*name_map { + for (name, elements) in &(*name_map).0 { if name.is_empty() { continue; } @@ -1521,7 +1544,7 @@ impl WindowMethods for Window { } } let id_map = document.id_map(); - for (id, elements) in &*id_map { + for (id, elements) in &(*id_map).0 { if id.is_empty() { continue; } @@ -2666,7 +2689,7 @@ impl Window { /// Create a new cached instance of the given value. pub fn cache_layout_value<T>(&self, value: T) -> LayoutValue<T> where - T: Copy + JSTraceable + MallocSizeOf, + T: Copy + MallocSizeOf, { LayoutValue::new(self.layout_marker.borrow().clone(), value) } @@ -2676,14 +2699,21 @@ impl Window { /// value can only be read as long as the associated layout marker that is considered /// valid. It will automatically become unavailable when the next layout operation is /// performed. -#[derive(JSTraceable, MallocSizeOf)] -pub struct LayoutValue<T: JSTraceable + MallocSizeOf> { +#[derive(MallocSizeOf)] +pub struct LayoutValue<T: MallocSizeOf> { #[ignore_malloc_size_of = "Rc is hard"] is_valid: Rc<Cell<bool>>, value: T, } -impl<T: Copy + JSTraceable + MallocSizeOf> LayoutValue<T> { +#[allow(unsafe_code)] +unsafe impl<T: JSTraceable + MallocSizeOf> JSTraceable for LayoutValue<T> { + unsafe fn trace(&self, trc: *mut js::jsapi::JSTracer) { + self.value.trace(trc) + } +} + +impl<T: Copy + MallocSizeOf> LayoutValue<T> { fn new(marker: Rc<Cell<bool>>, value: T) -> Self { LayoutValue { is_valid: marker, diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 9ae85a30fc6..a2b1cbfe7f4 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -72,13 +72,16 @@ pub struct WindowProxy { /// The id of the browsing context. /// In the case that this is a nested browsing context, this is the id /// of the container. + #[no_trace] browsing_context_id: BrowsingContextId, // https://html.spec.whatwg.org/multipage/#opener-browsing-context + #[no_trace] opener: Option<BrowsingContextId>, /// The frame id of the top-level ancestor browsing context. /// In the case that this is a top-level window, this is our id. + #[no_trace] top_level_browsing_context_id: TopLevelBrowsingContextId, /// The name of the browsing context (sometimes, but not always, @@ -89,6 +92,7 @@ pub struct WindowProxy { /// We do not try to keep the pipeline id for documents in other threads, /// as this would require the constellation notifying many script threads about /// the change, which could be expensive. + #[no_trace] currently_active: Cell<Option<PipelineId>>, /// Has the browsing context been discarded? @@ -110,12 +114,15 @@ pub struct WindowProxy { delaying_load_events_mode: Cell<bool>, /// The creator browsing context's base url. + #[no_trace] creator_base_url: Option<ServoUrl>, /// The creator browsing context's url. + #[no_trace] creator_url: Option<ServoUrl>, /// The creator browsing context's origin. + #[no_trace] creator_origin: Option<ImmutableOrigin>, } diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index fbc0c0cd138..321474f31ee 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -46,6 +46,7 @@ pub type TrustedWorkerAddress = Trusted<Worker>; pub struct Worker { eventtarget: EventTarget, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] /// Sender to the Receiver associated with the DedicatedWorkerGlobalScope /// this Worker created. sender: Sender<DedicatedWorkerScriptMsg>, diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 3aaeca56d3b..a41946926db 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -97,7 +97,9 @@ pub struct WorkerGlobalScope { worker_name: DOMString, worker_type: WorkerType, + #[no_trace] worker_id: WorkerId, + #[no_trace] worker_url: DomRefCell<ServoUrl>, #[ignore_malloc_size_of = "Arc"] closing: Arc<AtomicBool>, @@ -107,11 +109,13 @@ pub struct WorkerGlobalScope { navigator: MutNullableDom<WorkerNavigator>, #[ignore_malloc_size_of = "Defined in ipc-channel"] + #[no_trace] /// Optional `IpcSender` for sending the `DevtoolScriptControlMsg` /// to the server from within the worker from_devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] /// This `Receiver` will be ignored later if the corresponding /// `IpcSender` doesn't exist from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs index c3974e3e1ce..cbe7996899c 100644 --- a/components/script/dom/workerlocation.rs +++ b/components/script/dom/workerlocation.rs @@ -15,6 +15,7 @@ use servo_url::{ImmutableOrigin, ServoUrl}; #[dom_struct] pub struct WorkerLocation { reflector_: Reflector, + #[no_trace] url: ServoUrl, } diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 7455e2a5775..b1f9fc83ebe 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -169,7 +169,7 @@ impl WorkletMethods for Worklet { /// A guid for worklets. #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)] -pub struct WorkletId(Uuid); +pub struct WorkletId(#[no_trace] Uuid); malloc_size_of_is_0!(WorkletId); @@ -251,12 +251,18 @@ impl PendingTasksStruct { #[derive(Clone, JSTraceable)] pub struct WorkletThreadPool { // Channels to send data messages to the three roles. + #[no_trace] primary_sender: Sender<WorkletData>, + #[no_trace] hot_backup_sender: Sender<WorkletData>, + #[no_trace] cold_backup_sender: Sender<WorkletData>, // Channels to send control messages to the three threads. + #[no_trace] control_sender_0: Sender<WorkletControl>, + #[no_trace] control_sender_1: Sender<WorkletControl>, + #[no_trace] control_sender_2: Sender<WorkletControl>, } @@ -746,6 +752,7 @@ impl WorkletThread { pub struct WorkletExecutor { worklet_id: WorkletId, #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] primary_sender: Sender<WorkletData>, } diff --git a/components/script/dom/workletglobalscope.rs b/components/script/dom/workletglobalscope.rs index 96270b8fab8..888a2058bc3 100644 --- a/components/script/dom/workletglobalscope.rs +++ b/components/script/dom/workletglobalscope.rs @@ -41,9 +41,11 @@ pub struct WorkletGlobalScope { /// The global for this worklet. globalscope: GlobalScope, /// The base URL for this worklet. + #[no_trace] base_url: ServoUrl, /// Sender back to the script thread #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] to_script_thread_sender: Sender<MainThreadScriptMsg>, /// Worklet task executor executor: WorkletExecutor, diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 4f901a13b3b..669edfb1c71 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -141,16 +141,22 @@ pub struct XMLHttpRequest { #[ignore_malloc_size_of = "Defined in rust-mozjs"] response_json: Heap<JSVal>, #[ignore_malloc_size_of = "Defined in hyper"] + #[no_trace] response_headers: DomRefCell<HeaderMap>, #[ignore_malloc_size_of = "Defined in hyper"] + #[no_trace] override_mime_type: DomRefCell<Option<Mime>>, + #[no_trace] override_charset: DomRefCell<Option<&'static Encoding>>, // Associated concepts #[ignore_malloc_size_of = "Defined in hyper"] + #[no_trace] request_method: DomRefCell<Method>, + #[no_trace] request_url: DomRefCell<Option<ServoUrl>>, #[ignore_malloc_size_of = "Defined in hyper"] + #[no_trace] request_headers: DomRefCell<HeaderMap>, request_body_len: Cell<usize>, sync: Cell<bool>, @@ -162,7 +168,9 @@ pub struct XMLHttpRequest { fetch_time: Cell<i64>, generation_id: Cell<GenerationId>, response_status: Cell<Result<(), ()>>, + #[no_trace] referrer: Referrer, + #[no_trace] referrer_policy: Option<ReferrerPolicy>, canceller: DomRefCell<FetchCanceller>, } diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs index 5086626e256..6274ca78387 100644 --- a/components/script/dom/xrframe.rs +++ b/components/script/dom/xrframe.rs @@ -28,6 +28,7 @@ pub struct XRFrame { reflector_: Reflector, session: Dom<XRSession>, #[ignore_malloc_size_of = "defined in webxr_api"] + #[no_trace] data: Frame, active: Cell<bool>, animation_frame: Cell<bool>, diff --git a/components/script/dom/xrhittestresult.rs b/components/script/dom/xrhittestresult.rs index 9c7c36a24ef..dd35043e187 100644 --- a/components/script/dom/xrhittestresult.rs +++ b/components/script/dom/xrhittestresult.rs @@ -16,6 +16,7 @@ use webxr_api::HitTestResult; pub struct XRHitTestResult { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webxr"] + #[no_trace] result: HitTestResult, frame: Dom<XRFrame>, } diff --git a/components/script/dom/xrhittestsource.rs b/components/script/dom/xrhittestsource.rs index a665a9f1b71..913193cfae3 100644 --- a/components/script/dom/xrhittestsource.rs +++ b/components/script/dom/xrhittestsource.rs @@ -14,6 +14,7 @@ use webxr_api::HitTestId; pub struct XRHitTestSource { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webxr"] + #[no_trace] id: HitTestId, session: Dom<XRSession>, } diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index 592ced2f10d..8b3f3f793e4 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -24,6 +24,7 @@ pub struct XRInputSource { reflector: Reflector, session: Dom<XRSession>, #[ignore_malloc_size_of = "Defined in rust-webxr"] + #[no_trace] info: InputSource, target_ray_space: MutNullableDom<XRSpace>, grip_space: MutNullableDom<XRSpace>, diff --git a/components/script/dom/xrjointspace.rs b/components/script/dom/xrjointspace.rs index 4b31b0bc6a2..57b0b88f761 100644 --- a/components/script/dom/xrjointspace.rs +++ b/components/script/dom/xrjointspace.rs @@ -15,8 +15,10 @@ use webxr_api::{BaseSpace, Frame, InputId, Joint, JointFrame, Space}; pub struct XRJointSpace { xrspace: XRSpace, #[ignore_malloc_size_of = "defined in rust-webxr"] + #[no_trace] input: InputId, #[ignore_malloc_size_of = "defined in rust-webxr"] + #[no_trace] joint: Joint, } diff --git a/components/script/dom/xrlayer.rs b/components/script/dom/xrlayer.rs index 7328609d89f..7319eb482dd 100644 --- a/components/script/dom/xrlayer.rs +++ b/components/script/dom/xrlayer.rs @@ -21,6 +21,7 @@ pub struct XRLayer { /// If none, the session is inline (the composition disabled flag is true) /// and this is a XRWebGLLayer. #[ignore_malloc_size_of = "Layer ids don't heap-allocate"] + #[no_trace] layer_id: Option<LayerId>, } diff --git a/components/script/dom/xrray.rs b/components/script/dom/xrray.rs index f39813a4ddc..1847e985362 100644 --- a/components/script/dom/xrray.rs +++ b/components/script/dom/xrray.rs @@ -24,6 +24,7 @@ use webxr_api::{ApiSpace, Ray}; pub struct XRRay { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webxr"] + #[no_trace] ray: Ray<ApiSpace>, #[ignore_malloc_size_of = "defined in mozjs"] matrix: Heap<*mut JSObject>, diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index 74f5e348137..1ee7f4304ea 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -27,6 +27,7 @@ pub struct XRRigidTransform { position: MutNullableDom<DOMPointReadOnly>, orientation: MutNullableDom<DOMPointReadOnly>, #[ignore_malloc_size_of = "defined in euclid"] + #[no_trace] transform: ApiRigidTransform, inverse: MutNullableDom<XRRigidTransform>, #[ignore_malloc_size_of = "defined in mozjs"] diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 73f2bc4ce88..0afa821211f 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -43,7 +43,6 @@ use ipc_channel::router::ROUTER; use metrics::ToMs; use profile_traits::ipc; use std::cell::Cell; -use std::collections::HashMap; use std::f64::consts::{FRAC_PI_2, PI}; use std::mem; use std::rc::Rc; @@ -54,6 +53,8 @@ use webxr_api::{ View, Viewer, Visibility, }; +use super::bindings::trace::HashMapTracedValues; + #[dom_struct] pub struct XRSession { eventtarget: EventTarget, @@ -62,11 +63,13 @@ pub struct XRSession { visibility_state: Cell<XRVisibilityState>, viewer_space: MutNullableDom<XRSpace>, #[ignore_malloc_size_of = "defined in webxr"] + #[no_trace] session: DomRefCell<Session>, frame_requested: Cell<bool>, pending_render_state: MutNullableDom<XRRenderState>, active_render_state: MutDom<XRRenderState>, /// Cached projection matrix for inline sessions + #[no_trace] inline_projection_matrix: DomRefCell<Transform3D<f32, Viewer, Display>>, next_raf_id: Cell<i32>, @@ -81,9 +84,10 @@ pub struct XRSession { /// https://immersive-web.github.io/webxr/#ended ended: Cell<bool>, #[ignore_malloc_size_of = "defined in webxr"] + #[no_trace] next_hit_test_id: Cell<HitTestId>, #[ignore_malloc_size_of = "defined in webxr"] - pending_hit_test_promises: DomRefCell<HashMap<HitTestId, Rc<Promise>>>, + pending_hit_test_promises: DomRefCell<HashMapTracedValues<HitTestId, Rc<Promise>>>, /// Opaque framebuffers need to know the session is "outside of a requestAnimationFrame" /// https://immersive-web.github.io/webxr/#opaque-framebuffer outside_raf: Cell<bool>, @@ -115,7 +119,7 @@ impl XRSession { end_promises: DomRefCell::new(vec![]), ended: Cell::new(false), next_hit_test_id: Cell::new(HitTestId(0)), - pending_hit_test_promises: DomRefCell::new(HashMap::new()), + pending_hit_test_promises: DomRefCell::new(HashMapTracedValues::new()), outside_raf: Cell::new(true), } } diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 15e4f9e65f4..907aa2935d1 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -40,6 +40,7 @@ pub struct XRSystem { active_immersive_session: MutNullableDom<XRSession>, active_inline_sessions: DomRefCell<Vec<Dom<XRSession>>>, test: MutNullableDom<XRTest>, + #[no_trace] pipeline: PipelineId, } diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index b849b1d03ba..ec3edde82e0 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -25,6 +25,7 @@ pub struct XRView { #[ignore_malloc_size_of = "mozjs"] proj: Heap<*mut JSObject>, #[ignore_malloc_size_of = "defined in rust-webxr"] + #[no_trace] view: View<ApiSpace>, transform: Dom<XRRigidTransform>, } diff --git a/components/script/dom/xrviewport.rs b/components/script/dom/xrviewport.rs index 30872bae0c4..968cb573264 100644 --- a/components/script/dom/xrviewport.rs +++ b/components/script/dom/xrviewport.rs @@ -13,6 +13,7 @@ use webxr_api::Viewport; #[dom_struct] pub struct XRViewport { reflector_: Reflector, + #[no_trace] viewport: Rect<i32, Viewport>, } diff --git a/components/script/dom/xrwebglsubimage.rs b/components/script/dom/xrwebglsubimage.rs index 0813bd85d9e..d9d5420dfe3 100644 --- a/components/script/dom/xrwebglsubimage.rs +++ b/components/script/dom/xrwebglsubimage.rs @@ -17,6 +17,7 @@ pub struct XRWebGLSubImage { color_texture: Dom<WebGLTexture>, depth_stencil_texture: Option<Dom<WebGLTexture>>, image_index: Option<u32>, + #[no_trace] size: Size2D<u32, Viewport>, } diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 9de88ba0277..5e88d46dffb 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -52,6 +52,7 @@ struct FetchContext { #[derive(Default, JSTraceable, MallocSizeOf)] pub struct FetchCanceller { #[ignore_malloc_size_of = "channels are hard"] + #[no_trace] cancel_chan: Option<ipc::IpcSender<()>>, } diff --git a/components/script/lib.rs b/components/script/lib.rs index 66c878dbbde..3d46f4f797c 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -8,10 +8,17 @@ #![feature(register_tool)] #![deny(unsafe_code)] #![doc = "The script crate contains all matters DOM."] -#![cfg_attr(not(feature = "unrooted_must_root_lint"), allow(unknown_lints))] +#![cfg_attr( + not(any( + feature = "unrooted_must_root_lint", + feature = "trace_in_no_trace_lint" + )), + allow(unknown_lints) +)] #![allow(deprecated)] // FIXME: Can we make `allow` only apply to the `plugin` crate attribute? #![plugin(script_plugins)] #![register_tool(unrooted_must_root_lint)] +#![register_tool(trace_in_no_trace_lint)] #[macro_use] extern crate bitflags; diff --git a/components/script/microtask.rs b/components/script/microtask.rs index 10322bb2fef..4a810fd0cfd 100644 --- a/components/script/microtask.rs +++ b/components/script/microtask.rs @@ -53,6 +53,7 @@ pub trait MicrotaskRunnable { pub struct EnqueuedPromiseCallback { #[ignore_malloc_size_of = "Rc has unclear ownership"] pub callback: Rc<PromiseJobCallback>, + #[no_trace] pub pipeline: PipelineId, pub is_user_interacting: bool, } @@ -63,6 +64,7 @@ pub struct EnqueuedPromiseCallback { pub struct UserMicrotask { #[ignore_malloc_size_of = "Rc has unclear ownership"] pub callback: Rc<VoidFunction>, + #[no_trace] pub pipeline: PipelineId, } diff --git a/components/script/script_module.rs b/components/script/script_module.rs index 9ba8dd523a0..01fe01e3472 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -145,7 +145,7 @@ impl ModuleScript { #[derive(Clone, Debug, Eq, Hash, JSTraceable, PartialEq)] pub enum ModuleIdentity { ScriptId(ScriptId), - ModuleUrl(ServoUrl), + ModuleUrl(#[no_trace] ServoUrl), } impl ModuleIdentity { @@ -165,6 +165,7 @@ impl ModuleIdentity { #[derive(JSTraceable)] pub struct ModuleTree { + #[no_trace] url: ServoUrl, text: DomRefCell<Rc<DOMString>>, record: DomRefCell<Option<ModuleObject>>, @@ -178,11 +179,15 @@ pub struct ModuleTree { // (https://infra.spec.whatwg.org/#ordered-map), however we can usually get away with using // stdlib maps and sets because we rarely iterate over them. parent_identities: DomRefCell<IndexSet<ModuleIdentity>>, + #[no_trace] descendant_urls: DomRefCell<IndexSet<ServoUrl>>, // A set to memoize which descendants are under fetching + #[no_trace] incomplete_fetch_urls: DomRefCell<IndexSet<ServoUrl>>, + #[no_trace] visited_urls: DomRefCell<HashSet<ServoUrl>>, rethrow_error: DomRefCell<Option<RethrowError>>, + #[no_trace] network_error: DomRefCell<Option<NetworkError>>, // A promise for owners to execute when the module tree // is finished @@ -324,7 +329,7 @@ impl ModuleTree { let module_map = global.get_module_map().borrow(); let mut discovered_urls = HashSet::new(); - return ModuleTree::recursive_check_descendants(&self, &module_map, &mut discovered_urls); + return ModuleTree::recursive_check_descendants(&self, &module_map.0, &mut discovered_urls); } // We just leverage the power of Promise to run the task for `finish` the owner. @@ -926,7 +931,7 @@ impl ModuleOwner { let network_error = module_tree.get_network_error().borrow(); match network_error.as_ref() { - Some(network_error) => Err(network_error.clone()), + Some(network_error) => Err(network_error.clone().into()), None => match module_identity { ModuleIdentity::ModuleUrl(script_src) => Ok(ScriptOrigin::external( Rc::clone(&module_tree.get_text().borrow()), @@ -1296,11 +1301,15 @@ pub unsafe extern "C" fn host_import_module_dynamically( #[derive(Clone, JSTraceable, MallocSizeOf)] /// <https://html.spec.whatwg.org/multipage/#script-fetch-options> pub struct ScriptFetchOptions { + #[no_trace] pub referrer: Referrer, pub integrity_metadata: String, + #[no_trace] pub credentials_mode: CredentialsMode, pub cryptographic_nonce: String, + #[no_trace] pub parser_metadata: ParserMetadata, + #[no_trace] pub referrer_policy: Option<ReferrerPolicy>, } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 96ea03881d4..e3051a0f8c2 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -34,7 +34,7 @@ use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::ThreadLocalStackRoots; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom, RootCollection}; use crate::dom::bindings::str::DOMString; -use crate::dom::bindings::trace::JSTraceable; +use crate::dom::bindings::trace::{HashMapTracedValues, JSTraceable}; use crate::dom::customelementregistry::{ CallbackReaction, CustomElementDefinition, CustomElementReactionStack, }; @@ -185,26 +185,36 @@ pub unsafe fn trace_thread(tr: *mut JSTracer) { #[derive(JSTraceable)] struct InProgressLoad { /// The pipeline which requested this load. + #[no_trace] pipeline_id: PipelineId, /// The browsing context being loaded into. + #[no_trace] browsing_context_id: BrowsingContextId, /// The top level ancestor browsing context. + #[no_trace] top_level_browsing_context_id: TopLevelBrowsingContextId, /// The parent pipeline and frame type associated with this load, if any. + #[no_trace] parent_info: Option<PipelineId>, /// The opener, if this is an auxiliary. + #[no_trace] opener: Option<BrowsingContextId>, /// The current window size associated with this pipeline. + #[no_trace] window_size: WindowSizeData, /// Channel to the layout thread associated with this pipeline. + #[no_trace] layout_chan: Sender<message::Msg>, /// The activity level of the document (inactive, active or fully active). + #[no_trace] activity: DocumentActivity, /// Window is visible. is_visible: bool, /// The requested URL of the load. + #[no_trace] url: ServoUrl, /// The origin for the document + #[no_trace] origin: MutableOrigin, /// Timestamp reporting the time when the browser started this load. navigation_start: u64, @@ -398,7 +408,7 @@ impl ScriptPort for Receiver<(TrustedServiceWorkerAddress, CommonScriptMsg)> { /// Encapsulates internal communication of shared messages within the script thread. #[derive(JSTraceable)] -pub struct SendableMainThreadScriptChan(pub Sender<CommonScriptMsg>); +pub struct SendableMainThreadScriptChan(#[no_trace] pub Sender<CommonScriptMsg>); impl ScriptChan for SendableMainThreadScriptChan { fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { @@ -412,7 +422,7 @@ impl ScriptChan for SendableMainThreadScriptChan { /// Encapsulates internal communication of main thread messages within the script thread. #[derive(JSTraceable)] -pub struct MainThreadScriptChan(pub Sender<MainThreadScriptMsg>); +pub struct MainThreadScriptChan(#[no_trace] pub Sender<MainThreadScriptMsg>); impl ScriptChan for MainThreadScriptChan { fn send(&self, msg: CommonScriptMsg) -> Result<(), ()> { @@ -436,13 +446,13 @@ impl OpaqueSender<CommonScriptMsg> for Sender<MainThreadScriptMsg> { #[derive(JSTraceable)] #[unrooted_must_root_lint::must_root] pub struct Documents { - map: HashMap<PipelineId, Dom<Document>>, + map: HashMapTracedValues<PipelineId, Dom<Document>>, } impl Documents { pub fn new() -> Documents { Documents { - map: HashMap::new(), + map: HashMapTracedValues::new(), } } @@ -522,17 +532,20 @@ pub struct ScriptThread { documents: DomRefCell<Documents>, /// The window proxies known by this thread /// TODO: this map grows, but never shrinks. Issue #15258. - window_proxies: DomRefCell<HashMap<BrowsingContextId, Dom<WindowProxy>>>, + window_proxies: DomRefCell<HashMapTracedValues<BrowsingContextId, Dom<WindowProxy>>>, /// A list of data pertaining to loads that have not yet received a network response incomplete_loads: DomRefCell<Vec<InProgressLoad>>, /// A vector containing parser contexts which have not yet been fully processed incomplete_parser_contexts: IncompleteParserContexts, /// Image cache for this script thread. + #[no_trace] image_cache: Arc<dyn ImageCache>, /// A handle to the resource thread. This is an `Arc` to avoid running out of file descriptors if /// there are many iframes. + #[no_trace] resource_threads: ResourceThreads, /// A handle to the bluetooth thread. + #[no_trace] bluetooth_thread: IpcSender<BluetoothRequest>, /// A queue of tasks to be executed in this script-thread. @@ -551,12 +564,15 @@ pub struct ScriptThread { dom_manipulation_task_sender: Box<dyn ScriptChan>, + #[no_trace] media_element_task_sender: Sender<MainThreadScriptMsg>, + #[no_trace] user_interaction_task_sender: Sender<MainThreadScriptMsg>, networking_task_sender: Box<dyn ScriptChan>, + #[no_trace] history_traversal_task_sender: Sender<MainThreadScriptMsg>, file_reading_task_sender: Box<dyn ScriptChan>, @@ -570,34 +586,45 @@ pub struct ScriptThread { remote_event_task_sender: Box<dyn ScriptChan>, /// A channel to hand out to threads that need to respond to a message from the script thread. + #[no_trace] control_chan: IpcSender<ConstellationControlMsg>, /// The port on which the constellation and layout threads can communicate with the /// script thread. + #[no_trace] control_port: Receiver<ConstellationControlMsg>, /// For communicating load url messages to the constellation + #[no_trace] script_sender: IpcSender<(PipelineId, ScriptMsg)>, /// A sender for new layout threads to communicate to the constellation. + #[no_trace] layout_to_constellation_chan: IpcSender<LayoutMsg>, /// The port on which we receive messages from the image cache + #[no_trace] image_cache_port: Receiver<ImageCacheMsg>, /// The channel on which the image cache can send messages to ourself. + #[no_trace] image_cache_channel: Sender<ImageCacheMsg>, /// For providing contact with the time profiler. + #[no_trace] time_profiler_chan: profile_time::ProfilerChan, /// For providing contact with the memory profiler. + #[no_trace] mem_profiler_chan: profile_mem::ProfilerChan, /// For providing instructions to an optional devtools server. + #[no_trace] devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>, /// For receiving commands from an optional devtools server. Will be ignored if /// no such server exists. + #[no_trace] devtools_port: Receiver<DevtoolScriptControlMsg>, + #[no_trace] devtools_sender: IpcSender<DevtoolScriptControlMsg>, /// The JavaScript runtime. @@ -607,10 +634,13 @@ pub struct ScriptThread { topmost_mouse_over_target: MutNullableDom<Element>, /// List of pipelines that have been owned and closed by this script thread. + #[no_trace] closed_pipelines: DomRefCell<HashSet<PipelineId>>, + #[no_trace] scheduler_chan: IpcSender<TimerSchedulerMsg>, + #[no_trace] content_process_shutdown_chan: Sender<()>, /// <https://html.spec.whatwg.org/multipage/#microtask-queue> @@ -623,9 +653,11 @@ pub struct ScriptThread { mutation_observers: DomRefCell<Vec<Dom<MutationObserver>>>, /// A handle to the WebGL thread + #[no_trace] webgl_chan: Option<WebGLPipeline>, /// The WebXR device registry + #[no_trace] webxr_registry: webxr_api::Registry, /// The worklet thread pool @@ -639,9 +671,11 @@ pub struct ScriptThread { custom_element_reaction_stack: CustomElementReactionStack, /// The Webrender Document ID associated with this thread. + #[no_trace] webrender_document: DocumentId, /// Webrender API sender. + #[no_trace] webrender_api_sender: WebrenderIpcSender, /// Periodically print out on which events script threads spend their processing time. @@ -678,9 +712,11 @@ pub struct ScriptThread { user_agent: Cow<'static, str>, /// Application window's GL Context for Media player + #[no_trace] player_context: WindowGLContext, /// A mechanism to force the compositor's event loop to process events. + #[no_trace] event_loop_waker: Option<Box<dyn EventLoopWaker>>, /// A set of all nodes ever created in this script thread @@ -690,9 +726,11 @@ pub struct ScriptThread { is_user_interacting: Cell<bool>, /// Identity manager for WebGPU resources + #[no_trace] gpu_id_hub: Arc<Mutex<Identities>>, /// Receiver to receive commands from optional WebGPU server. + #[no_trace] webgpu_port: RefCell<Option<Receiver<WebGPUMsg>>>, // Secure context @@ -1297,7 +1335,7 @@ impl ScriptThread { ScriptThread { documents: DomRefCell::new(Documents::new()), - window_proxies: DomRefCell::new(HashMap::new()), + window_proxies: DomRefCell::new(HashMapTracedValues::new()), incomplete_loads: DomRefCell::new(vec![]), incomplete_parser_contexts: IncompleteParserContexts(RefCell::new(vec![])), diff --git a/components/script/task_source/dom_manipulation.rs b/components/script/task_source/dom_manipulation.rs index d9dcdfb2472..68316b79fe3 100644 --- a/components/script/task_source/dom_manipulation.rs +++ b/components/script/task_source/dom_manipulation.rs @@ -16,7 +16,7 @@ use std::fmt; use std::result::Result; #[derive(JSTraceable)] -pub struct DOMManipulationTaskSource(pub Box<dyn ScriptChan + Send>, pub PipelineId); +pub struct DOMManipulationTaskSource(pub Box<dyn ScriptChan + Send>, #[no_trace] pub PipelineId); impl Clone for DOMManipulationTaskSource { fn clone(&self) -> DOMManipulationTaskSource { diff --git a/components/script/task_source/file_reading.rs b/components/script/task_source/file_reading.rs index 20b49a239b4..646778ffea5 100644 --- a/components/script/task_source/file_reading.rs +++ b/components/script/task_source/file_reading.rs @@ -10,7 +10,10 @@ use crate::task_source::{TaskSource, TaskSourceName}; use msg::constellation_msg::PipelineId; #[derive(JSTraceable)] -pub struct FileReadingTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct FileReadingTaskSource( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for FileReadingTaskSource { fn clone(&self) -> FileReadingTaskSource { diff --git a/components/script/task_source/history_traversal.rs b/components/script/task_source/history_traversal.rs index 0fdb428b845..ecabbddfa55 100644 --- a/components/script/task_source/history_traversal.rs +++ b/components/script/task_source/history_traversal.rs @@ -10,7 +10,10 @@ use crossbeam_channel::Sender; use msg::constellation_msg::PipelineId; #[derive(Clone, JSTraceable)] -pub struct HistoryTraversalTaskSource(pub Sender<MainThreadScriptMsg>, pub PipelineId); +pub struct HistoryTraversalTaskSource( + #[no_trace] pub Sender<MainThreadScriptMsg>, + #[no_trace] pub PipelineId, +); impl TaskSource for HistoryTraversalTaskSource { const NAME: TaskSourceName = TaskSourceName::HistoryTraversal; diff --git a/components/script/task_source/media_element.rs b/components/script/task_source/media_element.rs index c0a902b373b..16922a0ec87 100644 --- a/components/script/task_source/media_element.rs +++ b/components/script/task_source/media_element.rs @@ -18,7 +18,10 @@ use std::fmt; use std::result::Result; #[derive(Clone, JSTraceable)] -pub struct MediaElementTaskSource(pub Sender<MainThreadScriptMsg>, pub PipelineId); +pub struct MediaElementTaskSource( + #[no_trace] pub Sender<MainThreadScriptMsg>, + #[no_trace] pub PipelineId, +); impl fmt::Debug for MediaElementTaskSource { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/components/script/task_source/networking.rs b/components/script/task_source/networking.rs index 92d04b29220..0193cb22839 100644 --- a/components/script/task_source/networking.rs +++ b/components/script/task_source/networking.rs @@ -8,7 +8,10 @@ use crate::task_source::{TaskSource, TaskSourceName}; use msg::constellation_msg::PipelineId; #[derive(JSTraceable)] -pub struct NetworkingTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct NetworkingTaskSource( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for NetworkingTaskSource { fn clone(&self) -> NetworkingTaskSource { diff --git a/components/script/task_source/performance_timeline.rs b/components/script/task_source/performance_timeline.rs index 1669ac6e689..58e2660e6fd 100644 --- a/components/script/task_source/performance_timeline.rs +++ b/components/script/task_source/performance_timeline.rs @@ -16,7 +16,10 @@ use std::fmt; use std::result::Result; #[derive(JSTraceable)] -pub struct PerformanceTimelineTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct PerformanceTimelineTaskSource( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for PerformanceTimelineTaskSource { fn clone(&self) -> PerformanceTimelineTaskSource { diff --git a/components/script/task_source/port_message.rs b/components/script/task_source/port_message.rs index e9d1766f521..e21230f8099 100644 --- a/components/script/task_source/port_message.rs +++ b/components/script/task_source/port_message.rs @@ -9,7 +9,10 @@ use msg::constellation_msg::PipelineId; use std::fmt; #[derive(JSTraceable)] -pub struct PortMessageQueue(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct PortMessageQueue( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for PortMessageQueue { fn clone(&self) -> PortMessageQueue { diff --git a/components/script/task_source/remote_event.rs b/components/script/task_source/remote_event.rs index a1d54604996..91e132ed719 100644 --- a/components/script/task_source/remote_event.rs +++ b/components/script/task_source/remote_event.rs @@ -8,7 +8,10 @@ use crate::task_source::{TaskSource, TaskSourceName}; use msg::constellation_msg::PipelineId; #[derive(JSTraceable)] -pub struct RemoteEventTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct RemoteEventTaskSource( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for RemoteEventTaskSource { fn clone(&self) -> RemoteEventTaskSource { diff --git a/components/script/task_source/timer.rs b/components/script/task_source/timer.rs index cd134fb12a2..9c4d03bdda5 100644 --- a/components/script/task_source/timer.rs +++ b/components/script/task_source/timer.rs @@ -10,7 +10,10 @@ use std::fmt; #[derive(JSTraceable)] /// https://html.spec.whatwg.org/multipage/#timer-task-source -pub struct TimerTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct TimerTaskSource( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for TimerTaskSource { fn clone(&self) -> TimerTaskSource { diff --git a/components/script/task_source/user_interaction.rs b/components/script/task_source/user_interaction.rs index bb434ab7026..1f543d88cfd 100644 --- a/components/script/task_source/user_interaction.rs +++ b/components/script/task_source/user_interaction.rs @@ -18,7 +18,10 @@ use std::fmt; use std::result::Result; #[derive(Clone, JSTraceable)] -pub struct UserInteractionTaskSource(pub Sender<MainThreadScriptMsg>, pub PipelineId); +pub struct UserInteractionTaskSource( + #[no_trace] pub Sender<MainThreadScriptMsg>, + #[no_trace] pub PipelineId, +); impl fmt::Debug for UserInteractionTaskSource { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/components/script/task_source/websocket.rs b/components/script/task_source/websocket.rs index f4e153328b9..843a9632a8a 100644 --- a/components/script/task_source/websocket.rs +++ b/components/script/task_source/websocket.rs @@ -8,7 +8,10 @@ use crate::task_source::{TaskSource, TaskSourceName}; use msg::constellation_msg::PipelineId; #[derive(JSTraceable)] -pub struct WebsocketTaskSource(pub Box<dyn ScriptChan + Send + 'static>, pub PipelineId); +pub struct WebsocketTaskSource( + pub Box<dyn ScriptChan + Send + 'static>, + #[no_trace] pub PipelineId, +); impl Clone for WebsocketTaskSource { fn clone(&self) -> WebsocketTaskSource { diff --git a/components/script/timers.rs b/components/script/timers.rs index 5078bc1e788..d337f197061 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -36,20 +36,24 @@ pub struct OneshotTimerHandle(i32); pub struct OneshotTimers { js_timers: JsTimers, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] /// The sender, to be cloned for each timer, /// on which the timer scheduler in the constellation can send an event /// when the timer is due. timer_event_chan: DomRefCell<Option<IpcSender<TimerEvent>>>, #[ignore_malloc_size_of = "Defined in std"] + #[no_trace] /// The sender to the timer scheduler in the constellation. scheduler_chan: IpcSender<TimerSchedulerMsg>, next_timer_handle: Cell<OneshotTimerHandle>, timers: DomRefCell<Vec<OneshotTimer>>, + #[no_trace] suspended_since: Cell<Option<MsDuration>>, /// Initially 0, increased whenever the associated document is reactivated /// by the amount of ms the document was inactive. The current time can be /// offset back by this amount for a coherent time across document /// activations. + #[no_trace] suspension_offset: Cell<MsDuration>, /// Calls to `fire_timer` with a different argument than this get ignored. /// They were previously scheduled and got invalidated when @@ -57,14 +61,17 @@ pub struct OneshotTimers { /// - the timer it was scheduled for got canceled or /// - a timer was added with an earlier callback time. In this case the /// original timer is rescheduled when it is the next one to get called. + #[no_trace] expected_event_id: Cell<TimerEventId>, } #[derive(DenyPublicFields, JSTraceable, MallocSizeOf)] struct OneshotTimer { handle: OneshotTimerHandle, + #[no_trace] source: TimerSource, callback: OneshotTimerCallback, + #[no_trace] scheduled_for: MsDuration, } @@ -355,6 +362,7 @@ pub struct JsTimers { /// The nesting level of the currently executing timer task or 0. nesting_level: Cell<u32>, /// Used to introduce a minimum delay in event intervals + #[no_trace] min_duration: Cell<Option<MsDuration>>, } @@ -371,10 +379,12 @@ struct JsTimerEntry { pub struct JsTimerTask { #[ignore_malloc_size_of = "Because it is non-owning"] handle: JsTimerHandle, + #[no_trace] source: TimerSource, callback: InternalTimerCallback, is_interval: IsInterval, nesting_level: u32, + #[no_trace] duration: MsDuration, is_user_interacting: bool, } |