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
This commit is contained in:
Samson 2023-08-04 12:17:43 +02:00 committed by GitHub
parent 66e0d543cf
commit 9514f670d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
167 changed files with 1903 additions and 1020 deletions

View file

@ -7,10 +7,160 @@ extern crate syn;
#[macro_use] #[macro_use]
extern crate synstructure; extern crate synstructure;
decl_derive!([JSTraceable] => js_traceable_derive); decl_derive!([JSTraceable, attributes(no_trace)] =>
/// Implements `JSTraceable` on structs and enums
///
/// Example:
/// ```rust
/// #[derive(JSTraceable)]
/// struct S {
/// js_managed: JSManagedType,
/// #[no_trace]
/// non_js: NonJSManagedType,
/// }
/// ```
///
/// creates:
///
/// ```rust
/// unsafe impl JSTraceable for S {
/// #[inline]
/// unsafe fn trace(&self, tracer: *mut js::jsapi::JSTracer) {
/// match *self {
/// S {
/// js_managed: ref __binding_0,
/// non_js: ref __binding_1,
/// } => {
/// {
/// __binding_0.trace(tracer);
/// }
/// {
/// // __binding_1 is not traceable so we do not need to trace it
/// }
/// },
/// }
/// }
/// }
/// ```
///
/// In cases where there is a need to make type (empty) traceable (`HashMap<NoTraceable, Traceable>`),
/// NoTrace wrapper can be used, because it implements empty traceble:
/// ```rust
/// unsafe impl<T> JSTraceable for NoTrace<T> {
/// unsafe fn trace(&self, _: *mut ::js::jsapi::JSTracer) { /* nop */}
/// }
/// ```
///
/// ## SAFETY
/// Puting `#[no_trace]` on fields is safe if there are no types that are JS managed in that field.
/// `#[no_trace]` should NOT be put on field that does implement (non-empty) `JSTraceable` (is JS managed).
/// There are safeguards in place to prevent such mistakes. Example error:
///
/// ```console
/// error[E0282]: type annotations needed
/// |
/// | #[derive(JSTraceable, MallocSizeOf)]
/// | ^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `NoTraceOnJSTraceable`
/// |
/// = note: this error originates in the derive macro `JSTraceable`
/// ```
///
/// If you can assure that type has empty JSTraceable impl, you can bypass guards, providing your reasoning:
/// ```rust
/// #[derive(JSTraceable)]
/// struct S {
/// #[no_trace = "Safe because both u32 and u64 are empty traceable"]
/// field: HashMap<u32, u64>,
/// }
/// ```
js_traceable_derive);
// based off https://docs.rs/static_assertions/latest/src/static_assertions/assert_impl.rs.html#263
fn assert_not_impl_traceable(ty: &syn::Type) -> proc_macro2::TokenStream {
quote!(
const _: fn() = || {
// Generic trait with a blanket impl over `()` for all types.
// becomes ambiguous if impl
trait NoTraceOnJSTraceable<A> {
// Required for actually being able to reference the trait.
fn some_item() {}
}
impl<T: ?Sized> NoTraceOnJSTraceable<()> for T {}
// Used for the specialized impl when JSTraceable is implemented.
#[allow(dead_code)]
struct Invalid0;
// forbids JSTraceable
impl<T> NoTraceOnJSTraceable<Invalid0> for T where T: ?Sized + crate::dom::bindings::trace::JSTraceable {}
#[allow(dead_code)]
struct Invalid2;
// forbids HashMap<JSTraceble, _>
impl<K, V, S> NoTraceOnJSTraceable<Invalid2> for std::collections::HashMap<K, V, S>
where
K: crate::dom::bindings::trace::JSTraceable + std::cmp::Eq + std::hash::Hash,
S: std::hash::BuildHasher,
{
}
#[allow(dead_code)]
struct Invalid3;
// forbids HashMap<_, JSTraceble>
impl<K, V, S> NoTraceOnJSTraceable<Invalid3> for std::collections::HashMap<K, V, S>
where
K: std::cmp::Eq + std::hash::Hash,
V: crate::dom::bindings::trace::JSTraceable,
S: std::hash::BuildHasher,
{
}
#[allow(dead_code)]
struct Invalid4;
// forbids BTreeMap<_, JSTraceble>
impl<K, V> NoTraceOnJSTraceable<Invalid4> for std::collections::BTreeMap<K, V> where
K: crate::dom::bindings::trace::JSTraceable + std::cmp::Eq + std::hash::Hash
{
}
#[allow(dead_code)]
struct Invalid5;
// forbids BTreeMap<_, JSTraceble>
impl<K, V> NoTraceOnJSTraceable<Invalid5> for std::collections::BTreeMap<K, V>
where
K: std::cmp::Eq + std::hash::Hash,
V: crate::dom::bindings::trace::JSTraceable,
{
}
// If there is only one specialized trait impl, type inference with
// `_` can be resolved and this can compile. Fails to compile if
// ty implements `NoTraceOnJSTraceable<InvalidX>`.
let _ = <#ty as NoTraceOnJSTraceable<_>>::some_item;
};
)
}
fn js_traceable_derive(s: synstructure::Structure) -> proc_macro2::TokenStream { fn js_traceable_derive(s: synstructure::Structure) -> proc_macro2::TokenStream {
let match_body = s.each(|binding| Some(quote!(#binding.trace(tracer);))); let mut asserts = quote!();
let match_body = s.each(|binding| {
for attr in binding.ast().attrs.iter() {
match attr.parse_meta().unwrap() {
syn::Meta::Path(ref path) | syn::Meta::List(syn::MetaList { ref path, .. }) => {
if path.is_ident("no_trace") {
asserts.extend(assert_not_impl_traceable(&binding.ast().ty));
return None;
}
},
syn::Meta::NameValue(syn::MetaNameValue { ref path, .. }) => {
if path.is_ident("no_trace") {
return None;
}
},
}
}
Some(quote!(#binding.trace(tracer);))
});
let ast = s.ast(); let ast = s.ast();
let name = &ast.ident; let name = &ast.ident;
@ -24,6 +174,8 @@ fn js_traceable_derive(s: synstructure::Structure) -> proc_macro2::TokenStream {
} }
let tokens = quote! { let tokens = quote! {
#asserts
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe impl #impl_generics crate::dom::bindings::trace::JSTraceable for #name #ty_generics #where_clause { unsafe impl #impl_generics crate::dom::bindings::trace::JSTraceable for #name #ty_generics #where_clause {
#[inline] #[inline]

View file

@ -17,7 +17,8 @@ debugmozjs = ['js/debugmozjs']
jitspew = ['js/jitspew'] jitspew = ['js/jitspew']
profilemozjs = ['js/profilemozjs'] profilemozjs = ['js/profilemozjs']
unrooted_must_root_lint = ["script_plugins/unrooted_must_root_lint"] 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"] webgl_backtrace = ["canvas_traits/webgl_backtrace"]
js_backtrace = [] js_backtrace = []
refcell_backtrace = ["accountable-refcell"] refcell_backtrace = ["accountable-refcell"]

View file

@ -13,6 +13,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite; use crate::dom::bindings::num::Finite;
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::NoTrace;
use crate::dom::event::Event; use crate::dom::event::Event;
use crate::dom::node::{from_untrusted_node_address, window_from_node, Node, NodeDamage}; use crate::dom::node::{from_untrusted_node_address, window_from_node, Node, NodeDamage};
use crate::dom::transitionevent::TransitionEvent; use crate::dom::transitionevent::TransitionEvent;
@ -35,13 +36,14 @@ use style::selector_parser::PseudoElement;
#[unrooted_must_root_lint::must_root] #[unrooted_must_root_lint::must_root]
pub(crate) struct Animations { pub(crate) struct Animations {
/// The map of nodes to their animation states. /// The map of nodes to their animation states.
#[no_trace]
pub sets: DocumentAnimationSet, pub sets: DocumentAnimationSet,
/// Whether or not we have animations that are running. /// Whether or not we have animations that are running.
has_running_animations: Cell<bool>, has_running_animations: Cell<bool>,
/// A list of nodes with in-progress CSS transitions or pending events. /// 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. /// A list of pending animation-related events.
pending_events: DomRefCell<Vec<TransitionOrAnimationEvent>>, pending_events: DomRefCell<Vec<TransitionOrAnimationEvent>>,
@ -81,7 +83,10 @@ impl Animations {
let sets = self.sets.sets.read(); let sets = self.sets.sets.read();
let rooted_nodes = self.rooted_nodes.borrow(); 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); node.dirty(NodeDamage::NodeStyleDamaged);
} }
@ -332,7 +337,7 @@ impl Animations {
let mut rooted_nodes = self.rooted_nodes.borrow_mut(); let mut rooted_nodes = self.rooted_nodes.borrow_mut();
for (key, set) in sets.iter() { for (key, set) in sets.iter() {
let opaque_node = key.node; let opaque_node = key.node;
if rooted_nodes.contains_key(&opaque_node) { if rooted_nodes.contains_key(&NoTrace(opaque_node)) {
continue; continue;
} }
@ -342,7 +347,7 @@ impl Animations {
let address = UntrustedNodeAddress(opaque_node.0 as *const c_void); let address = UntrustedNodeAddress(opaque_node.0 as *const c_void);
unsafe { unsafe {
rooted_nodes.insert( rooted_nodes.insert(
opaque_node, NoTrace(opaque_node),
Dom::from_ref(&*from_untrusted_node_address(address)), Dom::from_ref(&*from_untrusted_node_address(address)),
) )
}; };
@ -355,7 +360,7 @@ impl Animations {
let pending_events = self.pending_events.borrow(); let pending_events = self.pending_events.borrow();
let nodes: FxHashSet<OpaqueNode> = sets.keys().map(|key| key.node).collect(); let nodes: FxHashSet<OpaqueNode> = sets.keys().map(|key| key.node).collect();
self.rooted_nodes.borrow_mut().retain(|node, _| { 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() { for event in events.into_iter() {
// We root the node here to ensure that sending this event doesn't // We root the node here to ensure that sending this event doesn't
// unroot it as a side-effect. // 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), Some(node) => DomRoot::from_ref(&**node),
None => { None => {
warn!("Tried to send an event for an unrooted node"); warn!("Tried to send an event for an unrooted node");
@ -569,12 +574,15 @@ impl TransitionOrAnimationEventType {
/// A transition or animation event. /// A transition or animation event.
pub struct TransitionOrAnimationEvent { pub struct TransitionOrAnimationEvent {
/// The pipeline id of the layout task that sent this message. /// The pipeline id of the layout task that sent this message.
#[no_trace]
pub pipeline_id: PipelineId, pub pipeline_id: PipelineId,
/// The type of transition event this should trigger. /// The type of transition event this should trigger.
pub event_type: TransitionOrAnimationEventType, pub event_type: TransitionOrAnimationEventType,
/// The address of the node which owns this transition. /// The address of the node which owns this transition.
#[no_trace]
pub node: OpaqueNode, pub node: OpaqueNode,
/// The pseudo element for this transition or animation, if applicable. /// The pseudo element for this transition or animation, if applicable.
#[no_trace]
pub pseudo_element: Option<PseudoElement>, pub pseudo_element: Option<PseudoElement>,
/// The name of the property that is transitioning (in the case of a transition) /// 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). /// or the name of the animation (in the case of an animation).

View file

@ -281,9 +281,11 @@ impl TransmitBodyConnectHandler {
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
struct TransmitBodyPromiseHandler { struct TransmitBodyPromiseHandler {
#[ignore_malloc_size_of = "Channels are hard"] #[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
bytes_sender: IpcSender<BodyChunkResponse>, bytes_sender: IpcSender<BodyChunkResponse>,
stream: DomRoot<ReadableStream>, stream: DomRoot<ReadableStream>,
#[ignore_malloc_size_of = "Channels are hard"] #[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
control_sender: IpcSender<BodyChunkRequest>, control_sender: IpcSender<BodyChunkRequest>,
} }
@ -328,9 +330,11 @@ impl Callback for TransmitBodyPromiseHandler {
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
struct TransmitBodyPromiseRejectionHandler { struct TransmitBodyPromiseRejectionHandler {
#[ignore_malloc_size_of = "Channels are hard"] #[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
bytes_sender: IpcSender<BodyChunkResponse>, bytes_sender: IpcSender<BodyChunkResponse>,
stream: DomRoot<ReadableStream>, stream: DomRoot<ReadableStream>,
#[ignore_malloc_size_of = "Channels are hard"] #[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
control_sender: IpcSender<BodyChunkRequest>, control_sender: IpcSender<BodyChunkRequest>,
} }

View file

@ -61,7 +61,7 @@ use style_traits::values::ToCss;
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) enum CanvasFillOrStrokeStyle { pub(crate) enum CanvasFillOrStrokeStyle {
Color(RGBA), Color(#[no_trace] RGBA),
Gradient(Dom<CanvasGradient>), Gradient(Dom<CanvasGradient>),
Pattern(Dom<CanvasPattern>), Pattern(Dom<CanvasPattern>),
} }
@ -80,22 +80,31 @@ impl CanvasFillOrStrokeStyle {
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
pub(crate) struct CanvasContextState { pub(crate) struct CanvasContextState {
global_alpha: f64, global_alpha: f64,
#[no_trace]
global_composition: CompositionOrBlending, global_composition: CompositionOrBlending,
image_smoothing_enabled: bool, image_smoothing_enabled: bool,
fill_style: CanvasFillOrStrokeStyle, fill_style: CanvasFillOrStrokeStyle,
stroke_style: CanvasFillOrStrokeStyle, stroke_style: CanvasFillOrStrokeStyle,
line_width: f64, line_width: f64,
#[no_trace]
line_cap: LineCapStyle, line_cap: LineCapStyle,
#[no_trace]
line_join: LineJoinStyle, line_join: LineJoinStyle,
miter_limit: f64, miter_limit: f64,
#[no_trace]
transform: Transform2D<f32>, transform: Transform2D<f32>,
shadow_offset_x: f64, shadow_offset_x: f64,
shadow_offset_y: f64, shadow_offset_y: f64,
shadow_blur: f64, shadow_blur: f64,
#[no_trace]
shadow_color: RGBA, shadow_color: RGBA,
#[no_trace]
font_style: Option<Font>, font_style: Option<Font>,
#[no_trace]
text_align: TextAlign, text_align: TextAlign,
#[no_trace]
text_baseline: TextBaseline, text_baseline: TextBaseline,
#[no_trace]
direction: Direction, direction: Direction,
} }
@ -131,17 +140,23 @@ impl CanvasContextState {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
pub(crate) struct CanvasState { pub(crate) struct CanvasState {
#[ignore_malloc_size_of = "Defined in ipc-channel"] #[ignore_malloc_size_of = "Defined in ipc-channel"]
#[no_trace]
ipc_renderer: IpcSender<CanvasMsg>, ipc_renderer: IpcSender<CanvasMsg>,
#[no_trace]
canvas_id: CanvasId, canvas_id: CanvasId,
state: DomRefCell<CanvasContextState>, state: DomRefCell<CanvasContextState>,
origin_clean: Cell<bool>, origin_clean: Cell<bool>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
image_cache: Arc<dyn ImageCache>, image_cache: Arc<dyn ImageCache>,
/// The base URL for resolving CSS image URL values. /// The base URL for resolving CSS image URL values.
/// Needed because of https://github.com/servo/servo/issues/17625 /// Needed because of https://github.com/servo/servo/issues/17625
#[no_trace]
base_url: ServoUrl, base_url: ServoUrl,
#[no_trace]
origin: ImmutableOrigin, origin: ImmutableOrigin,
/// Any missing image URLs. /// Any missing image URLs.
#[no_trace]
missing_image_urls: DomRefCell<Vec<ServoUrl>>, missing_image_urls: DomRefCell<Vec<ServoUrl>>,
saved_states: DomRefCell<Vec<CanvasContextState>>, saved_states: DomRefCell<Vec<CanvasContextState>>,
} }

View file

@ -17,11 +17,11 @@ use servo_url::ServoUrl;
#[derive(Clone, Debug, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Debug, JSTraceable, MallocSizeOf, PartialEq)]
pub enum LoadType { pub enum LoadType {
Image(ServoUrl), Image(#[no_trace] ServoUrl),
Script(ServoUrl), Script(#[no_trace] ServoUrl),
Subframe(ServoUrl), Subframe(#[no_trace] ServoUrl),
Stylesheet(ServoUrl), Stylesheet(#[no_trace] ServoUrl),
PageSource(ServoUrl), PageSource(#[no_trace] ServoUrl),
Media, Media,
} }
@ -66,6 +66,7 @@ impl Drop for LoadBlocker {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
pub struct DocumentLoader { pub struct DocumentLoader {
#[no_trace]
resource_threads: ResourceThreads, resource_threads: ResourceThreads,
blocking_loads: Vec<LoadType>, blocking_loads: Vec<LoadType>,
events_inhibited: bool, events_inhibited: bool,

View file

@ -20,6 +20,7 @@ use devtools_traits::DevtoolScriptControlMsg;
/// Worker object will remain alive. /// Worker object will remain alive.
#[derive(Clone, JSTraceable)] #[derive(Clone, JSTraceable)]
pub struct SendableWorkerScriptChan { pub struct SendableWorkerScriptChan {
#[no_trace]
pub sender: Sender<DedicatedWorkerScriptMsg>, pub sender: Sender<DedicatedWorkerScriptMsg>,
pub worker: TrustedWorkerAddress, pub worker: TrustedWorkerAddress,
} }
@ -46,6 +47,7 @@ impl ScriptChan for SendableWorkerScriptChan {
/// Worker object will remain alive. /// Worker object will remain alive.
#[derive(Clone, JSTraceable)] #[derive(Clone, JSTraceable)]
pub struct WorkerThreadWorkerChan { pub struct WorkerThreadWorkerChan {
#[no_trace]
pub sender: Sender<DedicatedWorkerScriptMsg>, pub sender: Sender<DedicatedWorkerScriptMsg>,
pub worker: TrustedWorkerAddress, pub worker: TrustedWorkerAddress,
} }

View file

@ -31,6 +31,7 @@ use servo_media::audio::node::AudioNodeInit;
pub struct AnalyserNode { pub struct AnalyserNode {
node: AudioNode, node: AudioNode,
#[ignore_malloc_size_of = "Defined in servo-media"] #[ignore_malloc_size_of = "Defined in servo-media"]
#[no_trace]
engine: DomRefCell<AnalysisEngine>, engine: DomRefCell<AnalysisEngine>,
} }

View file

@ -20,6 +20,7 @@ use servo_atoms::Atom;
#[dom_struct] #[dom_struct]
pub struct AnimationEvent { pub struct AnimationEvent {
event: Event, event: Event,
#[no_trace]
animation_name: Atom, animation_name: Atom,
elapsed_time: Finite<f32>, elapsed_time: Finite<f32>,
pseudo_element: DOMString, pseudo_element: DOMString,

View file

@ -27,7 +27,9 @@ use style::values::GenericAtomIdent;
#[dom_struct] #[dom_struct]
pub struct Attr { pub struct Attr {
node_: Node, node_: Node,
#[no_trace]
identifier: AttrIdentifier, identifier: AttrIdentifier,
#[no_trace]
value: DomRefCell<AttrValue>, value: DomRefCell<AttrValue>,
/// the element that owns this attribute. /// the element that owns this attribute.

View file

@ -50,6 +50,7 @@ pub struct AudioBuffer {
/// Aggregates the data from js_channels. /// Aggregates the data from js_channels.
/// This is Some<T> iff the buffers in js_channels are detached. /// This is Some<T> iff the buffers in js_channels are detached.
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
shared_channels: DomRefCell<Option<ServoMediaAudioBuffer>>, shared_channels: DomRefCell<Option<ServoMediaAudioBuffer>>,
/// https://webaudio.github.io/web-audio-api/#dom-audiobuffer-samplerate /// https://webaudio.github.io/web-audio-api/#dom-audiobuffer-samplerate
sample_rate: f32, sample_rate: f32,

View file

@ -33,6 +33,7 @@ pub const MAX_CHANNEL_COUNT: u32 = 32;
pub struct AudioNode { pub struct AudioNode {
eventtarget: EventTarget, eventtarget: EventTarget,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
node_id: NodeId, node_id: NodeId,
context: Dom<BaseAudioContext>, context: Dom<BaseAudioContext>,
number_of_inputs: u32, number_of_inputs: u32,

View file

@ -23,8 +23,10 @@ pub struct AudioParam {
reflector_: Reflector, reflector_: Reflector,
context: Dom<BaseAudioContext>, context: Dom<BaseAudioContext>,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
node: NodeId, node: NodeId,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
param: ParamType, param: ParamType,
automation_rate: Cell<AutomationRate>, automation_rate: Cell<AutomationRate>,
default_value: f32, default_value: f32,

View file

@ -82,6 +82,7 @@ struct DecodeResolver {
pub struct BaseAudioContext { pub struct BaseAudioContext {
eventtarget: EventTarget, eventtarget: EventTarget,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
audio_context_impl: Arc<Mutex<AudioContext>>, audio_context_impl: Arc<Mutex<AudioContext>>,
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-destination
destination: MutNullableDom<AudioDestinationNode>, destination: MutNullableDom<AudioDestinationNode>,

View file

@ -40,43 +40,11 @@ use crate::dom::gpubuffer::GPUBufferState;
use crate::dom::gpucanvascontext::WebGPUContextId; use crate::dom::gpucanvascontext::WebGPUContextId;
use crate::dom::gpucommandencoder::GPUCommandEncoderState; use crate::dom::gpucommandencoder::GPUCommandEncoderState;
use crate::dom::htmlimageelement::SourceSet; use crate::dom::htmlimageelement::SourceSet;
use crate::dom::htmlmediaelement::{HTMLMediaElementFetchContext, MediaFrameRenderer}; use crate::dom::htmlmediaelement::HTMLMediaElementFetchContext;
use crate::dom::identityhub::Identities;
use crate::script_runtime::{ContextForRequestInterrupt, StreamConsumer}; use crate::script_runtime::{ContextForRequestInterrupt, StreamConsumer};
use crate::script_thread::IncompleteParserContexts; use crate::script_thread::IncompleteParserContexts;
use crate::task::TaskBox; 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 indexmap::IndexMap;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use js::glue::{CallObjectTracer, CallScriptTracer, CallStringTracer, CallValueTracer}; use js::glue::{CallObjectTracer, CallScriptTracer, CallStringTracer, CallValueTracer};
use js::jsapi::{ use js::jsapi::{
GCTraceKindToAscii, Heap, JSObject, JSScript, JSString, JSTracer, JobQueue, TraceKind, 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::TypedArray;
use js::typedarray::TypedArrayElement; use js::typedarray::TypedArrayElement;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use media::WindowGLContext; use parking_lot::RwLock;
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 servo_arc::Arc as ServoArc; 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 smallvec::SmallVec;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::{Cell, RefCell, UnsafeCell}; use std::cell::{Cell, RefCell, UnsafeCell};
use std::collections::hash_map::RandomState;
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
use std::fmt::Display;
use std::hash::{BuildHasher, Hash}; use std::hash::{BuildHasher, Hash};
use std::mem; use std::mem;
use std::num::NonZeroU64; use std::num::NonZeroU64;
@ -143,42 +69,16 @@ use std::ops::{Deref, DerefMut, Range};
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::{Arc, Mutex}; use std::sync::Arc;
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::time::{Instant, SystemTime}; use std::time::{Instant, SystemTime};
use style::animation::DocumentAnimationSet;
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
use style::author_styles::AuthorStyles; 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::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::fmt::UTF8;
use tendril::stream::LossyDecoder; use tendril::stream::LossyDecoder;
use tendril::{StrTendril, TendrilSink}; use tendril::TendrilSink;
use time::{Duration, Timespec, Tm}; use webxr_api::{Finger, Hand};
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};
unsafe_no_jsmanaged_fields!(Tm);
unsafe_no_jsmanaged_fields!(JoinHandle<()>); unsafe_no_jsmanaged_fields!(JoinHandle<()>);
/// A trait to allow tracing (only) DOM objects. /// A trait to allow tracing (only) DOM objects.
@ -187,40 +87,159 @@ pub unsafe trait JSTraceable {
unsafe fn trace(&self, trc: *mut JSTracer); 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);
impl<T: Display> Display for NoTrace<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T> From<T> for NoTrace<T> {
fn from(item: T) -> Self {
Self(item)
}
}
#[allow(unsafe_code)]
unsafe impl<T> JSTraceable for NoTrace<T> {
#[inline]
unsafe fn trace(&self, _: *mut ::js::jsapi::JSTracer) {}
}
impl<T: MallocSizeOf> MallocSizeOf for NoTrace<T> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.0.size_of(ops)
}
}
/// 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>);
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())
}
}
impl<K, V, S> HashMapTracedValues<K, V, S> {
#[inline]
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, K, V> {
self.0.iter()
}
#[inline]
pub fn drain(&mut self) -> std::collections::hash_map::Drain<'_, K, V> {
self.0.drain()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
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)
}
#[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!(IncompleteParserContexts);
unsafe_no_jsmanaged_fields!(MessagePortImpl);
unsafe_no_jsmanaged_fields!(MessagePortId);
unsafe_no_jsmanaged_fields!(MessagePortRouterId);
unsafe_no_jsmanaged_fields!(ServiceWorkerId);
unsafe_no_jsmanaged_fields!(ServiceWorkerRegistrationId);
unsafe_no_jsmanaged_fields!(BroadcastChannelRouterId);
unsafe_no_jsmanaged_fields!(BlobId);
unsafe_no_jsmanaged_fields!(BlobImpl);
unsafe_no_jsmanaged_fields!(CSSError);
unsafe_no_jsmanaged_fields!(&'static Encoding);
unsafe_no_jsmanaged_fields!(Decoder);
unsafe_no_jsmanaged_fields!(Reflector); unsafe_no_jsmanaged_fields!(Reflector);
unsafe_no_jsmanaged_fields!(Duration);
unsafe_no_jsmanaged_fields!(TexDataType, TexFormat);
unsafe_no_jsmanaged_fields!(*mut JobQueue); unsafe_no_jsmanaged_fields!(*mut JobQueue);
unsafe_no_jsmanaged_fields!(Cow<'static, str>); unsafe_no_jsmanaged_fields!(Cow<'static, str>);
unsafe_no_jsmanaged_fields!(CspList);
/// Trace a `JSScript`. /// Trace a `JSScript`.
pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut JSScript>) { pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut JSScript>) {
unsafe { 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!(bool, f32, f64, String, AtomicBool, AtomicUsize, char);
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!(usize, u8, u16, u32, u64); unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64);
unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64);
unsafe_no_jsmanaged_fields!(NonZeroU64); unsafe_no_jsmanaged_fields!(NonZeroU64);
unsafe_no_jsmanaged_fields!(Error); 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!(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!(Runtime);
unsafe_no_jsmanaged_fields!(ContextForRequestInterrupt); unsafe_no_jsmanaged_fields!(ContextForRequestInterrupt);
unsafe_no_jsmanaged_fields!(HeaderMap, Method);
unsafe_no_jsmanaged_fields!(WindowProxyHandler); 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!(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!(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!(SystemTime);
unsafe_no_jsmanaged_fields!(Instant); unsafe_no_jsmanaged_fields!(Instant);
unsafe_no_jsmanaged_fields!(RelativePos);
unsafe_no_jsmanaged_fields!(StyleAndOpaqueLayoutData);
unsafe_no_jsmanaged_fields!(PathBuf); 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!(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!(GPUBufferState);
unsafe_no_jsmanaged_fields!(GPUCommandEncoderState); unsafe_no_jsmanaged_fields!(GPUCommandEncoderState);
unsafe_no_jsmanaged_fields!(Range<u64>); 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!(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!(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!(StreamConsumer);
unsafe_no_jsmanaged_fields!(DocumentAnimationSet);
unsafe_no_jsmanaged_fields!(Stencil); unsafe_no_jsmanaged_fields!(Stencil);
unsafe impl<'a> JSTraceable for &'a str { 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 () { unsafe impl JSTraceable for () {
#[inline] #[inline]
unsafe fn trace(&self, _: *mut JSTracer) { 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> { unsafe impl<T: DomObject> JSTraceable for Trusted<T> {
#[inline] #[inline]
unsafe fn trace(&self, _: *mut JSTracer) { 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>>> unsafe impl<T> JSTraceable for TypedArray<T, Box<Heap<*mut JSObject>>>
where where
T: TypedArrayElement, T: TypedArrayElement,

View file

@ -34,6 +34,7 @@ use uuid::Uuid;
#[dom_struct] #[dom_struct]
pub struct Blob { pub struct Blob {
reflector_: Reflector, reflector_: Reflector,
#[no_trace]
blob_id: BlobId, blob_id: BlobId,
} }

View file

@ -22,6 +22,7 @@ pub struct BroadcastChannel {
eventtarget: EventTarget, eventtarget: EventTarget,
name: DOMString, name: DOMString,
closed: Cell<bool>, closed: Cell<bool>,
#[no_trace]
id: Uuid, id: Uuid,
} }

View file

@ -22,13 +22,14 @@ use dom_struct::dom_struct;
pub struct CanvasGradient { pub struct CanvasGradient {
reflector_: Reflector, reflector_: Reflector,
style: CanvasGradientStyle, style: CanvasGradientStyle,
#[no_trace]
stops: DomRefCell<Vec<CanvasGradientStop>>, stops: DomRefCell<Vec<CanvasGradientStop>>,
} }
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
pub enum CanvasGradientStyle { pub enum CanvasGradientStyle {
Linear(LinearGradientStyle), Linear(#[no_trace] LinearGradientStyle),
Radial(RadialGradientStyle), Radial(#[no_trace] RadialGradientStyle),
} }
impl CanvasGradient { impl CanvasGradient {

View file

@ -15,6 +15,7 @@ use euclid::default::Size2D;
pub struct CanvasPattern { pub struct CanvasPattern {
reflector_: Reflector, reflector_: Reflector,
surface_data: Vec<u8>, surface_data: Vec<u8>,
#[no_trace]
surface_size: Size2D<u32>, surface_size: Size2D<u32>,
repeat_x: bool, repeat_x: bool,
repeat_y: bool, repeat_y: bool,

View file

@ -18,9 +18,11 @@ use uuid::Uuid;
pub struct Client { pub struct Client {
reflector_: Reflector, reflector_: Reflector,
active_worker: MutNullableDom<ServiceWorker>, active_worker: MutNullableDom<ServiceWorker>,
#[no_trace]
url: ServoUrl, url: ServoUrl,
frame_type: FrameType, frame_type: FrameType,
#[ignore_malloc_size_of = "Defined in uuid"] #[ignore_malloc_size_of = "Defined in uuid"]
#[no_trace]
id: Uuid, id: Uuid,
} }

View file

@ -17,6 +17,7 @@ use style::stylesheets::FontFaceRule;
pub struct CSSFontFaceRule { pub struct CSSFontFaceRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
fontfacerule: Arc<Locked<FontFaceRule>>, fontfacerule: Arc<Locked<FontFaceRule>>,
} }

View file

@ -20,6 +20,7 @@ use style::stylesheets::CssRules as StyleCssRules;
pub struct CSSGroupingRule { pub struct CSSGroupingRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
rules: Arc<Locked<StyleCssRules>>, rules: Arc<Locked<StyleCssRules>>,
rulelist: MutNullableDom<CSSRuleList>, rulelist: MutNullableDom<CSSRuleList>,
} }

View file

@ -17,6 +17,7 @@ use style::stylesheets::ImportRule;
pub struct CSSImportRule { pub struct CSSImportRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
import_rule: Arc<Locked<ImportRule>>, import_rule: Arc<Locked<ImportRule>>,
} }

View file

@ -20,6 +20,7 @@ use style::stylesheets::keyframes_rule::Keyframe;
pub struct CSSKeyframeRule { pub struct CSSKeyframeRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
keyframerule: Arc<Locked<Keyframe>>, keyframerule: Arc<Locked<Keyframe>>,
style_decl: MutNullableDom<CSSStyleDeclaration>, style_decl: MutNullableDom<CSSStyleDeclaration>,
} }

View file

@ -24,6 +24,7 @@ use style::values::KeyframesName;
pub struct CSSKeyframesRule { pub struct CSSKeyframesRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
keyframesrule: Arc<Locked<KeyframesRule>>, keyframesrule: Arc<Locked<KeyframesRule>>,
rulelist: MutNullableDom<CSSRuleList>, rulelist: MutNullableDom<CSSRuleList>,
} }

View file

@ -25,6 +25,7 @@ use style_traits::{ParsingMode, ToCss};
pub struct CSSMediaRule { pub struct CSSMediaRule {
cssconditionrule: CSSConditionRule, cssconditionrule: CSSConditionRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
mediarule: Arc<Locked<MediaRule>>, mediarule: Arc<Locked<MediaRule>>,
medialist: MutNullableDom<MediaList>, medialist: MutNullableDom<MediaList>,
} }

View file

@ -18,6 +18,7 @@ use style::stylesheets::NamespaceRule;
pub struct CSSNamespaceRule { pub struct CSSNamespaceRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
namespacerule: Arc<Locked<NamespaceRule>>, namespacerule: Arc<Locked<NamespaceRule>>,
} }

View file

@ -34,6 +34,7 @@ pub struct CSSStyleDeclaration {
reflector_: Reflector, reflector_: Reflector,
owner: CSSStyleOwner, owner: CSSStyleOwner,
readonly: bool, readonly: bool,
#[no_trace]
pseudo: Option<PseudoElement>, pseudo: Option<PseudoElement>,
} }
@ -43,7 +44,9 @@ pub enum CSSStyleOwner {
Element(Dom<Element>), Element(Dom<Element>),
CSSRule( CSSRule(
Dom<CSSRule>, Dom<CSSRule>,
#[ignore_malloc_size_of = "Arc"] Arc<Locked<PropertyDeclarationBlock>>, #[ignore_malloc_size_of = "Arc"]
#[no_trace]
Arc<Locked<PropertyDeclarationBlock>>,
), ),
} }

View file

@ -26,6 +26,7 @@ use style::stylesheets::{Origin, StyleRule};
pub struct CSSStyleRule { pub struct CSSStyleRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
stylerule: Arc<Locked<StyleRule>>, stylerule: Arc<Locked<StyleRule>>,
style_decl: MutNullableDom<CSSStyleDeclaration>, style_decl: MutNullableDom<CSSStyleDeclaration>,
} }

View file

@ -26,6 +26,7 @@ pub struct CSSStyleSheet {
owner: MutNullableDom<Element>, owner: MutNullableDom<Element>,
rulelist: MutNullableDom<CSSRuleList>, rulelist: MutNullableDom<CSSRuleList>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
style_stylesheet: Arc<StyleStyleSheet>, style_stylesheet: Arc<StyleStyleSheet>,
origin_clean: Cell<bool>, origin_clean: Cell<bool>,
} }

View file

@ -23,6 +23,7 @@ use style_traits::{ParsingMode, ToCss};
pub struct CSSSupportsRule { pub struct CSSSupportsRule {
cssconditionrule: CSSConditionRule, cssconditionrule: CSSConditionRule,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
supportsrule: Arc<Locked<SupportsRule>>, supportsrule: Arc<Locked<SupportsRule>>,
} }

View file

@ -43,12 +43,14 @@ use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue}; use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue};
use js::rust::{HandleObject, HandleValue, MutableHandleValue}; use js::rust::{HandleObject, HandleValue, MutableHandleValue};
use std::cell::Cell; use std::cell::Cell;
use std::collections::{HashMap, VecDeque}; use std::collections::VecDeque;
use std::mem; use std::mem;
use std::ops::Deref; use std::ops::Deref;
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use super::bindings::trace::HashMapTracedValues;
/// <https://dom.spec.whatwg.org/#concept-element-custom-element-state> /// <https://dom.spec.whatwg.org/#concept-element-custom-element-state>
#[derive(Clone, Copy, Eq, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, Eq, JSTraceable, MallocSizeOf, PartialEq)]
pub enum CustomElementState { pub enum CustomElementState {
@ -72,12 +74,12 @@ pub struct CustomElementRegistry {
window: Dom<Window>, window: Dom<Window>,
#[ignore_malloc_size_of = "Rc"] #[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>, element_definition_is_running: Cell<bool>,
#[ignore_malloc_size_of = "Rc"] #[ignore_malloc_size_of = "Rc"]
definitions: DomRefCell<HashMap<LocalName, Rc<CustomElementDefinition>>>, definitions: DomRefCell<HashMapTracedValues<LocalName, Rc<CustomElementDefinition>>>,
} }
impl CustomElementRegistry { impl CustomElementRegistry {
@ -85,9 +87,9 @@ impl CustomElementRegistry {
CustomElementRegistry { CustomElementRegistry {
reflector_: Reflector::new(), reflector_: Reflector::new(),
window: Dom::from_ref(window), window: Dom::from_ref(window),
when_defined: DomRefCell::new(HashMap::new()), when_defined: DomRefCell::new(HashMapTracedValues::new()),
element_definition_is_running: Cell::new(false), 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 /// Cleans up any active promises
/// <https://github.com/servo/servo/issues/15318> /// <https://github.com/servo/servo/issues/15318>
pub fn teardown(&self) { 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> /// <https://html.spec.whatwg.org/multipage/#look-up-a-custom-element-definition>
@ -112,6 +114,7 @@ impl CustomElementRegistry {
) -> Option<Rc<CustomElementDefinition>> { ) -> Option<Rc<CustomElementDefinition>> {
self.definitions self.definitions
.borrow() .borrow()
.0
.values() .values()
.find(|definition| { .find(|definition| {
// Step 4-5 // Step 4-5
@ -127,6 +130,7 @@ impl CustomElementRegistry {
) -> Option<Rc<CustomElementDefinition>> { ) -> Option<Rc<CustomElementDefinition>> {
self.definitions self.definitions
.borrow() .borrow()
.0
.values() .values()
.find(|definition| definition.constructor.callback() == constructor.get()) .find(|definition| definition.constructor.callback() == constructor.get())
.cloned() .cloned()
@ -497,8 +501,10 @@ pub enum ConstructionStackEntry {
/// <https://html.spec.whatwg.org/multipage/#custom-element-definition> /// <https://html.spec.whatwg.org/multipage/#custom-element-definition>
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
pub struct CustomElementDefinition { pub struct CustomElementDefinition {
#[no_trace]
pub name: LocalName, pub name: LocalName,
#[no_trace]
pub local_name: LocalName, pub local_name: LocalName,
#[ignore_malloc_size_of = "Rc"] #[ignore_malloc_size_of = "Rc"]

View file

@ -182,6 +182,7 @@ pub struct DedicatedWorkerGlobalScope {
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
task_queue: TaskQueue<DedicatedWorkerScriptMsg>, task_queue: TaskQueue<DedicatedWorkerScriptMsg>,
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace]
own_sender: Sender<DedicatedWorkerScriptMsg>, own_sender: Sender<DedicatedWorkerScriptMsg>,
#[ignore_malloc_size_of = "Trusted<T> has unclear ownership like Dom<T>"] #[ignore_malloc_size_of = "Trusted<T> has unclear ownership like Dom<T>"]
worker: DomRefCell<Option<TrustedWorkerAddress>>, worker: DomRefCell<Option<TrustedWorkerAddress>>,
@ -189,11 +190,14 @@ pub struct DedicatedWorkerGlobalScope {
/// Sender to the parent thread. /// Sender to the parent thread.
parent_sender: Box<dyn ScriptChan + Send>, parent_sender: Box<dyn ScriptChan + Send>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
image_cache: Arc<dyn ImageCache>, image_cache: Arc<dyn ImageCache>,
#[no_trace]
browsing_context: Option<BrowsingContextId>, browsing_context: Option<BrowsingContextId>,
/// A receiver of control messages, /// A receiver of control messages,
/// currently only used to signal shutdown. /// currently only used to signal shutdown.
#[ignore_malloc_size_of = "Channels are hard"] #[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
control_receiver: Receiver<DedicatedWorkerControlMsg>, control_receiver: Receiver<DedicatedWorkerControlMsg>,
} }

View file

@ -176,6 +176,8 @@ use url::Host;
use uuid::Uuid; use uuid::Uuid;
use webrender_api::units::DeviceIntRect; use webrender_api::units::DeviceIntRect;
use super::bindings::trace::{HashMapTracedValues, NoTrace};
/// The number of times we are allowed to see spurious `requestAnimationFrame()` calls before /// The number of times we are allowed to see spurious `requestAnimationFrame()` calls before
/// falling back to fake ones. /// falling back to fake ones.
/// ///
@ -235,21 +237,26 @@ pub struct Document {
window: Dom<Window>, window: Dom<Window>,
implementation: MutNullableDom<DOMImplementation>, implementation: MutNullableDom<DOMImplementation>,
#[ignore_malloc_size_of = "type from external crate"] #[ignore_malloc_size_of = "type from external crate"]
#[no_trace]
content_type: Mime, content_type: Mime,
last_modified: Option<String>, last_modified: Option<String>,
#[no_trace]
encoding: Cell<&'static Encoding>, encoding: Cell<&'static Encoding>,
has_browsing_context: bool, has_browsing_context: bool,
is_html_document: bool, is_html_document: bool,
#[no_trace]
activity: Cell<DocumentActivity>, activity: Cell<DocumentActivity>,
#[no_trace]
url: DomRefCell<ServoUrl>, url: DomRefCell<ServoUrl>,
#[ignore_malloc_size_of = "defined in selectors"] #[ignore_malloc_size_of = "defined in selectors"]
#[no_trace]
quirks_mode: Cell<QuirksMode>, quirks_mode: Cell<QuirksMode>,
/// Caches for the getElement methods /// Caches for the getElement methods
id_map: DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>,
name_map: DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, name_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>,
tag_map: DomRefCell<HashMap<LocalName, Dom<HTMLCollection>>>, tag_map: DomRefCell<HashMapTracedValues<LocalName, Dom<HTMLCollection>>>,
tagns_map: DomRefCell<HashMap<QualName, Dom<HTMLCollection>>>, tagns_map: DomRefCell<HashMapTracedValues<QualName, Dom<HTMLCollection>>>,
classes_map: DomRefCell<HashMap<Vec<Atom>, Dom<HTMLCollection>>>, classes_map: DomRefCell<HashMapTracedValues<Vec<Atom>, Dom<HTMLCollection>>>,
images: MutNullableDom<HTMLCollection>, images: MutNullableDom<HTMLCollection>,
embeds: MutNullableDom<HTMLCollection>, embeds: MutNullableDom<HTMLCollection>,
links: MutNullableDom<HTMLCollection>, links: MutNullableDom<HTMLCollection>,
@ -259,6 +266,7 @@ pub struct Document {
applets: MutNullableDom<HTMLCollection>, applets: MutNullableDom<HTMLCollection>,
/// Lock use for style attributes and author-origin stylesheet objects in this document. /// Lock use for style attributes and author-origin stylesheet objects in this document.
/// Can be acquired once for accessing many objects. /// Can be acquired once for accessing many objects.
#[no_trace]
style_shared_lock: StyleSharedRwLock, style_shared_lock: StyleSharedRwLock,
/// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed. /// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed.
stylesheets: DomRefCell<DocumentStylesheetSet<StyleSheetInDocument>>, stylesheets: DomRefCell<DocumentStylesheetSet<StyleSheetInDocument>>,
@ -309,7 +317,7 @@ pub struct Document {
appropriate_template_contents_owner_document: MutNullableDom<Document>, appropriate_template_contents_owner_document: MutNullableDom<Document>,
/// Information on elements needing restyle to ship over to the layout thread when the /// Information on elements needing restyle to ship over to the layout thread when the
/// time comes. /// 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 /// This flag will be true if layout suppressed a reflow attempt that was
/// needed in order for the page to be painted. /// needed in order for the page to be painted.
needs_paint: Cell<bool>, needs_paint: Cell<bool>,
@ -328,10 +336,13 @@ pub struct Document {
unload_event_start: Cell<u64>, unload_event_start: Cell<u64>,
unload_event_end: Cell<u64>, unload_event_end: Cell<u64>,
/// <https://html.spec.whatwg.org/multipage/#concept-document-https-state> /// <https://html.spec.whatwg.org/multipage/#concept-document-https-state>
#[no_trace]
https_state: Cell<HttpsState>, https_state: Cell<HttpsState>,
/// The document's origin. /// The document's origin.
#[no_trace]
origin: MutableOrigin, origin: MutableOrigin,
/// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states /// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states
#[no_trace]
referrer_policy: Cell<Option<ReferrerPolicy>>, referrer_policy: Cell<Option<ReferrerPolicy>>,
/// <https://html.spec.whatwg.org/multipage/#dom-document-referrer> /// <https://html.spec.whatwg.org/multipage/#dom-document-referrer>
referrer: Option<String>, referrer: Option<String>,
@ -339,6 +350,7 @@ pub struct Document {
target_element: MutNullableDom<Element>, target_element: MutNullableDom<Element>,
/// <https://w3c.github.io/uievents/#event-type-dblclick> /// <https://w3c.github.io/uievents/#event-type-dblclick>
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace]
last_click_info: DomRefCell<Option<(Instant, Point2D<f32>)>>, last_click_info: DomRefCell<Option<(Instant, Point2D<f32>)>>,
/// <https://html.spec.whatwg.org/multipage/#ignore-destructive-writes-counter> /// <https://html.spec.whatwg.org/multipage/#ignore-destructive-writes-counter>
ignore_destructive_writes_counter: Cell<u32>, ignore_destructive_writes_counter: Cell<u32>,
@ -362,8 +374,10 @@ pub struct Document {
/// whenever any element with the same ID as the form attribute /// whenever any element with the same ID as the form attribute
/// is inserted or removed from the document. /// is inserted or removed from the document.
/// See https://html.spec.whatwg.org/multipage/#form-owner /// 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>, interactive_time: DomRefCell<InteractiveMetrics>,
#[no_trace]
tti_window: DomRefCell<InteractiveWindow>, tti_window: DomRefCell<InteractiveWindow>,
/// RAII canceller for Fetch /// RAII canceller for Fetch
canceller: FetchCanceller, canceller: FetchCanceller,
@ -399,11 +413,13 @@ pub struct Document {
/// hosting the media controls UI. /// hosting the media controls UI.
media_controls: DomRefCell<HashMap<String, Dom<ShadowRoot>>>, media_controls: DomRefCell<HashMap<String, Dom<ShadowRoot>>>,
/// List of all WebGL context IDs that need flushing. /// 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. /// List of all WebGPU context IDs that need flushing.
dirty_webgpu_contexts: DomRefCell<HashMap<WebGPUContextId, Dom<GPUCanvasContext>>>, dirty_webgpu_contexts: DomRefCell<HashMap<WebGPUContextId, Dom<GPUCanvasContext>>>,
/// https://html.spec.whatwg.org/multipage/#concept-document-csp-list /// https://html.spec.whatwg.org/multipage/#concept-document-csp-list
#[ignore_malloc_size_of = "Defined in rust-content-security-policy"] #[ignore_malloc_size_of = "Defined in rust-content-security-policy"]
#[no_trace]
csp_list: DomRefCell<Option<CspList>>, csp_list: DomRefCell<Option<CspList>>,
/// https://w3c.github.io/slection-api/#dfn-selection /// https://w3c.github.io/slection-api/#dfn-selection
selection: MutNullableDom<Selection>, selection: MutNullableDom<Selection>,
@ -2865,11 +2881,11 @@ impl Document {
.for_each(|(_, context)| context.send_swap_chain_present()); .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() 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() self.name_map.borrow()
} }
} }
@ -3071,15 +3087,15 @@ impl Document {
url: DomRefCell::new(url), url: DomRefCell::new(url),
// https://dom.spec.whatwg.org/#concept-document-quirks // https://dom.spec.whatwg.org/#concept-document-quirks
quirks_mode: Cell::new(QuirksMode::NoQuirks), quirks_mode: Cell::new(QuirksMode::NoQuirks),
id_map: DomRefCell::new(HashMap::new()), id_map: DomRefCell::new(HashMapTracedValues::new()),
name_map: DomRefCell::new(HashMap::new()), name_map: DomRefCell::new(HashMapTracedValues::new()),
// https://dom.spec.whatwg.org/#concept-document-encoding // https://dom.spec.whatwg.org/#concept-document-encoding
encoding: Cell::new(encoding), encoding: Cell::new(encoding),
is_html_document: is_html_document == IsHTMLDocument::HTMLDocument, is_html_document: is_html_document == IsHTMLDocument::HTMLDocument,
activity: Cell::new(activity), activity: Cell::new(activity),
tag_map: DomRefCell::new(HashMap::new()), tag_map: DomRefCell::new(HashMapTracedValues::new()),
tagns_map: DomRefCell::new(HashMap::new()), tagns_map: DomRefCell::new(HashMapTracedValues::new()),
classes_map: DomRefCell::new(HashMap::new()), classes_map: DomRefCell::new(HashMapTracedValues::new()),
images: Default::default(), images: Default::default(),
embeds: Default::default(), embeds: Default::default(),
links: Default::default(), links: Default::default(),
@ -3164,7 +3180,7 @@ impl Document {
shadow_roots: DomRefCell::new(HashSet::new()), shadow_roots: DomRefCell::new(HashSet::new()),
shadow_roots_styles_changed: Cell::new(false), shadow_roots_styles_changed: Cell::new(false),
media_controls: DomRefCell::new(HashMap::new()), 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()), dirty_webgpu_contexts: DomRefCell::new(HashMap::new()),
csp_list: DomRefCell::new(None), csp_list: DomRefCell::new(None),
selection: MutNullableDom::new(None), selection: MutNullableDom::new(None),
@ -3494,8 +3510,10 @@ impl Document {
pub fn ensure_pending_restyle(&self, el: &Element) -> RefMut<PendingRestyle> { pub fn ensure_pending_restyle(&self, el: &Element) -> RefMut<PendingRestyle> {
let map = self.pending_restyles.borrow_mut(); let map = self.pending_restyles.borrow_mut();
RefMut::map(map, |m| { RefMut::map(map, |m| {
m.entry(Dom::from_ref(el)) &mut m
.or_insert_with(PendingRestyle::new) .entry(Dom::from_ref(el))
.or_insert_with(|| NoTrace(PendingRestyle::new()))
.0
}) })
} }
@ -3864,7 +3882,7 @@ impl Document {
return None; return None;
} }
node.note_dirty_descendants(); node.note_dirty_descendants();
Some((node.to_trusted_node_address(), restyle)) Some((node.to_trusted_node_address(), restyle.0))
}) })
.collect() .collect()
} }
@ -4838,6 +4856,7 @@ impl DocumentMethods for Document {
// Step 4. // Step 4.
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct DocumentNamedGetter { struct DocumentNamedGetter {
#[no_trace]
name: Atom, name: Atom,
} }
impl CollectionFilter for DocumentNamedGetter { 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 mut names_with_first_named_element_map: HashMap<&Atom, &Element> = HashMap::new();
let name_map = self.name_map.borrow(); let name_map = self.name_map.borrow();
for (name, elements) in &*name_map { for (name, elements) in &(*name_map).0 {
if name.is_empty() { if name.is_empty() {
continue; continue;
} }
@ -4890,7 +4909,7 @@ impl DocumentMethods for Document {
} }
} }
let id_map = self.id_map.borrow(); let id_map = self.id_map.borrow();
for (id, elements) in &*id_map { for (id, elements) in &(*id_map).0 {
if id.is_empty() { if id.is_empty() {
continue; continue;
} }
@ -5367,6 +5386,7 @@ impl PendingInOrderScriptVec {
#[unrooted_must_root_lint::must_root] #[unrooted_must_root_lint::must_root]
struct PendingScript { struct PendingScript {
element: Dom<HTMLScriptElement>, element: Dom<HTMLScriptElement>,
// TODO(sagudev): could this be all no_trace?
load: Option<ScriptResult>, load: Option<ScriptResult>,
} }

View file

@ -19,14 +19,15 @@ use crate::dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use servo_atoms::Atom; use servo_atoms::Atom;
use std::collections::HashMap;
use super::bindings::trace::HashMapTracedValues;
// https://dom.spec.whatwg.org/#documentfragment // https://dom.spec.whatwg.org/#documentfragment
#[dom_struct] #[dom_struct]
pub struct DocumentFragment { pub struct DocumentFragment {
node: Node, node: Node,
/// Caches for the getElement methods /// Caches for the getElement methods
id_map: DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>,
} }
impl DocumentFragment { impl DocumentFragment {
@ -34,7 +35,7 @@ impl DocumentFragment {
pub fn new_inherited(document: &Document) -> DocumentFragment { pub fn new_inherited(document: &Document) -> DocumentFragment {
DocumentFragment { DocumentFragment {
node: Node::new_inherited(document), 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)) 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 &self.id_map
} }
} }

View file

@ -17,17 +17,19 @@ use script_layout_interface::message::{NodesFromPointQueryType, QueryMsg};
use script_traits::UntrustedNodeAddress; use script_traits::UntrustedNodeAddress;
use servo_arc::Arc; use servo_arc::Arc;
use servo_atoms::Atom; use servo_atoms::Atom;
use std::collections::HashMap;
use std::fmt; use std::fmt;
use style::invalidation::media_queries::{MediaListKey, ToMediaListKey}; use style::invalidation::media_queries::{MediaListKey, ToMediaListKey};
use style::media_queries::MediaList; use style::media_queries::MediaList;
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard}; use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard};
use style::stylesheets::{Stylesheet, StylesheetContents}; use style::stylesheets::{Stylesheet, StylesheetContents};
use super::bindings::trace::HashMapTracedValues;
#[derive(Clone, JSTraceable, MallocSizeOf)] #[derive(Clone, JSTraceable, MallocSizeOf)]
#[unrooted_must_root_lint::must_root] #[unrooted_must_root_lint::must_root]
pub struct StyleSheetInDocument { pub struct StyleSheetInDocument {
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
pub sheet: Arc<Stylesheet>, pub sheet: Arc<Stylesheet>,
pub owner: Dom<Element>, 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. /// Remove any existing association between the provided id/name and any elements in this document.
pub fn unregister_named_element( pub fn unregister_named_element(
&self, &self,
id_map: &DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>,
to_unregister: &Element, to_unregister: &Element,
id: &Atom, id: &Atom,
) { ) {
@ -275,7 +277,7 @@ impl DocumentOrShadowRoot {
/// Associate an element present in this document with the provided id/name. /// Associate an element present in this document with the provided id/name.
pub fn register_named_element( pub fn register_named_element(
&self, &self,
id_map: &DomRefCell<HashMap<Atom, Vec<Dom<Element>>>>, id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>,
element: &Element, element: &Element,
id: &Atom, id: &Atom,
root: DomRoot<Node>, root: DomRoot<Node>,

View file

@ -34,6 +34,7 @@ use style::parser::ParserContext;
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub struct DOMMatrixReadOnly { pub struct DOMMatrixReadOnly {
reflector_: Reflector, reflector_: Reflector,
#[no_trace]
matrix: DomRefCell<Transform3D<f64>>, matrix: DomRefCell<Transform3D<f64>>,
is2D: Cell<bool>, is2D: Cell<bool>,
} }

View file

@ -19,7 +19,9 @@ use style::str::HTML_SPACE_CHARACTERS;
pub struct DOMTokenList { pub struct DOMTokenList {
reflector_: Reflector, reflector_: Reflector,
element: Dom<Element>, element: Dom<Element>,
#[no_trace]
local_name: LocalName, local_name: LocalName,
#[no_trace]
supported_tokens: Option<Vec<Atom>>, supported_tokens: Option<Vec<Atom>>,
} }

View file

@ -13,7 +13,7 @@ use uuid::Uuid;
/// An unique id for dynamic module /// An unique id for dynamic module
#[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)]
pub struct DynamicModuleId(pub Uuid); pub struct DynamicModuleId(#[no_trace] pub Uuid);
#[dom_struct] #[dom_struct]
pub struct DynamicModuleOwner { pub struct DynamicModuleOwner {

View file

@ -149,23 +149,31 @@ use xml5ever::serialize::TraversalScope::IncludeNode as XmlIncludeNode;
#[dom_struct] #[dom_struct]
pub struct Element { pub struct Element {
node: Node, node: Node,
#[no_trace]
local_name: LocalName, local_name: LocalName,
tag_name: TagName, tag_name: TagName,
#[no_trace]
namespace: Namespace, namespace: Namespace,
#[no_trace]
prefix: DomRefCell<Option<Prefix>>, prefix: DomRefCell<Option<Prefix>>,
attrs: DomRefCell<Vec<Dom<Attr>>>, attrs: DomRefCell<Vec<Dom<Attr>>>,
#[no_trace]
id_attribute: DomRefCell<Option<Atom>>, id_attribute: DomRefCell<Option<Atom>>,
#[no_trace]
is: DomRefCell<Option<LocalName>>, is: DomRefCell<Option<LocalName>>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
style_attribute: DomRefCell<Option<Arc<Locked<PropertyDeclarationBlock>>>>, style_attribute: DomRefCell<Option<Arc<Locked<PropertyDeclarationBlock>>>>,
attr_list: MutNullableDom<NamedNodeMap>, attr_list: MutNullableDom<NamedNodeMap>,
class_list: MutNullableDom<DOMTokenList>, class_list: MutNullableDom<DOMTokenList>,
#[no_trace]
state: Cell<ElementState>, state: Cell<ElementState>,
/// These flags are set by the style system to indicate the that certain /// These flags are set by the style system to indicate the that certain
/// operations may require restyling this element or its descendants. The /// operations may require restyling this element or its descendants. The
/// flags are not atomic, so the style system takes care of only set them /// flags are not atomic, so the style system takes care of only set them
/// when it has exclusive access to the element. /// when it has exclusive access to the element.
#[ignore_malloc_size_of = "bitflags defined in rust-selectors"] #[ignore_malloc_size_of = "bitflags defined in rust-selectors"]
#[no_trace]
selector_flags: Cell<ElementSelectorFlags>, selector_flags: Cell<ElementSelectorFlags>,
rare_data: DomRefCell<Option<Box<ElementRareData>>>, rare_data: DomRefCell<Option<Box<ElementRareData>>>,
} }
@ -3673,6 +3681,7 @@ impl<'a> AttributeMutation<'a> {
/// owner changes. /// owner changes.
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct TagName { struct TagName {
#[no_trace]
ptr: DomRefCell<Option<LocalName>>, ptr: DomRefCell<Option<LocalName>>,
} }

View file

@ -39,6 +39,7 @@ pub struct Event {
reflector_: Reflector, reflector_: Reflector,
current_target: MutNullableDom<EventTarget>, current_target: MutNullableDom<EventTarget>,
target: MutNullableDom<EventTarget>, target: MutNullableDom<EventTarget>,
#[no_trace]
type_: DomRefCell<Atom>, type_: DomRefCell<Atom>,
phase: Cell<EventPhase>, phase: Cell<EventPhase>,
canceled: Cell<EventDefault>, canceled: Cell<EventDefault>,

View file

@ -60,7 +60,9 @@ enum ReadyState {
#[dom_struct] #[dom_struct]
pub struct EventSource { pub struct EventSource {
eventtarget: EventTarget, eventtarget: EventTarget,
#[no_trace]
url: ServoUrl, url: ServoUrl,
#[no_trace]
request: DomRefCell<Option<RequestBuilder>>, request: DomRefCell<Option<RequestBuilder>>,
last_event_id: DomRefCell<DOMString>, last_event_id: DomRefCell<DOMString>,
reconnection_time: Cell<u64>, reconnection_time: Cell<u64>,
@ -647,6 +649,7 @@ pub struct EventSourceTimeoutCallback {
#[ignore_malloc_size_of = "Because it is non-owning"] #[ignore_malloc_size_of = "Because it is non-owning"]
event_source: Trusted<EventSource>, event_source: Trusted<EventSource>,
#[ignore_malloc_size_of = "Because it is non-owning"] #[ignore_malloc_size_of = "Because it is non-owning"]
#[no_trace]
action_sender: ipc::IpcSender<FetchResponseMsg>, action_sender: ipc::IpcSender<FetchResponseMsg>,
} }

View file

@ -44,7 +44,6 @@ use libc::c_char;
use servo_atoms::Atom; use servo_atoms::Atom;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
use std::default::Default; use std::default::Default;
use std::ffi::CString; use std::ffi::CString;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
@ -52,6 +51,8 @@ use std::mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::rc::Rc; use std::rc::Rc;
use super::bindings::trace::HashMapTracedValues;
#[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)]
pub enum CommonEventHandler { pub enum CommonEventHandler {
EventHandler(#[ignore_malloc_size_of = "Rc"] Rc<EventHandlerNonNull>), EventHandler(#[ignore_malloc_size_of = "Rc"] Rc<EventHandlerNonNull>),
@ -81,6 +82,7 @@ pub enum ListenerPhase {
#[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)]
struct InternalRawUncompiledHandler { struct InternalRawUncompiledHandler {
source: DOMString, source: DOMString,
#[no_trace]
url: ServoUrl, url: ServoUrl,
line: usize, line: usize,
} }
@ -344,7 +346,7 @@ impl EventListeners {
#[dom_struct] #[dom_struct]
pub struct EventTarget { pub struct EventTarget {
reflector_: Reflector, reflector_: Reflector,
handlers: DomRefCell<HashMap<Atom, EventListeners, BuildHasherDefault<FnvHasher>>>, handlers: DomRefCell<HashMapTracedValues<Atom, EventListeners, BuildHasherDefault<FnvHasher>>>,
} }
impl EventTarget { impl EventTarget {

View file

@ -38,8 +38,10 @@ use webxr_api::{
pub struct FakeXRDevice { pub struct FakeXRDevice {
reflector: Reflector, reflector: Reflector,
#[ignore_malloc_size_of = "defined in ipc-channel"] #[ignore_malloc_size_of = "defined in ipc-channel"]
#[no_trace]
sender: IpcSender<MockDeviceMsg>, sender: IpcSender<MockDeviceMsg>,
#[ignore_malloc_size_of = "defined in webxr-api"] #[ignore_malloc_size_of = "defined in webxr-api"]
#[no_trace]
next_input_id: Cell<InputId>, next_input_id: Cell<InputId>,
} }

View file

@ -23,8 +23,10 @@ use webxr_api::{
pub struct FakeXRInputController { pub struct FakeXRInputController {
reflector: Reflector, reflector: Reflector,
#[ignore_malloc_size_of = "defined in ipc-channel"] #[ignore_malloc_size_of = "defined in ipc-channel"]
#[no_trace]
sender: IpcSender<MockDeviceMsg>, sender: IpcSender<MockDeviceMsg>,
#[ignore_malloc_size_of = "defined in webxr-api"] #[ignore_malloc_size_of = "defined in webxr-api"]
#[no_trace]
id: InputId, id: InputId,
} }

View file

@ -20,10 +20,12 @@ use html5ever::LocalName;
use js::rust::HandleObject; use js::rust::HandleObject;
use script_traits::serializable::BlobImpl; use script_traits::serializable::BlobImpl;
use super::bindings::trace::NoTrace;
#[dom_struct] #[dom_struct]
pub struct FormData { pub struct FormData {
reflector_: Reflector, reflector_: Reflector,
data: DomRefCell<Vec<(LocalName, FormDatum)>>, data: DomRefCell<Vec<(NoTrace<LocalName>, FormDatum)>>,
} }
impl FormData { impl FormData {
@ -31,8 +33,8 @@ impl FormData {
let data = match form_datums { let data = match form_datums {
Some(data) => data Some(data) => data
.iter() .iter()
.map(|datum| (LocalName::from(datum.name.as_ref()), datum.clone())) .map(|datum| (NoTrace(LocalName::from(datum.name.as_ref())), datum.clone()))
.collect::<Vec<(LocalName, FormDatum)>>(), .collect::<Vec<(NoTrace<LocalName>, FormDatum)>>(),
None => Vec::new(), None => Vec::new(),
}; };
@ -87,7 +89,7 @@ impl FormDataMethods for FormData {
self.data self.data
.borrow_mut() .borrow_mut()
.push((LocalName::from(name.0), datum)); .push((NoTrace(LocalName::from(name.0)), datum));
} }
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
@ -101,14 +103,14 @@ impl FormDataMethods for FormData {
self.data self.data
.borrow_mut() .borrow_mut()
.push((LocalName::from(name.0), datum)); .push((NoTrace(LocalName::from(name.0)), datum));
} }
// https://xhr.spec.whatwg.org/#dom-formdata-delete // https://xhr.spec.whatwg.org/#dom-formdata-delete
fn Delete(&self, name: USVString) { fn Delete(&self, name: USVString) {
self.data self.data
.borrow_mut() .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 // https://xhr.spec.whatwg.org/#dom-formdata-get
@ -116,7 +118,7 @@ impl FormDataMethods for FormData {
self.data self.data
.borrow() .borrow()
.iter() .iter()
.filter(|(datum_name, _)| datum_name == &LocalName::from(name.0.clone())) .filter(|(datum_name, _)| datum_name.0 == LocalName::from(name.0.clone()))
.next() .next()
.map(|(_, datum)| match &datum.value { .map(|(_, datum)| match &datum.value {
FormDatumValue::String(ref s) => { FormDatumValue::String(ref s) => {
@ -131,12 +133,12 @@ impl FormDataMethods for FormData {
self.data self.data
.borrow() .borrow()
.iter() .iter()
.filter_map(|datum| { .filter_map(|(datum_name, datum)| {
if datum.0 != LocalName::from(name.0.clone()) { if datum_name.0 != LocalName::from(name.0.clone()) {
return None; return None;
} }
Some(match &datum.1.value { Some(match &datum.value {
FormDatumValue::String(ref s) => { FormDatumValue::String(ref s) => {
FileOrUSVString::USVString(USVString(s.to_string())) FileOrUSVString::USVString(USVString(s.to_string()))
}, },
@ -151,7 +153,7 @@ impl FormDataMethods for FormData {
self.data self.data
.borrow() .borrow()
.iter() .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 // https://xhr.spec.whatwg.org/#dom-formdata-set
@ -159,10 +161,10 @@ impl FormDataMethods for FormData {
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
let local_name = LocalName::from(name.0.clone()); 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(( data.push((
local_name, NoTrace(local_name),
FormDatum { FormDatum {
ty: DOMString::from("string"), ty: DOMString::from("string"),
name: DOMString::from(name.0), name: DOMString::from(name.0),
@ -177,10 +179,10 @@ impl FormDataMethods for FormData {
let mut data = self.data.borrow_mut(); let mut data = self.data.borrow_mut();
let local_name = LocalName::from(name.0.clone()); 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(( data.push((
LocalName::from(name.0.clone()), NoTrace(LocalName::from(name.0.clone())),
FormDatum { FormDatum {
ty: DOMString::from("file"), ty: DOMString::from("file"),
name: DOMString::from(name.0), name: DOMString::from(name.0),

View file

@ -129,6 +129,8 @@ use time::{get_time, Timespec};
use uuid::Uuid; use uuid::Uuid;
use webgpu::{identity::WebGPUOpResult, ErrorScopeId, WebGPUDevice}; use webgpu::{identity::WebGPUOpResult, ErrorScopeId, WebGPUDevice};
use super::bindings::trace::HashMapTracedValues;
#[derive(JSTraceable)] #[derive(JSTraceable)]
pub struct AutoCloseWorker { pub struct AutoCloseWorker {
/// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-closing /// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-closing
@ -137,6 +139,7 @@ pub struct AutoCloseWorker {
join_handle: Option<JoinHandle<()>>, join_handle: Option<JoinHandle<()>>,
/// A sender of control messages, /// A sender of control messages,
/// currently only used to signal shutdown. /// currently only used to signal shutdown.
#[no_trace]
control_sender: Sender<DedicatedWorkerControlMsg>, control_sender: Sender<DedicatedWorkerControlMsg>,
/// The context to request an interrupt on the worker thread. /// The context to request an interrupt on the worker thread.
context: ContextForRequestInterrupt, context: ContextForRequestInterrupt,
@ -187,13 +190,15 @@ pub struct GlobalScope {
blob_state: DomRefCell<BlobState>, blob_state: DomRefCell<BlobState>,
/// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-registration-object-map> /// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-registration-object-map>
registration_map: registration_map: DomRefCell<
DomRefCell<HashMap<ServiceWorkerRegistrationId, Dom<ServiceWorkerRegistration>>>, HashMapTracedValues<ServiceWorkerRegistrationId, Dom<ServiceWorkerRegistration>>,
>,
/// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-object-map> /// <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. /// Pipeline id associated with this global.
#[no_trace]
pipeline_id: PipelineId, pipeline_id: PipelineId,
/// A flag to indicate whether the developer tools has requested /// 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 /// module map is used when importing JavaScript modules
/// https://html.spec.whatwg.org/multipage/#concept-settings-object-module-map /// https://html.spec.whatwg.org/multipage/#concept-settings-object-module-map
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
module_map: DomRefCell<HashMap<ServoUrl, Rc<ModuleTree>>>, module_map: DomRefCell<HashMapTracedValues<ServoUrl, Rc<ModuleTree>>>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
inline_module_map: DomRefCell<HashMap<ScriptId, Rc<ModuleTree>>>, inline_module_map: DomRefCell<HashMap<ScriptId, Rc<ModuleTree>>>,
/// For providing instructions to an optional devtools server. /// For providing instructions to an optional devtools server.
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>, devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
/// For sending messages to the memory profiler. /// For sending messages to the memory profiler.
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
mem_profiler_chan: profile_mem::ProfilerChan, mem_profiler_chan: profile_mem::ProfilerChan,
/// For sending messages to the time profiler. /// For sending messages to the time profiler.
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
time_profiler_chan: profile_time::ProfilerChan, time_profiler_chan: profile_time::ProfilerChan,
/// A handle for communicating messages to the constellation thread. /// A handle for communicating messages to the constellation thread.
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
script_to_constellation_chan: ScriptToConstellationChan, script_to_constellation_chan: ScriptToConstellationChan,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
scheduler_chan: IpcSender<TimerSchedulerMsg>, scheduler_chan: IpcSender<TimerSchedulerMsg>,
/// <https://html.spec.whatwg.org/multipage/#in-error-reporting-mode> /// <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, /// Associated resource threads for use by DOM objects like XMLHttpRequest,
/// including resource_thread, filemanager_thread and storage_thread /// including resource_thread, filemanager_thread and storage_thread
#[no_trace]
resource_threads: ResourceThreads, resource_threads: ResourceThreads,
/// The mechanism by which time-outs and intervals are scheduled. /// The mechanism by which time-outs and intervals are scheduled.
@ -245,9 +256,11 @@ pub struct GlobalScope {
init_timers: Cell<bool>, init_timers: Cell<bool>,
/// The origin of the globalscope /// The origin of the globalscope
#[no_trace]
origin: MutableOrigin, origin: MutableOrigin,
/// https://html.spec.whatwg.org/multipage/#concept-environment-creation-url /// https://html.spec.whatwg.org/multipage/#concept-environment-creation-url
#[no_trace]
creation_url: Option<ServoUrl>, creation_url: Option<ServoUrl>,
/// A map for storing the previous permission state read results. /// A map for storing the previous permission state read results.
@ -296,16 +309,18 @@ pub struct GlobalScope {
/// Identity Manager for WebGPU resources /// Identity Manager for WebGPU resources
#[ignore_malloc_size_of = "defined in wgpu"] #[ignore_malloc_size_of = "defined in wgpu"]
#[no_trace]
gpu_id_hub: Arc<Mutex<Identities>>, gpu_id_hub: Arc<Mutex<Identities>>,
/// WebGPU devices /// WebGPU devices
gpu_devices: DomRefCell<HashMap<WebGPUDevice, Dom<GPUDevice>>>, gpu_devices: DomRefCell<HashMapTracedValues<WebGPUDevice, Dom<GPUDevice>>>,
// https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute // https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
frozen_supported_performance_entry_types: DomRefCell<Option<Heap<JSVal>>>, frozen_supported_performance_entry_types: DomRefCell<Option<Heap<JSVal>>>,
/// currect https state (from previous request) /// currect https state (from previous request)
#[no_trace]
https_state: Cell<HttpsState>, https_state: Cell<HttpsState>,
/// The stack of active group labels for the Console APIs. /// 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. /// The weak ref to the corresponding DOM object.
tracker: BlobTracker, tracker: BlobTracker,
/// The data and logic backing the DOM object. /// The data and logic backing the DOM object.
#[no_trace]
blob_impl: BlobImpl, blob_impl: BlobImpl,
/// Whether this blob has an outstanding URL, /// Whether this blob has an outstanding URL,
/// <https://w3c.github.io/FileAPI/#url>. /// <https://w3c.github.io/FileAPI/#url>.
@ -389,7 +405,7 @@ pub struct BlobInfo {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
pub enum BlobState { pub enum BlobState {
/// A map of managed blobs. /// A map of managed blobs.
Managed(HashMap<BlobId, BlobInfo>), Managed(HashMapTracedValues<BlobId, BlobInfo>),
/// This global is not managing any blobs at this time. /// This global is not managing any blobs at this time.
UnManaged, UnManaged,
} }
@ -412,6 +428,7 @@ pub struct ManagedMessagePort {
/// The option is needed to take out the port-impl /// The option is needed to take out the port-impl
/// as part of its transferring steps, /// as part of its transferring steps,
/// without having to worry about rooting the dom-port. /// without having to worry about rooting the dom-port.
#[no_trace]
port_impl: Option<MessagePortImpl>, port_impl: Option<MessagePortImpl>,
/// We keep ports pending when they are first transfer-received, /// We keep ports pending when they are first transfer-received,
/// and only add them, and ask the constellation to complete the transfer, /// 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 /// of https://html.spec.whatwg.org/multipage/#dom-broadcastchannel-postmessage
/// requires keeping track of creation order, hence the queue. /// requires keeping track of creation order, hence the queue.
Managed( Managed(
BroadcastChannelRouterId, #[no_trace] BroadcastChannelRouterId,
/// The map of channel-name to queue of channels, in order of creation. /// The map of channel-name to queue of channels, in order of creation.
HashMap<DOMString, VecDeque<Dom<BroadcastChannel>>>, HashMap<DOMString, VecDeque<Dom<BroadcastChannel>>>,
), ),
@ -444,8 +461,8 @@ pub enum BroadcastChannelState {
pub enum MessagePortState { pub enum MessagePortState {
/// The message-port router id for this global, and a map of managed ports. /// The message-port router id for this global, and a map of managed ports.
Managed( Managed(
MessagePortRouterId, #[no_trace] MessagePortRouterId,
HashMap<MessagePortId, ManagedMessagePort>, HashMapTracedValues<MessagePortId, ManagedMessagePort>,
), ),
/// This global is not managing any ports at this time. /// This global is not managing any ports at this time.
UnManaged, UnManaged,
@ -739,8 +756,8 @@ impl GlobalScope {
blob_state: DomRefCell::new(BlobState::UnManaged), blob_state: DomRefCell::new(BlobState::UnManaged),
eventtarget: EventTarget::new_inherited(), eventtarget: EventTarget::new_inherited(),
crypto: Default::default(), crypto: Default::default(),
registration_map: DomRefCell::new(HashMap::new()), registration_map: DomRefCell::new(HashMapTracedValues::new()),
worker_map: DomRefCell::new(HashMap::new()), worker_map: DomRefCell::new(HashMapTracedValues::new()),
pipeline_id, pipeline_id,
devtools_wants_updates: Default::default(), devtools_wants_updates: Default::default(),
console_timers: DomRefCell::new(Default::default()), console_timers: DomRefCell::new(Default::default()),
@ -766,7 +783,7 @@ impl GlobalScope {
is_headless, is_headless,
user_agent, user_agent,
gpu_id_hub, gpu_id_hub,
gpu_devices: DomRefCell::new(HashMap::new()), gpu_devices: DomRefCell::new(HashMapTracedValues::new()),
frozen_supported_performance_entry_types: DomRefCell::new(Default::default()), frozen_supported_performance_entry_types: DomRefCell::new(Default::default()),
https_state: Cell::new(HttpsState::None), https_state: Cell::new(HttpsState::None),
console_group_stack: DomRefCell::new(Vec::new()), console_group_stack: DomRefCell::new(Vec::new()),
@ -789,7 +806,7 @@ impl GlobalScope {
if let MessagePortState::Managed(_router_id, message_ports) = if let MessagePortState::Managed(_router_id, message_ports) =
&*self.message_port_state.borrow() &*self.message_port_state.borrow()
{ {
return message_ports.contains_key(port_id); return message_ports.contains_key(&*port_id);
} }
false false
} }
@ -976,7 +993,7 @@ impl GlobalScope {
&mut *self.message_port_state.borrow_mut() &mut *self.message_port_state.borrow_mut()
{ {
for (port_id, entangled_id) in &[(port1, port2), (port2, port1)] { 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 => { None => {
return warn!("entangled_ports called on a global not managing the port."); 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() &mut *self.message_port_state.borrow_mut()
{ {
let mut port_impl = message_ports let mut port_impl = message_ports
.remove(&port_id) .remove(&*port_id)
.map(|ref mut managed_port| { .map(|ref mut managed_port| {
managed_port managed_port
.port_impl .port_impl
@ -1040,7 +1057,7 @@ impl GlobalScope {
if let MessagePortState::Managed(_id, message_ports) = if let MessagePortState::Managed(_id, message_ports) =
&mut *self.message_port_state.borrow_mut() &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."), None => panic!("start_message_port called on a unknown port."),
Some(managed_port) => { Some(managed_port) => {
if let Some(port_impl) = managed_port.port_impl.as_mut() { if let Some(port_impl) = managed_port.port_impl.as_mut() {
@ -1073,7 +1090,7 @@ impl GlobalScope {
if let MessagePortState::Managed(_id, message_ports) = if let MessagePortState::Managed(_id, message_ports) =
&mut *self.message_port_state.borrow_mut() &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."), None => panic!("close_message_port called on an unknown port."),
Some(managed_port) => { Some(managed_port) => {
if let Some(port_impl) = managed_port.port_impl.as_mut() { if let Some(port_impl) = managed_port.port_impl.as_mut() {
@ -1306,7 +1323,7 @@ impl GlobalScope {
.collect(); .collect();
for id in to_be_added.iter() { for id in to_be_added.iter() {
let managed_port = message_ports let managed_port = message_ports
.get_mut(&id) .get_mut(&*id)
.expect("Collected port-id to match an entry"); .expect("Collected port-id to match an entry");
if !managed_port.pending { if !managed_port.pending {
panic!("Only pending ports should be found in to_be_added") panic!("Only pending ports should be found in to_be_added")
@ -1472,7 +1489,8 @@ impl GlobalScope {
}), }),
); );
let router_id = MessagePortRouterId::new(); 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 let _ = self
.script_to_constellation_chan() .script_to_constellation_chan()
.send(ScriptMsg::NewMessagePortRouter( .send(ScriptMsg::NewMessagePortRouter(
@ -1551,7 +1569,7 @@ impl GlobalScope {
match &mut *blob_state { match &mut *blob_state {
BlobState::UnManaged => { BlobState::UnManaged => {
let mut blobs_map = HashMap::new(); let mut blobs_map = HashMapTracedValues::new();
blobs_map.insert(blob_id, blob_info); blobs_map.insert(blob_id, blob_info);
*blob_state = BlobState::Managed(blobs_map); *blob_state = BlobState::Managed(blobs_map);
}, },
@ -1593,7 +1611,7 @@ impl GlobalScope {
fn perform_a_blob_garbage_collection_checkpoint(&self) { fn perform_a_blob_garbage_collection_checkpoint(&self) {
let mut blob_state = self.blob_state.borrow_mut(); let mut blob_state = self.blob_state.borrow_mut();
if let BlobState::Managed(blobs_map) = &mut *blob_state { 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 { let garbage_collected = match &blob_info.tracker {
BlobTracker::File(weak) => weak.root().is_none(), BlobTracker::File(weak) => weak.root().is_none(),
BlobTracker::Blob(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(); let blob_state = self.blob_state.borrow();
if let BlobState::Managed(blobs_map) = &*blob_state { if let BlobState::Managed(blobs_map) = &*blob_state {
let blob_info = blobs_map let blob_info = blobs_map
.get(blob_id) .get(&blob_id)
.expect("get_blob_bytes for an unknown blob."); .expect("get_blob_bytes for an unknown blob.");
match blob_info.blob_impl.blob_data() { match blob_info.blob_impl.blob_data() {
BlobData::Sliced(ref parent, ref rel_pos) => { BlobData::Sliced(ref parent, ref rel_pos) => {
@ -1671,7 +1689,7 @@ impl GlobalScope {
let blob_state = self.blob_state.borrow(); let blob_state = self.blob_state.borrow();
if let BlobState::Managed(blobs_map) = &*blob_state { if let BlobState::Managed(blobs_map) = &*blob_state {
let blob_info = blobs_map let blob_info = blobs_map
.get(blob_id) .get(&blob_id)
.expect("get_blob_bytes_non_sliced called for a unknown blob."); .expect("get_blob_bytes_non_sliced called for a unknown blob.");
match blob_info.blob_impl.blob_data() { match blob_info.blob_impl.blob_data() {
BlobData::File(ref f) => { BlobData::File(ref f) => {
@ -1709,7 +1727,7 @@ impl GlobalScope {
let blob_state = self.blob_state.borrow(); let blob_state = self.blob_state.borrow();
if let BlobState::Managed(blobs_map) = &*blob_state { if let BlobState::Managed(blobs_map) = &*blob_state {
let blob_info = blobs_map let blob_info = blobs_map
.get(blob_id) .get(&blob_id)
.expect("get_blob_bytes_or_file_id for an unknown blob."); .expect("get_blob_bytes_or_file_id for an unknown blob.");
match blob_info.blob_impl.blob_data() { match blob_info.blob_impl.blob_data() {
BlobData::Sliced(ref parent, ref rel_pos) => { BlobData::Sliced(ref parent, ref rel_pos) => {
@ -1745,7 +1763,7 @@ impl GlobalScope {
let blob_state = self.blob_state.borrow(); let blob_state = self.blob_state.borrow();
if let BlobState::Managed(blobs_map) = &*blob_state { if let BlobState::Managed(blobs_map) = &*blob_state {
let blob_info = blobs_map 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."); .expect("get_blob_bytes_non_sliced_or_file_id called for a unknown blob.");
match blob_info.blob_impl.blob_data() { match blob_info.blob_impl.blob_data() {
BlobData::File(ref f) => match f.get_cache() { BlobData::File(ref f) => match f.get_cache() {
@ -1767,7 +1785,7 @@ impl GlobalScope {
let blob_state = self.blob_state.borrow(); let blob_state = self.blob_state.borrow();
if let BlobState::Managed(blobs_map) = &*blob_state { if let BlobState::Managed(blobs_map) = &*blob_state {
let blob_info = blobs_map let blob_info = blobs_map
.get(blob_id) .get(&blob_id)
.expect("get_blob_type_string called for a unknown blob."); .expect("get_blob_type_string called for a unknown blob.");
blob_info.blob_impl.type_string() blob_info.blob_impl.type_string()
} else { } else {
@ -1781,7 +1799,7 @@ impl GlobalScope {
if let BlobState::Managed(blobs_map) = &*blob_state { if let BlobState::Managed(blobs_map) = &*blob_state {
let parent = { let parent = {
let blob_info = blobs_map let blob_info = blobs_map
.get(blob_id) .get(&blob_id)
.expect("get_blob_size called for a unknown blob."); .expect("get_blob_size called for a unknown blob.");
match blob_info.blob_impl.blob_data() { match blob_info.blob_impl.blob_data() {
BlobData::Sliced(ref parent, ref rel_pos) => { 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 rel_pos.to_abs_range(parent_size as usize).len() as u64
}, },
None => { 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() { match blob_info.blob_impl.blob_data() {
BlobData::File(ref f) => f.get_size(), BlobData::File(ref f) => f.get_size(),
BlobData::Memory(ref v) => v.len() as u64, BlobData::Memory(ref v) => v.len() as u64,
@ -1823,7 +1843,7 @@ impl GlobalScope {
if let BlobState::Managed(blobs_map) = &mut *blob_state { if let BlobState::Managed(blobs_map) = &mut *blob_state {
let parent = { let parent = {
let blob_info = blobs_map let blob_info = blobs_map
.get_mut(blob_id) .get_mut(&blob_id)
.expect("get_blob_url_id called for a unknown blob."); .expect("get_blob_url_id called for a unknown blob.");
// Keep track of blobs with outstanding URLs. // 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 parent_size = rel_pos.to_abs_range(parent_size as usize).len() as u64;
let blob_info = blobs_map let blob_info = blobs_map
.get_mut(blob_id) .get_mut(&blob_id)
.expect("Blob whose url is requested is unknown."); .expect("Blob whose url is requested is unknown.");
self.create_sliced_url_id(blob_info, &parent_file_id, &rel_pos, parent_size) self.create_sliced_url_id(blob_info, &parent_file_id, &rel_pos, parent_size)
}, },
None => { None => {
let blob_info = blobs_map let blob_info = blobs_map
.get_mut(blob_id) .get_mut(&blob_id)
.expect("Blob whose url is requested is unknown."); .expect("Blob whose url is requested is unknown.");
self.promote(blob_info, /* set_valid is */ true) self.promote(blob_info, /* set_valid is */ true)
}, },
@ -2206,7 +2226,7 @@ impl GlobalScope {
self.module_map.borrow_mut().insert(url, Rc::new(module)); 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 &self.module_map
} }

View file

@ -26,10 +26,12 @@ use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, WebGPURe
pub struct GPUAdapter { pub struct GPUAdapter {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
name: DOMString, name: DOMString,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
extensions: Heap<*mut JSObject>, extensions: Heap<*mut JSObject>,
#[no_trace]
adapter: WebGPUAdapter, adapter: WebGPUAdapter,
} }

View file

@ -16,7 +16,9 @@ use webgpu::{WebGPUBindGroup, WebGPUDevice};
pub struct GPUBindGroup { pub struct GPUBindGroup {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
bind_group: WebGPUBindGroup, bind_group: WebGPUBindGroup,
#[no_trace]
device: WebGPUDevice, device: WebGPUDevice,
layout: Dom<GPUBindGroupLayout>, layout: Dom<GPUBindGroupLayout>,
} }

View file

@ -15,6 +15,7 @@ use webgpu::WebGPUBindGroupLayout;
pub struct GPUBindGroupLayout { pub struct GPUBindGroupLayout {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
bind_group_layout: WebGPUBindGroupLayout, bind_group_layout: WebGPUBindGroupLayout,
} }

View file

@ -59,9 +59,11 @@ pub struct GPUBufferMapInfo {
pub struct GPUBuffer { pub struct GPUBuffer {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
state: Cell<GPUBufferState>, state: Cell<GPUBufferState>,
#[no_trace]
buffer: WebGPUBuffer, buffer: WebGPUBuffer,
device: Dom<GPUDevice>, device: Dom<GPUDevice>,
size: GPUSize64, size: GPUSize64,

View file

@ -37,11 +37,14 @@ pub struct WebGPUContextId(pub u64);
pub struct GPUCanvasContext { pub struct GPUCanvasContext {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
canvas: Dom<HTMLCanvasElement>, canvas: Dom<HTMLCanvasElement>,
#[no_trace]
size: Cell<Size2D<u32>>, size: Cell<Size2D<u32>>,
swap_chain: DomRefCell<Option<Dom<GPUSwapChain>>>, swap_chain: DomRefCell<Option<Dom<GPUSwapChain>>>,
#[ignore_malloc_size_of = "Defined in webrender"] #[ignore_malloc_size_of = "Defined in webrender"]
#[no_trace]
webrender_image: Cell<Option<webrender_api::ImageKey>>, webrender_image: Cell<Option<webrender_api::ImageKey>>,
context_id: WebGPUContextId, context_id: WebGPUContextId,
} }

View file

@ -26,8 +26,10 @@ impl Hash for DomRoot<GPUBuffer> {
pub struct GPUCommandBuffer { pub struct GPUCommandBuffer {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
command_buffer: WebGPUCommandBuffer, command_buffer: WebGPUCommandBuffer,
buffers: DomRefCell<HashSet<Dom<GPUBuffer>>>, buffers: DomRefCell<HashSet<Dom<GPUBuffer>>>,
} }

View file

@ -44,8 +44,10 @@ pub enum GPUCommandEncoderState {
pub struct GPUCommandEncoder { pub struct GPUCommandEncoder {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
encoder: webgpu::WebGPUCommandEncoder, encoder: webgpu::WebGPUCommandEncoder,
buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>, buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>,
state: DomRefCell<GPUCommandEncoderState>, state: DomRefCell<GPUCommandEncoderState>,

View file

@ -22,9 +22,11 @@ use webgpu::{
pub struct GPUComputePassEncoder { pub struct GPUComputePassEncoder {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[ignore_malloc_size_of = "defined in wgpu-core"] #[ignore_malloc_size_of = "defined in wgpu-core"]
#[no_trace]
compute_pass: DomRefCell<Option<ComputePass>>, compute_pass: DomRefCell<Option<ComputePass>>,
command_encoder: Dom<GPUCommandEncoder>, command_encoder: Dom<GPUCommandEncoder>,
} }

View file

@ -19,7 +19,9 @@ use webgpu::{WebGPUBindGroupLayout, WebGPUComputePipeline};
pub struct GPUComputePipeline { pub struct GPUComputePipeline {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
compute_pipeline: WebGPUComputePipeline, compute_pipeline: WebGPUComputePipeline,
#[no_trace]
bind_group_layouts: Vec<WebGPUBindGroupLayout>, bind_group_layouts: Vec<WebGPUBindGroupLayout>,
device: Dom<GPUDevice>, device: Dom<GPUDevice>,
} }

View file

@ -108,6 +108,7 @@ struct ScopeContext {
pub struct GPUDevice { pub struct GPUDevice {
eventtarget: EventTarget, eventtarget: EventTarget,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
adapter: Dom<GPUAdapter>, adapter: Dom<GPUAdapter>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
@ -115,6 +116,7 @@ pub struct GPUDevice {
#[ignore_malloc_size_of = "Because it is non-owning"] #[ignore_malloc_size_of = "Because it is non-owning"]
limits: GPULimits, limits: GPULimits,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
device: webgpu::WebGPUDevice, device: webgpu::WebGPUDevice,
default_queue: Dom<GPUQueue>, default_queue: Dom<GPUQueue>,
scope_context: DomRefCell<ScopeContext>, scope_context: DomRefCell<ScopeContext>,

View file

@ -15,7 +15,9 @@ use webgpu::{WebGPUBindGroupLayout, WebGPUPipelineLayout};
pub struct GPUPipelineLayout { pub struct GPUPipelineLayout {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
pipeline_layout: WebGPUPipelineLayout, pipeline_layout: WebGPUPipelineLayout,
#[no_trace]
bind_group_layouts: Vec<WebGPUBindGroupLayout>, bind_group_layouts: Vec<WebGPUBindGroupLayout>,
} }

View file

@ -27,9 +27,11 @@ use webgpu::{identity::WebGPUOpResult, wgt, WebGPU, WebGPUQueue, WebGPURequest};
pub struct GPUQueue { pub struct GPUQueue {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
device: DomRefCell<Option<Dom<GPUDevice>>>, device: DomRefCell<Option<Dom<GPUDevice>>>,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
queue: WebGPUQueue, queue: WebGPUQueue,
} }

View file

@ -15,8 +15,11 @@ use webgpu::{WebGPU, WebGPUDevice, WebGPURenderBundle};
pub struct GPURenderBundle { pub struct GPURenderBundle {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
#[no_trace]
device: WebGPUDevice, device: WebGPUDevice,
#[no_trace]
render_bundle: WebGPURenderBundle, render_bundle: WebGPURenderBundle,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
} }

View file

@ -24,9 +24,11 @@ use webgpu::{
pub struct GPURenderBundleEncoder { pub struct GPURenderBundleEncoder {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
device: Dom<GPUDevice>, device: Dom<GPUDevice>,
#[ignore_malloc_size_of = "defined in wgpu-core"] #[ignore_malloc_size_of = "defined in wgpu-core"]
#[no_trace]
render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>, render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
} }

View file

@ -25,9 +25,11 @@ use webgpu::{
pub struct GPURenderPassEncoder { pub struct GPURenderPassEncoder {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[ignore_malloc_size_of = "defined in wgpu-core"] #[ignore_malloc_size_of = "defined in wgpu-core"]
#[no_trace]
render_pass: DomRefCell<Option<RenderPass>>, render_pass: DomRefCell<Option<RenderPass>>,
command_encoder: Dom<GPUCommandEncoder>, command_encoder: Dom<GPUCommandEncoder>,
} }

View file

@ -19,7 +19,9 @@ use webgpu::{WebGPUBindGroupLayout, WebGPURenderPipeline};
pub struct GPURenderPipeline { pub struct GPURenderPipeline {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
render_pipeline: WebGPURenderPipeline, render_pipeline: WebGPURenderPipeline,
#[no_trace]
bind_group_layouts: Vec<WebGPUBindGroupLayout>, bind_group_layouts: Vec<WebGPUBindGroupLayout>,
device: Dom<GPUDevice>, device: Dom<GPUDevice>,
} }

View file

@ -15,8 +15,10 @@ use webgpu::{WebGPUDevice, WebGPUSampler};
pub struct GPUSampler { pub struct GPUSampler {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
device: WebGPUDevice, device: WebGPUDevice,
compare_enable: bool, compare_enable: bool,
#[no_trace]
sampler: WebGPUSampler, sampler: WebGPUSampler,
} }

View file

@ -15,6 +15,7 @@ use webgpu::WebGPUShaderModule;
pub struct GPUShaderModule { pub struct GPUShaderModule {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
shader_module: WebGPUShaderModule, shader_module: WebGPUShaderModule,
} }

View file

@ -18,6 +18,7 @@ use webrender_api::ImageKey;
pub struct GPUSwapChain { pub struct GPUSwapChain {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
context: Dom<GPUCanvasContext>, context: Dom<GPUCanvasContext>,

View file

@ -29,10 +29,12 @@ use webgpu::{
#[dom_struct] #[dom_struct]
pub struct GPUTexture { pub struct GPUTexture {
reflector_: Reflector, reflector_: Reflector,
#[no_trace]
texture: WebGPUTexture, texture: WebGPUTexture,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
device: Dom<GPUDevice>, device: Dom<GPUDevice>,
#[ignore_malloc_size_of = "channels are hard"] #[ignore_malloc_size_of = "channels are hard"]
#[no_trace]
channel: WebGPU, channel: WebGPU,
#[ignore_malloc_size_of = "defined in webgpu"] #[ignore_malloc_size_of = "defined in webgpu"]
texture_size: GPUExtent3DDict, texture_size: GPUExtent3DDict,

View file

@ -16,6 +16,7 @@ use webgpu::WebGPUTextureView;
pub struct GPUTextureView { pub struct GPUTextureView {
reflector_: Reflector, reflector_: Reflector,
label: DomRefCell<Option<USVString>>, label: DomRefCell<Option<USVString>>,
#[no_trace]
texture_view: WebGPUTextureView, texture_view: WebGPUTextureView,
texture: Dom<GPUTexture>, texture: Dom<GPUTexture>,
} }

View file

@ -25,6 +25,7 @@ pub struct Headers {
reflector_: Reflector, reflector_: Reflector,
guard: Cell<Guard>, guard: Cell<Guard>,
#[ignore_malloc_size_of = "Defined in hyper"] #[ignore_malloc_size_of = "Defined in hyper"]
#[no_trace]
header_list: DomRefCell<HyperHeaders>, header_list: DomRefCell<HyperHeaders>,
} }

View file

@ -42,6 +42,7 @@ pub struct History {
window: Dom<Window>, window: Dom<Window>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
state: Heap<JSVal>, state: Heap<JSVal>,
#[no_trace]
state_id: Cell<Option<HistoryStateId>>, state_id: Cell<Option<HistoryStateId>>,
} }

View file

@ -42,6 +42,7 @@ use style::attr::AttrValue;
pub struct HTMLAnchorElement { pub struct HTMLAnchorElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
rel_list: MutNullableDom<DOMTokenList>, rel_list: MutNullableDom<DOMTokenList>,
#[no_trace]
url: DomRefCell<Option<ServoUrl>>, url: DomRefCell<Option<ServoUrl>>,
} }

View file

@ -164,7 +164,9 @@ impl HTMLCollection {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct HtmlDocumentFilter { struct HtmlDocumentFilter {
#[no_trace]
qualified_name: LocalName, qualified_name: LocalName,
#[no_trace]
ascii_lower_qualified_name: LocalName, ascii_lower_qualified_name: LocalName,
} }
impl CollectionFilter for HtmlDocumentFilter { impl CollectionFilter for HtmlDocumentFilter {
@ -216,6 +218,7 @@ impl HTMLCollection {
) -> DomRoot<HTMLCollection> { ) -> DomRoot<HTMLCollection> {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct TagNameNSFilter { struct TagNameNSFilter {
#[no_trace]
qname: QualName, qname: QualName,
} }
impl CollectionFilter for TagNameNSFilter { impl CollectionFilter for TagNameNSFilter {
@ -245,6 +248,7 @@ impl HTMLCollection {
) -> DomRoot<HTMLCollection> { ) -> DomRoot<HTMLCollection> {
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct ClassNameFilter { struct ClassNameFilter {
#[no_trace]
classes: Vec<Atom>, classes: Vec<Atom>,
} }
impl CollectionFilter for ClassNameFilter { impl CollectionFilter for ClassNameFilter {

View file

@ -76,11 +76,12 @@ use style::element_state::ElementState;
use style::str::split_html_space_chars; use style::str::split_html_space_chars;
use crate::dom::bindings::codegen::UnionTypes::RadioNodeListOrElement; use crate::dom::bindings::codegen::UnionTypes::RadioNodeListOrElement;
use std::collections::HashMap;
use time::{now, Duration, Tm}; use time::{now, Duration, Tm};
use crate::dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods}; use crate::dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
use super::bindings::trace::{HashMapTracedValues, NoTrace};
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
pub struct GenerationId(u32); pub struct GenerationId(u32);
@ -93,7 +94,7 @@ pub struct HTMLFormElement {
elements: DomOnceCell<HTMLFormControlsCollection>, elements: DomOnceCell<HTMLFormControlsCollection>,
generation_id: Cell<GenerationId>, generation_id: Cell<GenerationId>,
controls: DomRefCell<Vec<Dom<Element>>>, 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>, firing_submission_events: Cell<bool>,
rel_list: MutNullableDom<DOMTokenList>, rel_list: MutNullableDom<DOMTokenList>,
} }
@ -116,7 +117,7 @@ impl HTMLFormElement {
elements: Default::default(), elements: Default::default(),
generation_id: Cell::new(GenerationId(0)), generation_id: Cell::new(GenerationId(0)),
controls: DomRefCell::new(Vec::new()), 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), firing_submission_events: Cell::new(false),
rel_list: Default::default(), rel_list: Default::default(),
} }
@ -441,7 +442,7 @@ impl HTMLFormElementMethods for HTMLFormElement {
name, name,
( (
Dom::from_ref(&*element_node.downcast::<Element>().unwrap()), Dom::from_ref(&*element_node.downcast::<Element>().unwrap()),
now(), NoTrace(now()),
), ),
); );
@ -555,7 +556,7 @@ impl HTMLFormElementMethods for HTMLFormElement {
let entry = SourcedName { let entry = SourcedName {
name: key.clone(), name: key.clone(),
element: DomRoot::from_ref(&*val.0), 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); sourced_names_vec.push(entry);
} }
@ -1336,7 +1337,7 @@ impl HTMLFormElement {
// changes form owner, then its entries must be removed // changes form owner, then its entries must be removed
// from that map." // from that map."
let mut past_names_map = self.past_names_map.borrow_mut(); 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(); self.update_validity();
} }

View file

@ -71,10 +71,15 @@ enum ProcessingMode {
#[dom_struct] #[dom_struct]
pub struct HTMLIFrameElement { pub struct HTMLIFrameElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
#[no_trace]
top_level_browsing_context_id: Cell<Option<TopLevelBrowsingContextId>>, top_level_browsing_context_id: Cell<Option<TopLevelBrowsingContextId>>,
#[no_trace]
browsing_context_id: Cell<Option<BrowsingContextId>>, browsing_context_id: Cell<Option<BrowsingContextId>>,
#[no_trace]
pipeline_id: Cell<Option<PipelineId>>, pipeline_id: Cell<Option<PipelineId>>,
#[no_trace]
pending_pipeline_id: Cell<Option<PipelineId>>, pending_pipeline_id: Cell<Option<PipelineId>>,
#[no_trace]
about_blank_pipeline_id: Cell<Option<PipelineId>>, about_blank_pipeline_id: Cell<Option<PipelineId>>,
sandbox: MutNullableDom<DOMTokenList>, sandbox: MutNullableDom<DOMTokenList>,
sandbox_allowance: Cell<Option<SandboxAllowance>>, sandbox_allowance: Cell<Option<SandboxAllowance>>,

View file

@ -142,12 +142,16 @@ enum ImageRequestPhase {
#[unrooted_must_root_lint::must_root] #[unrooted_must_root_lint::must_root]
struct ImageRequest { struct ImageRequest {
state: State, state: State,
#[no_trace]
parsed_url: Option<ServoUrl>, parsed_url: Option<ServoUrl>,
source_url: Option<USVString>, source_url: Option<USVString>,
blocker: Option<LoadBlocker>, blocker: Option<LoadBlocker>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
image: Option<Arc<Image>>, image: Option<Arc<Image>>,
#[no_trace]
metadata: Option<ImageMetadata>, metadata: Option<ImageMetadata>,
#[no_trace]
final_url: Option<ServoUrl>, final_url: Option<ServoUrl>,
current_pixel_density: Option<f64>, current_pixel_density: Option<f64>,
} }

View file

@ -255,6 +255,7 @@ pub struct HTMLInputElement {
maxlength: Cell<i32>, maxlength: Cell<i32>,
minlength: Cell<i32>, minlength: Cell<i32>,
#[ignore_malloc_size_of = "#7193"] #[ignore_malloc_size_of = "#7193"]
#[no_trace]
textinput: DomRefCell<TextInput<ScriptToConstellationChan>>, textinput: DomRefCell<TextInput<ScriptToConstellationChan>>,
// https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag // https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag
value_dirty: Cell<bool>, value_dirty: Cell<bool>,

View file

@ -57,6 +57,7 @@ pub struct HTMLLinkElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
rel_list: MutNullableDom<DOMTokenList>, rel_list: MutNullableDom<DOMTokenList>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
stylesheet: DomRefCell<Option<Arc<Stylesheet>>>, stylesheet: DomRefCell<Option<Arc<Stylesheet>>>,
cssom_stylesheet: MutNullableDom<CSSStyleSheet>, cssom_stylesheet: MutNullableDom<CSSStyleSheet>,

View file

@ -333,10 +333,13 @@ pub struct HTMLMediaElement {
#[ignore_malloc_size_of = "promises are hard"] #[ignore_malloc_size_of = "promises are hard"]
in_flight_play_promises_queue: DomRefCell<VecDeque<(Box<[Rc<Promise>]>, ErrorResult)>>, in_flight_play_promises_queue: DomRefCell<VecDeque<(Box<[Rc<Promise>]>, ErrorResult)>>,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
player: DomRefCell<Option<Arc<Mutex<dyn Player>>>>, player: DomRefCell<Option<Arc<Mutex<dyn Player>>>>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
video_renderer: Arc<Mutex<MediaFrameRenderer>>, video_renderer: Arc<Mutex<MediaFrameRenderer>>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
audio_renderer: DomRefCell<Option<Arc<Mutex<dyn AudioRenderer>>>>, audio_renderer: DomRefCell<Option<Arc<Mutex<dyn AudioRenderer>>>>,
/// https://html.spec.whatwg.org/multipage/#show-poster-flag /// https://html.spec.whatwg.org/multipage/#show-poster-flag
show_poster: Cell<bool>, show_poster: Cell<bool>,
@ -353,9 +356,11 @@ pub struct HTMLMediaElement {
/// https://html.spec.whatwg.org/multipage/#dom-media-muted /// https://html.spec.whatwg.org/multipage/#dom-media-muted
muted: Cell<bool>, muted: Cell<bool>,
/// URL of the media resource, if any. /// URL of the media resource, if any.
#[no_trace]
resource_url: DomRefCell<Option<ServoUrl>>, resource_url: DomRefCell<Option<ServoUrl>>,
/// URL of the media resource, if the resource is set through the src_object attribute and it /// URL of the media resource, if the resource is set through the src_object attribute and it
/// is a blob. /// is a blob.
#[no_trace]
blob_url: DomRefCell<Option<ServoUrl>>, blob_url: DomRefCell<Option<ServoUrl>>,
/// https://html.spec.whatwg.org/multipage/#dom-media-played /// https://html.spec.whatwg.org/multipage/#dom-media-played
#[ignore_malloc_size_of = "Rc"] #[ignore_malloc_size_of = "Rc"]
@ -368,6 +373,7 @@ pub struct HTMLMediaElement {
text_tracks_list: MutNullableDom<TextTrackList>, text_tracks_list: MutNullableDom<TextTrackList>,
/// Time of last timeupdate notification. /// Time of last timeupdate notification.
#[ignore_malloc_size_of = "Defined in time"] #[ignore_malloc_size_of = "Defined in time"]
#[no_trace]
next_timeupdate_event: Cell<Timespec>, next_timeupdate_event: Cell<Timespec>,
/// Latest fetch request context. /// Latest fetch request context.
current_fetch_context: DomRefCell<Option<HTMLMediaElementFetchContext>>, current_fetch_context: DomRefCell<Option<HTMLMediaElementFetchContext>>,
@ -379,6 +385,7 @@ pub struct HTMLMediaElement {
/// keeping a whitelist of media controls identifiers. /// keeping a whitelist of media controls identifiers.
media_controls_id: DomRefCell<Option<String>>, media_controls_id: DomRefCell<Option<String>>,
#[ignore_malloc_size_of = "Defined in other crates"] #[ignore_malloc_size_of = "Defined in other crates"]
#[no_trace]
player_context: WindowGLContext, player_context: WindowGLContext,
} }
@ -2471,6 +2478,7 @@ pub enum MediaElementMicrotask {
ResourceSelectionTask { ResourceSelectionTask {
elem: DomRoot<HTMLMediaElement>, elem: DomRoot<HTMLMediaElement>,
generation_id: u32, generation_id: u32,
#[no_trace]
base_url: ServoUrl, base_url: ServoUrl,
}, },
PauseIfNotInDocumentTask { PauseIfNotInDocumentTask {

View file

@ -27,6 +27,7 @@ use std::default::Default;
pub struct HTMLObjectElement { pub struct HTMLObjectElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
image: DomRefCell<Option<Arc<Image>>>, image: DomRefCell<Option<Arc<Image>>>,
form_owner: MutNullableDom<HTMLFormElement>, form_owner: MutNullableDom<HTMLFormElement>,
validity_state: MutNullableDom<ValidityState>, validity_state: MutNullableDom<ValidityState>,

View file

@ -13,6 +13,7 @@ use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::settings_stack::AutoEntryScript; use crate::dom::bindings::settings_stack::AutoEntryScript;
use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::bindings::trace::NoTrace;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::element::{ use crate::dom::element::{
cors_setting_for_element, referrer_policy_for_element, reflect_cross_origin_attribute, 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 compiled_script = FinishOffThreadStencil(*cx, token.0, ptr::null_mut());
let load = if compiled_script.is_null() { let load = if compiled_script.is_null() {
Err(NetworkError::Internal( Err(NoTrace(NetworkError::Internal(
"Off-thread compilation failed.".into(), "Off-thread compilation failed.".into(),
)) )))
} else { } else {
let script_text = DOMString::from(script); let script_text = DOMString::from(script);
let code = SourceCode::Compiled(CompiledSourceCode { let code = SourceCode::Compiled(CompiledSourceCode {
@ -144,7 +145,7 @@ unsafe extern "C" fn off_thread_compilation_callback(
/// An unique id for script element. /// An unique id for script element.
#[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, PartialEq)]
pub struct ScriptId(Uuid); pub struct ScriptId(#[no_trace] Uuid);
#[dom_struct] #[dom_struct]
pub struct HTMLScriptElement { pub struct HTMLScriptElement {
@ -257,6 +258,7 @@ pub enum SourceCode {
pub struct ScriptOrigin { pub struct ScriptOrigin {
#[ignore_malloc_size_of = "Rc is hard"] #[ignore_malloc_size_of = "Rc is hard"]
code: SourceCode, code: SourceCode,
#[no_trace]
url: ServoUrl, url: ServoUrl,
external: bool, external: bool,
fetch_options: ScriptFetchOptions, fetch_options: ScriptFetchOptions,
@ -326,7 +328,7 @@ fn finish_fetching_a_classic_script(
document.finish_load(LoadType::Script(url)); 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. /// The context required for asynchronously loading an external script source.
struct ClassicContext { struct ClassicContext {
@ -400,7 +402,7 @@ impl FetchResponseListener for ClassicContext {
&*self.elem.root(), &*self.elem.root(),
self.kind.clone(), self.kind.clone(),
self.url.clone(), self.url.clone(),
Err(err.clone()), Err(NoTrace(err.clone())),
); );
return; return;
}, },

View file

@ -34,6 +34,7 @@ use style_traits::ParsingMode;
pub struct HTMLStyleElement { pub struct HTMLStyleElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
stylesheet: DomRefCell<Option<Arc<Stylesheet>>>, stylesheet: DomRefCell<Option<Arc<Stylesheet>>>,
cssom_stylesheet: MutNullableDom<CSSStyleSheet>, cssom_stylesheet: MutNullableDom<CSSStyleSheet>,
/// <https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts> /// <https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts>

View file

@ -49,6 +49,7 @@ use style::element_state::ElementState;
pub struct HTMLTextAreaElement { pub struct HTMLTextAreaElement {
htmlelement: HTMLElement, htmlelement: HTMLElement,
#[ignore_malloc_size_of = "#7193"] #[ignore_malloc_size_of = "#7193"]
#[no_trace]
textinput: DomRefCell<TextInput<ScriptToConstellationChan>>, textinput: DomRefCell<TextInput<ScriptToConstellationChan>>,
placeholder: DomRefCell<DOMString>, placeholder: DomRefCell<DOMString>,
// https://html.spec.whatwg.org/multipage/#concept-textarea-dirty // https://html.spec.whatwg.org/multipage/#concept-textarea-dirty

View file

@ -60,6 +60,7 @@ pub struct HTMLVideoElement {
load_blocker: DomRefCell<Option<LoadBlocker>>, load_blocker: DomRefCell<Option<LoadBlocker>>,
/// A copy of the last frame /// A copy of the last frame
#[ignore_malloc_size_of = "VideoFrame"] #[ignore_malloc_size_of = "VideoFrame"]
#[no_trace]
last_frame: DomRefCell<Option<VideoFrame>>, last_frame: DomRefCell<Option<VideoFrame>>,
} }

View file

@ -24,6 +24,7 @@ pub struct MediaList {
reflector_: Reflector, reflector_: Reflector,
parent_stylesheet: Dom<CSSStyleSheet>, parent_stylesheet: Dom<CSSStyleSheet>,
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
media_queries: Arc<Locked<StyleMediaList>>, media_queries: Arc<Locked<StyleMediaList>>,
} }

View file

@ -27,6 +27,7 @@ pub enum MediaQueryListMatchState {
pub struct MediaQueryList { pub struct MediaQueryList {
eventtarget: EventTarget, eventtarget: EventTarget,
document: Dom<Document>, document: Dom<Document>,
#[no_trace]
media_query_list: MediaList, media_query_list: MediaList,
last_match_state: Cell<Option<bool>>, last_match_state: Cell<Option<bool>>,
} }

View file

@ -26,20 +26,23 @@ use embedder_traits::MediaMetadata as EmbedderMediaMetadata;
use embedder_traits::MediaSessionEvent; use embedder_traits::MediaSessionEvent;
use script_traits::MediaSessionActionType; use script_traits::MediaSessionActionType;
use script_traits::ScriptMsg; use script_traits::ScriptMsg;
use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use super::bindings::trace::HashMapTracedValues;
#[dom_struct] #[dom_struct]
pub struct MediaSession { pub struct MediaSession {
reflector_: Reflector, reflector_: Reflector,
/// https://w3c.github.io/mediasession/#dom-mediasession-metadata /// https://w3c.github.io/mediasession/#dom-mediasession-metadata
#[ignore_malloc_size_of = "defined in embedder_traits"] #[ignore_malloc_size_of = "defined in embedder_traits"]
#[no_trace]
metadata: DomRefCell<Option<EmbedderMediaMetadata>>, metadata: DomRefCell<Option<EmbedderMediaMetadata>>,
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate /// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
playback_state: DomRefCell<MediaSessionPlaybackState>, playback_state: DomRefCell<MediaSessionPlaybackState>,
/// https://w3c.github.io/mediasession/#supported-media-session-actions /// https://w3c.github.io/mediasession/#supported-media-session-actions
#[ignore_malloc_size_of = "Rc"] #[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. /// The media instance controlled by this media session.
/// For now only HTMLMediaElements are controlled by media sessions. /// For now only HTMLMediaElements are controlled by media sessions.
media_instance: MutNullableDom<HTMLMediaElement>, media_instance: MutNullableDom<HTMLMediaElement>,
@ -52,7 +55,7 @@ impl MediaSession {
reflector_: Reflector::new(), reflector_: Reflector::new(),
metadata: DomRefCell::new(None), metadata: DomRefCell::new(None),
playback_state: DomRefCell::new(MediaSessionPlaybackState::None), playback_state: DomRefCell::new(MediaSessionPlaybackState::None),
action_handlers: DomRefCell::new(HashMap::new()), action_handlers: DomRefCell::new(HashMapTracedValues::new()),
media_instance: Default::default(), media_instance: Default::default(),
}; };
media_session media_session

View file

@ -16,8 +16,10 @@ use servo_media::streams::MediaStreamType;
pub struct MediaStreamTrack { pub struct MediaStreamTrack {
eventtarget: EventTarget, eventtarget: EventTarget,
#[ignore_malloc_size_of = "defined in servo-media"] #[ignore_malloc_size_of = "defined in servo-media"]
#[no_trace]
id: MediaStreamId, id: MediaStreamId,
#[ignore_malloc_size_of = "defined in servo-media"] #[ignore_malloc_size_of = "defined in servo-media"]
#[no_trace]
ty: MediaStreamType, ty: MediaStreamType,
} }

View file

@ -33,7 +33,9 @@ use std::rc::Rc;
/// The MessagePort used in the DOM. /// The MessagePort used in the DOM.
pub struct MessagePort { pub struct MessagePort {
eventtarget: EventTarget, eventtarget: EventTarget,
#[no_trace]
message_port_id: MessagePortId, message_port_id: MessagePortId,
#[no_trace]
entangled_port: RefCell<Option<MessagePortId>>, entangled_port: RefCell<Option<MessagePortId>>,
detached: Cell<bool>, detached: Cell<bool>,
} }

View file

@ -43,6 +43,7 @@ pub struct MouseEvent {
button: Cell<i16>, button: Cell<i16>,
buttons: Cell<u16>, buttons: Cell<u16>,
related_target: MutNullableDom<EventTarget>, related_target: MutNullableDom<EventTarget>,
#[no_trace]
point_in_target: Cell<Option<Point2D<f32>>>, point_in_target: Cell<Option<Point2D<f32>>>,
} }

View file

@ -151,6 +151,7 @@ pub struct Node {
/// Style+Layout information. /// Style+Layout information.
#[ignore_malloc_size_of = "trait object"] #[ignore_malloc_size_of = "trait object"]
#[no_trace]
style_and_layout_data: DomRefCell<Option<Box<StyleAndOpaqueLayoutData>>>, style_and_layout_data: DomRefCell<Option<Box<StyleAndOpaqueLayoutData>>>,
} }

View file

@ -392,6 +392,7 @@ pub enum RadioListMode {
pub struct RadioList { pub struct RadioList {
form: Dom<HTMLFormElement>, form: Dom<HTMLFormElement>,
mode: RadioListMode, mode: RadioListMode,
#[no_trace]
name: Atom, name: Atom,
} }

View file

@ -35,6 +35,7 @@ use style_traits::DevicePixel;
#[dom_struct] #[dom_struct]
pub struct PaintRenderingContext2D { pub struct PaintRenderingContext2D {
context: CanvasRenderingContext2D, context: CanvasRenderingContext2D,
#[no_trace]
device_pixel_ratio: Cell<Scale<f32, CSSPixel, DevicePixel>>, device_pixel_ratio: Cell<Scale<f32, CSSPixel, DevicePixel>>,
} }

View file

@ -55,7 +55,6 @@ use servo_config::pref;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::cell::Cell; use std::cell::Cell;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::ptr::null_mut; use std::ptr::null_mut;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
@ -66,6 +65,8 @@ use style_traits::CSSPixel;
use style_traits::DevicePixel; use style_traits::DevicePixel;
use style_traits::SpeculativePainter; use style_traits::SpeculativePainter;
use super::bindings::trace::HashMapTracedValues;
/// <https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope> /// <https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope>
#[dom_struct] #[dom_struct]
pub struct PaintWorkletGlobalScope { pub struct PaintWorkletGlobalScope {
@ -73,23 +74,29 @@ pub struct PaintWorkletGlobalScope {
worklet_global: WorkletGlobalScope, worklet_global: WorkletGlobalScope,
/// The image cache /// The image cache
#[ignore_malloc_size_of = "Arc"] #[ignore_malloc_size_of = "Arc"]
#[no_trace]
image_cache: Arc<dyn ImageCache>, image_cache: Arc<dyn ImageCache>,
/// <https://drafts.css-houdini.org/css-paint-api/#paint-definitions> /// <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> /// <https://drafts.css-houdini.org/css-paint-api/#paint-class-instances>
#[ignore_malloc_size_of = "mozjs"] #[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 /// The most recent name the worklet was called with
#[no_trace]
cached_name: DomRefCell<Atom>, cached_name: DomRefCell<Atom>,
/// The most recent size the worklet was drawn at /// The most recent size the worklet was drawn at
#[no_trace]
cached_size: Cell<Size2D<f32, CSSPixel>>, cached_size: Cell<Size2D<f32, CSSPixel>>,
/// The most recent device pixel ratio the worklet was drawn at /// The most recent device pixel ratio the worklet was drawn at
#[no_trace]
cached_device_pixel_ratio: Cell<Scale<f32, CSSPixel, DevicePixel>>, cached_device_pixel_ratio: Cell<Scale<f32, CSSPixel, DevicePixel>>,
/// The most recent properties the worklet was drawn at /// The most recent properties the worklet was drawn at
#[no_trace]
cached_properties: DomRefCell<Vec<(Atom, String)>>, cached_properties: DomRefCell<Vec<(Atom, String)>>,
/// The most recent arguments the worklet was drawn at /// The most recent arguments the worklet was drawn at
cached_arguments: DomRefCell<Vec<String>>, cached_arguments: DomRefCell<Vec<String>>,
/// The most recent result /// The most recent result
#[no_trace]
cached_result: DomRefCell<DrawAPaintImageResult>, cached_result: DomRefCell<DrawAPaintImageResult>,
} }

View file

@ -42,8 +42,10 @@ pub struct PannerNode {
orientation_y: Dom<AudioParam>, orientation_y: Dom<AudioParam>,
orientation_z: Dom<AudioParam>, orientation_z: Dom<AudioParam>,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
panning_model: Cell<PanningModel>, panning_model: Cell<PanningModel>,
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
#[no_trace]
distance_model: Cell<DistanceModel>, distance_model: Cell<DistanceModel>,
ref_distance: Cell<f64>, ref_distance: Cell<f64>,
max_distance: Cell<f64>, max_distance: Cell<f64>,

View file

@ -47,7 +47,9 @@ pub struct ElementRareData {
pub custom_element_state: CustomElementState, pub custom_element_state: CustomElementState,
/// The "name" content attribute; not used as frequently as id, but used /// 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 /// in named getter loops so it's worth looking up quickly when present
#[no_trace]
pub name_attribute: Option<Atom>, pub name_attribute: Option<Atom>,
/// The client rect reported by layout. /// The client rect reported by layout.
#[no_trace]
pub client_rect: Option<LayoutValue<Rect<i32>>>, pub client_rect: Option<LayoutValue<Rect<i32>>>,
} }

View file

@ -48,6 +48,7 @@ use std::str::FromStr;
#[dom_struct] #[dom_struct]
pub struct Request { pub struct Request {
reflector_: Reflector, reflector_: Reflector,
#[no_trace]
request: DomRefCell<NetTraitsRequest>, request: DomRefCell<NetTraitsRequest>,
body_stream: MutNullableDom<ReadableStream>, body_stream: MutNullableDom<ReadableStream>,
headers: MutNullableDom<Headers>, headers: MutNullableDom<Headers>,

View file

@ -40,10 +40,13 @@ pub struct Response {
headers_reflector: MutNullableDom<Headers>, headers_reflector: MutNullableDom<Headers>,
/// `None` can be considered a StatusCode of `0`. /// `None` can be considered a StatusCode of `0`.
#[ignore_malloc_size_of = "Defined in hyper"] #[ignore_malloc_size_of = "Defined in hyper"]
#[no_trace]
status: DomRefCell<Option<StatusCode>>, status: DomRefCell<Option<StatusCode>>,
raw_status: DomRefCell<Option<(u16, Vec<u8>)>>, raw_status: DomRefCell<Option<(u16, Vec<u8>)>>,
response_type: DomRefCell<DOMResponseType>, response_type: DomRefCell<DOMResponseType>,
#[no_trace]
url: DomRefCell<Option<ServoUrl>>, url: DomRefCell<Option<ServoUrl>>,
#[no_trace]
url_list: DomRefCell<Vec<ServoUrl>>, url_list: DomRefCell<Vec<ServoUrl>>,
/// The stream of https://fetch.spec.whatwg.org/#body. /// The stream of https://fetch.spec.whatwg.org/#body.
body_stream: MutNullableDom<ReadableStream>, body_stream: MutNullableDom<ReadableStream>,

View file

@ -59,6 +59,7 @@ use std::rc::Rc;
pub struct RTCPeerConnection { pub struct RTCPeerConnection {
eventtarget: EventTarget, eventtarget: EventTarget,
#[ignore_malloc_size_of = "defined in servo-media"] #[ignore_malloc_size_of = "defined in servo-media"]
#[no_trace]
controller: DomRefCell<Option<WebRtcController>>, controller: DomRefCell<Option<WebRtcController>>,
closed: Cell<bool>, closed: Cell<bool>,
// Helps track state changes between the time createOffer/createAnswer // Helps track state changes between the time createOffer/createAnswer

View file

@ -34,8 +34,10 @@ pub type TrustedServiceWorkerAddress = Trusted<ServiceWorker>;
pub struct ServiceWorker { pub struct ServiceWorker {
eventtarget: EventTarget, eventtarget: EventTarget,
script_url: DomRefCell<String>, script_url: DomRefCell<String>,
#[no_trace]
scope_url: ServoUrl, scope_url: ServoUrl,
state: Cell<ServiceWorkerState>, state: Cell<ServiceWorkerState>,
#[no_trace]
worker_id: ServiceWorkerId, worker_id: ServiceWorkerId,
} }

View file

@ -131,6 +131,7 @@ pub enum MixedMessage {
#[derive(Clone, JSTraceable)] #[derive(Clone, JSTraceable)]
pub struct ServiceWorkerChan { pub struct ServiceWorkerChan {
#[no_trace]
pub sender: Sender<ServiceWorkerScriptMsg>, pub sender: Sender<ServiceWorkerScriptMsg>,
} }
@ -150,16 +151,16 @@ impl ScriptChan for ServiceWorkerChan {
} }
} }
unsafe_no_jsmanaged_fields!(TaskQueue<ServiceWorkerScriptMsg>);
#[dom_struct] #[dom_struct]
pub struct ServiceWorkerGlobalScope { pub struct ServiceWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope, workerglobalscope: WorkerGlobalScope,
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace]
task_queue: TaskQueue<ServiceWorkerScriptMsg>, task_queue: TaskQueue<ServiceWorkerScriptMsg>,
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace]
own_sender: Sender<ServiceWorkerScriptMsg>, own_sender: Sender<ServiceWorkerScriptMsg>,
/// A port on which a single "time-out" message can be received, /// 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 /// while still draining the task-queue
// and running all enqueued, and not cancelled, tasks. // and running all enqueued, and not cancelled, tasks.
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace]
time_out_port: Receiver<Instant>, time_out_port: Receiver<Instant>,
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace]
swmanager_sender: IpcSender<ServiceWorkerMsg>, swmanager_sender: IpcSender<ServiceWorkerMsg>,
#[no_trace]
scope_url: ServoUrl, scope_url: ServoUrl,
/// A receiver of control messages, /// A receiver of control messages,
/// currently only used to signal shutdown. /// currently only used to signal shutdown.
#[ignore_malloc_size_of = "Channels are hard"] #[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
control_receiver: Receiver<ServiceWorkerControlMsg>, control_receiver: Receiver<ServiceWorkerControlMsg>,
} }

Some files were not shown because too many files have changed in this diff Show more