mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Use mozjs tracing infrastructure (#29918)
* Update mozjs
64711ec2e6
also fixes https://github.com/servo/servo/issues/30043
* Move to mozjs Traceable and introduce CustomTraceable
This commit is contained in:
parent
1f7f4cf2be
commit
450f8193a5
20 changed files with 81 additions and 377 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -3704,7 +3704,7 @@ checksum = "903970ae2f248d7275214cf8f387f8ba0c4ea7e3d87a320e85493db60ce28616"
|
|||
[[package]]
|
||||
name = "mozjs"
|
||||
version = "0.14.1"
|
||||
source = "git+https://github.com/servo/mozjs#98b678283d1b0c6d263302ca2aff770aece0cb8e"
|
||||
source = "git+https://github.com/servo/mozjs#64711ec2e6dc4595df691bffc7f1e5052ab86c8d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lazy_static",
|
||||
|
@ -3717,7 +3717,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "mozjs_sys"
|
||||
version = "0.68.2"
|
||||
source = "git+https://github.com/servo/mozjs#98b678283d1b0c6d263302ca2aff770aece0cb8e"
|
||||
source = "git+https://github.com/servo/mozjs#64711ec2e6dc4595df691bffc7f1e5052ab86c8d"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
|
|
|
@ -7,7 +7,7 @@ extern crate syn;
|
|||
#[macro_use]
|
||||
extern crate synstructure;
|
||||
|
||||
decl_derive!([JSTraceable, attributes(no_trace)] =>
|
||||
decl_derive!([JSTraceable, attributes(no_trace, custom_trace)] =>
|
||||
/// Implements `JSTraceable` on structs and enums
|
||||
///
|
||||
/// Example:
|
||||
|
@ -17,6 +17,8 @@ decl_derive!([JSTraceable, attributes(no_trace)] =>
|
|||
/// js_managed: JSManagedType,
|
||||
/// #[no_trace]
|
||||
/// non_js: NonJSManagedType,
|
||||
/// #[custom_trace] // Extern type implements CustomTraceable that is in servo => no problem with orphan rules
|
||||
/// extern_managed_type: Extern<JSManagedType>,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -30,6 +32,7 @@ decl_derive!([JSTraceable, attributes(no_trace)] =>
|
|||
/// S {
|
||||
/// js_managed: ref __binding_0,
|
||||
/// non_js: ref __binding_1,
|
||||
/// extern_managed_type: ref __binding_2,
|
||||
/// } => {
|
||||
/// {
|
||||
/// __binding_0.trace(tracer);
|
||||
|
@ -37,6 +40,9 @@ decl_derive!([JSTraceable, attributes(no_trace)] =>
|
|||
/// {
|
||||
/// // __binding_1 is not traceable so we do not need to trace it
|
||||
/// }
|
||||
/// {
|
||||
/// <crate::dom::bindings::trace::CustomTraceable>::trace(__binding_2, tracer);
|
||||
/// }
|
||||
/// },
|
||||
/// }
|
||||
/// }
|
||||
|
@ -150,9 +156,12 @@ fn js_traceable_derive(s: synstructure::Structure) -> proc_macro2::TokenStream {
|
|||
if path.is_ident("no_trace") {
|
||||
asserts.extend(assert_not_impl_traceable(&binding.ast().ty));
|
||||
return None;
|
||||
} else if path.is_ident("custom_trace") {
|
||||
return Some(quote!(<crate::dom::bindings::trace::CustomTraceable>::trace(#binding, tracer);));
|
||||
}
|
||||
},
|
||||
syn::Meta::NameValue(syn::MetaNameValue { ref path, .. }) => {
|
||||
// if reason provided we can skip JSTraceable check
|
||||
if path.is_ident("no_trace") {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ impl RecordKey for ByteString {
|
|||
/// The `Record` (open-ended dictionary) type.
|
||||
#[derive(Clone, JSTraceable)]
|
||||
pub struct Record<K: RecordKey, V> {
|
||||
#[custom_trace]
|
||||
map: IndexMap<K, V>,
|
||||
}
|
||||
|
||||
|
|
|
@ -46,32 +46,23 @@ use crate::script_thread::IncompleteParserContexts;
|
|||
use crate::task::TaskBox;
|
||||
use indexmap::IndexMap;
|
||||
use js::glue::{CallObjectTracer, CallScriptTracer, CallStringTracer, CallValueTracer};
|
||||
use js::jsapi::{
|
||||
GCTraceKindToAscii, Heap, JSObject, JSScript, JSString, JSTracer, JobQueue, TraceKind,
|
||||
};
|
||||
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSScript, JSString, JSTracer, TraceKind};
|
||||
use js::jsval::JSVal;
|
||||
use js::rust::{GCMethods, Handle, Runtime, Stencil};
|
||||
use js::typedarray::TypedArray;
|
||||
use js::typedarray::TypedArrayElement;
|
||||
use js::rust::{GCMethods, Handle};
|
||||
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
use parking_lot::RwLock;
|
||||
use servo_arc::Arc as ServoArc;
|
||||
use smallvec::SmallVec;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{Cell, RefCell, UnsafeCell};
|
||||
|
||||
use std::collections::hash_map::RandomState;
|
||||
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::mem;
|
||||
use std::num::NonZeroU64;
|
||||
use std::ops::{Deref, DerefMut, Range};
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||
use std::sync::Arc;
|
||||
use std::thread::JoinHandle;
|
||||
use std::time::{Instant, SystemTime};
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use style::author_styles::AuthorStyles;
|
||||
use style::stylesheet_set::{AuthorStylesheetSet, DocumentStylesheetSet};
|
||||
use tendril::fmt::UTF8;
|
||||
|
@ -79,14 +70,28 @@ use tendril::stream::LossyDecoder;
|
|||
use tendril::TendrilSink;
|
||||
use webxr_api::{Finger, Hand};
|
||||
|
||||
unsafe_no_jsmanaged_fields!(JoinHandle<()>);
|
||||
|
||||
/// A trait to allow tracing (only) DOM objects.
|
||||
pub unsafe trait JSTraceable {
|
||||
pub use js::gc::Traceable as JSTraceable;
|
||||
|
||||
/// A trait to allow tracing only DOM sub-objects.
|
||||
pub unsafe trait CustomTraceable {
|
||||
/// Trace `self`.
|
||||
unsafe fn trace(&self, trc: *mut JSTracer);
|
||||
}
|
||||
|
||||
unsafe impl<T: CustomTraceable> CustomTraceable for Box<T> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(**self).trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: CustomTraceable> CustomTraceable for DomRefCell<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(*self).borrow().trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper type for nop traceble
|
||||
///
|
||||
/// SAFETY: Inner type must not impl JSTraceable
|
||||
|
@ -236,10 +241,7 @@ unsafe_no_jsmanaged_fields!(IncompleteParserContexts);
|
|||
|
||||
unsafe_no_jsmanaged_fields!(Reflector);
|
||||
|
||||
unsafe_no_jsmanaged_fields!(*mut JobQueue);
|
||||
|
||||
unsafe_no_jsmanaged_fields!(Cow<'static, str>);
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Trace a `JSScript`.
|
||||
pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut JSScript>) {
|
||||
unsafe {
|
||||
|
@ -252,6 +254,7 @@ pub fn trace_script(tracer: *mut JSTracer, description: &str, script: &Heap<*mut
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Trace a `JSVal`.
|
||||
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) {
|
||||
unsafe {
|
||||
|
@ -287,6 +290,7 @@ pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: &Heap<*mut JS
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Trace a `JSString`.
|
||||
pub fn trace_string(tracer: *mut JSTracer, description: &str, s: &Heap<*mut JSString>) {
|
||||
unsafe {
|
||||
|
@ -299,122 +303,25 @@ pub fn trace_string(tracer: *mut JSTracer, description: &str, s: &Heap<*mut JSSt
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for Rc<T> {
|
||||
unsafe impl<T: JSTraceable> CustomTraceable for ServoArc<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(**self).trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for Arc<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(**self).trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for ServoArc<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(**self).trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for RwLock<T> {
|
||||
unsafe impl<T: JSTraceable> CustomTraceable for RwLock<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
self.read().trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable + ?Sized> JSTraceable for Box<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(**self).trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for [T] {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for e in self.iter() {
|
||||
e.trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable + Copy> JSTraceable for Cell<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
self.get().trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for UnsafeCell<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(*self.get()).trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for DomRefCell<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(*self).borrow().trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for RefCell<T> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
(*self).borrow().trace(trc)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl JSTraceable for Heap<*mut JSScript> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
if self.get().is_null() {
|
||||
return;
|
||||
}
|
||||
trace_script(trc, "heap script", self);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl JSTraceable for Heap<*mut JSObject> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
if self.get().is_null() {
|
||||
return;
|
||||
}
|
||||
trace_object(trc, "heap object", self);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl JSTraceable for Heap<*mut JSString> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
if self.get().is_null() {
|
||||
return;
|
||||
}
|
||||
trace_string(trc, "heap string", self);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl JSTraceable for Heap<JSVal> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
trace_jsval(trc, "heap value", self);
|
||||
}
|
||||
}
|
||||
|
||||
// XXXManishearth Check if the following three are optimized to no-ops
|
||||
// if e.trace() is a no-op (e.g it is an unsafe_no_jsmanaged_fields type)
|
||||
unsafe impl<T: JSTraceable> JSTraceable for Vec<T> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for e in &*self {
|
||||
e.trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for VecDeque<T> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for e in &*self {
|
||||
e.trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable + Eq + Hash> JSTraceable for indexmap::IndexSet<T> {
|
||||
unsafe impl<T: JSTraceable + Eq + Hash> CustomTraceable for indexmap::IndexSet<T> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for e in self.iter() {
|
||||
|
@ -423,24 +330,9 @@ unsafe impl<T: JSTraceable + Eq + Hash> JSTraceable for indexmap::IndexSet<T> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<A, B, C, D> JSTraceable for (A, B, C, D)
|
||||
where
|
||||
A: JSTraceable,
|
||||
B: JSTraceable,
|
||||
C: JSTraceable,
|
||||
D: JSTraceable,
|
||||
{
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
self.0.trace(trc);
|
||||
self.1.trace(trc);
|
||||
self.2.trace(trc);
|
||||
self.3.trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
// XXXManishearth Check if the following three are optimized to no-ops
|
||||
// if e.trace() is a no-op (e.g it is an unsafe_no_jsmanaged_fields type)
|
||||
unsafe impl<T: JSTraceable + 'static> JSTraceable for SmallVec<[T; 1]> {
|
||||
unsafe impl<T: JSTraceable + 'static> CustomTraceable for SmallVec<[T; 1]> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for e in self.iter() {
|
||||
|
@ -449,24 +341,7 @@ unsafe impl<T: JSTraceable + 'static> JSTraceable for SmallVec<[T; 1]> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable> JSTraceable for Option<T> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
self.as_ref().map(|e| e.trace(trc));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: JSTraceable, U: JSTraceable> JSTraceable for Result<T, U> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
match *self {
|
||||
Ok(ref inner) => inner.trace(trc),
|
||||
Err(ref inner) => inner.trace(trc),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<K, V, S> JSTraceable for HashMap<K, V, S>
|
||||
unsafe impl<K, V, S> CustomTraceable for IndexMap<K, V, S>
|
||||
where
|
||||
K: Hash + Eq + JSTraceable,
|
||||
V: JSTraceable,
|
||||
|
@ -481,107 +356,19 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T, S> JSTraceable for HashSet<T, S>
|
||||
where
|
||||
T: Hash + Eq + JSTraceable,
|
||||
S: BuildHasher,
|
||||
{
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for v in &*self {
|
||||
v.trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<K: Ord + JSTraceable, V: JSTraceable> JSTraceable for BTreeMap<K, V> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for (k, v) in self {
|
||||
k.trace(trc);
|
||||
v.trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<K, V, S> JSTraceable for IndexMap<K, V, S>
|
||||
where
|
||||
K: Hash + Eq + JSTraceable,
|
||||
V: JSTraceable,
|
||||
S: BuildHasher,
|
||||
{
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
for (k, v) in &*self {
|
||||
k.trace(trc);
|
||||
v.trace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<A: JSTraceable, B: JSTraceable> JSTraceable for (A, B) {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
let (ref a, ref b) = *self;
|
||||
a.trace(trc);
|
||||
b.trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
let (ref a, ref b, ref c) = *self;
|
||||
a.trace(trc);
|
||||
b.trace(trc);
|
||||
c.trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, char);
|
||||
unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64);
|
||||
unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64);
|
||||
unsafe_no_jsmanaged_fields!(NonZeroU64);
|
||||
unsafe_no_jsmanaged_fields!(Error);
|
||||
unsafe_no_jsmanaged_fields!(TrustedPromise);
|
||||
|
||||
unsafe_no_jsmanaged_fields!(Runtime);
|
||||
unsafe_no_jsmanaged_fields!(ContextForRequestInterrupt);
|
||||
unsafe_no_jsmanaged_fields!(WindowProxyHandler);
|
||||
unsafe_no_jsmanaged_fields!(DOMString);
|
||||
unsafe_no_jsmanaged_fields!(USVString);
|
||||
unsafe_no_jsmanaged_fields!(SystemTime);
|
||||
unsafe_no_jsmanaged_fields!(Instant);
|
||||
unsafe_no_jsmanaged_fields!(PathBuf);
|
||||
unsafe_no_jsmanaged_fields!(WebGPUContextId);
|
||||
unsafe_no_jsmanaged_fields!(GPUBufferState);
|
||||
unsafe_no_jsmanaged_fields!(GPUCommandEncoderState);
|
||||
unsafe_no_jsmanaged_fields!(Range<u64>);
|
||||
unsafe_no_jsmanaged_fields!(SourceSet);
|
||||
unsafe_no_jsmanaged_fields!(HTMLMediaElementFetchContext);
|
||||
unsafe_no_jsmanaged_fields!(StreamConsumer);
|
||||
unsafe_no_jsmanaged_fields!(Stencil);
|
||||
|
||||
unsafe impl<'a> JSTraceable for &'a str {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, _: *mut JSTracer) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<A, B> JSTraceable for fn(A) -> B {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, _: *mut JSTracer) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl JSTraceable for () {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, _: *mut JSTracer) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: DomObject> JSTraceable for Trusted<T> {
|
||||
#[inline]
|
||||
|
@ -590,16 +377,7 @@ unsafe impl<T: DomObject> JSTraceable for Trusted<T> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> JSTraceable for TypedArray<T, Box<Heap<*mut JSObject>>>
|
||||
where
|
||||
T: TypedArrayElement,
|
||||
{
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
self.underlying_object().trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<S> JSTraceable for DocumentStylesheetSet<S>
|
||||
unsafe impl<S> CustomTraceable for DocumentStylesheetSet<S>
|
||||
where
|
||||
S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
|
@ -610,7 +388,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<S> JSTraceable for AuthorStylesheetSet<S>
|
||||
unsafe impl<S> CustomTraceable for AuthorStylesheetSet<S>
|
||||
where
|
||||
S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
|
@ -621,7 +399,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<S> JSTraceable for AuthorStyles<S>
|
||||
unsafe impl<S> CustomTraceable for AuthorStyles<S>
|
||||
where
|
||||
S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
|
@ -630,7 +408,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<Sink> JSTraceable for LossyDecoder<Sink>
|
||||
unsafe impl<Sink> CustomTraceable for LossyDecoder<Sink>
|
||||
where
|
||||
Sink: JSTraceable + TendrilSink<UTF8>,
|
||||
{
|
||||
|
@ -639,7 +417,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<J> JSTraceable for Hand<J>
|
||||
unsafe impl<J> CustomTraceable for Hand<J>
|
||||
where
|
||||
J: JSTraceable,
|
||||
{
|
||||
|
@ -669,7 +447,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<J> JSTraceable for Finger<J>
|
||||
unsafe impl<J> CustomTraceable for Finger<J>
|
||||
where
|
||||
J: JSTraceable,
|
||||
{
|
||||
|
@ -692,47 +470,7 @@ where
|
|||
}
|
||||
|
||||
/// Holds a set of JSTraceables that need to be rooted
|
||||
struct RootedTraceableSet {
|
||||
set: Vec<*const dyn JSTraceable>,
|
||||
}
|
||||
|
||||
thread_local!(
|
||||
/// TLV Holds a set of JSTraceables that need to be rooted
|
||||
static ROOTED_TRACEABLES: RefCell<RootedTraceableSet> = RefCell::new(RootedTraceableSet::new());
|
||||
);
|
||||
|
||||
impl RootedTraceableSet {
|
||||
fn new() -> RootedTraceableSet {
|
||||
RootedTraceableSet { set: vec![] }
|
||||
}
|
||||
|
||||
unsafe fn remove(traceable: *const dyn JSTraceable) {
|
||||
ROOTED_TRACEABLES.with(|ref traceables| {
|
||||
let mut traceables = traceables.borrow_mut();
|
||||
let idx = match traceables
|
||||
.set
|
||||
.iter()
|
||||
.rposition(|x| *x as *const () == traceable as *const ())
|
||||
{
|
||||
Some(idx) => idx,
|
||||
None => unreachable!(),
|
||||
};
|
||||
traceables.set.remove(idx);
|
||||
});
|
||||
}
|
||||
|
||||
unsafe fn add(traceable: *const dyn JSTraceable) {
|
||||
ROOTED_TRACEABLES.with(|ref traceables| {
|
||||
traceables.borrow_mut().set.push(traceable);
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
||||
for traceable in &self.set {
|
||||
(**traceable).trace(tracer);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use js::gc::RootedTraceableSet;
|
||||
|
||||
/// Roots any JSTraceable thing
|
||||
///
|
||||
|
@ -741,29 +479,23 @@ impl RootedTraceableSet {
|
|||
/// If you have an arbitrary number of DomObjects to root, use rooted_vec!.
|
||||
/// If you know what you're doing, use this.
|
||||
#[unrooted_must_root_lint::allow_unrooted_interior]
|
||||
pub struct RootedTraceableBox<T: 'static + JSTraceable> {
|
||||
ptr: *mut T,
|
||||
}
|
||||
pub struct RootedTraceableBox<T: JSTraceable + 'static>(js::gc::RootedTraceableBox<T>);
|
||||
|
||||
unsafe impl<T: JSTraceable + 'static> JSTraceable for RootedTraceableBox<T> {
|
||||
unsafe fn trace(&self, tracer: *mut JSTracer) {
|
||||
(*self.ptr).trace(tracer);
|
||||
self.0.trace(tracer);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JSTraceable + 'static> RootedTraceableBox<T> {
|
||||
/// DomRoot a JSTraceable thing for the life of this RootedTraceableBox
|
||||
pub fn new(traceable: T) -> RootedTraceableBox<T> {
|
||||
Self::from_box(Box::new(traceable))
|
||||
Self(js::gc::RootedTraceableBox::new(traceable))
|
||||
}
|
||||
|
||||
/// Consumes a boxed JSTraceable and roots it for the life of this RootedTraceableBox.
|
||||
pub fn from_box(boxed_traceable: Box<T>) -> RootedTraceableBox<T> {
|
||||
let traceable = Box::into_raw(boxed_traceable);
|
||||
unsafe {
|
||||
RootedTraceableSet::add(traceable);
|
||||
}
|
||||
RootedTraceableBox { ptr: traceable }
|
||||
Self(js::gc::RootedTraceableBox::from_box(boxed_traceable))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,7 +505,7 @@ where
|
|||
T: GCMethods + Copy,
|
||||
{
|
||||
pub fn handle(&self) -> Handle<T> {
|
||||
unsafe { Handle::from_raw((*self.ptr).handle()) }
|
||||
self.0.handle()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,7 +513,7 @@ impl<T: JSTraceable + MallocSizeOf> MallocSizeOf for RootedTraceableBox<T> {
|
|||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
// Briefly resurrect the real Box value so we can rely on the existing calculations.
|
||||
// Then immediately forget about it again to avoid dropping the box.
|
||||
let inner = unsafe { Box::from_raw(self.ptr) };
|
||||
let inner = unsafe { Box::from_raw(self.0.ptr()) };
|
||||
let size = inner.size_of(ops);
|
||||
mem::forget(inner);
|
||||
size
|
||||
|
@ -797,22 +529,13 @@ impl<T: JSTraceable + Default> Default for RootedTraceableBox<T> {
|
|||
impl<T: JSTraceable> Deref for RootedTraceableBox<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { &*self.ptr }
|
||||
self.0.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JSTraceable> DerefMut for RootedTraceableBox<T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
unsafe { &mut *self.ptr }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: JSTraceable + 'static> Drop for RootedTraceableBox<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
RootedTraceableSet::remove(self.ptr);
|
||||
let _ = Box::from_raw(self.ptr);
|
||||
}
|
||||
self.0.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -847,7 +570,7 @@ impl<'a, T: 'static + JSTraceable> RootedVec<'a, T> {
|
|||
unsafe {
|
||||
RootedTraceableSet::add(root);
|
||||
}
|
||||
RootedVec { root: root }
|
||||
RootedVec { root }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -862,7 +585,7 @@ impl<'a, T: 'static + JSTraceable + DomObject> RootedVec<'a, Dom<T>> {
|
|||
RootedTraceableSet::add(root);
|
||||
}
|
||||
root.v.extend(iter.map(|item| Dom::from_ref(&*item)));
|
||||
RootedVec { root: root }
|
||||
RootedVec { root }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -887,12 +610,3 @@ impl<'a, T: JSTraceable> DerefMut for RootedVec<'a, T> {
|
|||
&mut self.root.v
|
||||
}
|
||||
}
|
||||
|
||||
/// SM Callback that traces the rooted traceables
|
||||
pub unsafe fn trace_traceables(tracer: *mut JSTracer) {
|
||||
trace!("tracing stack-rooted traceables");
|
||||
ROOTED_TRACEABLES.with(|ref traceables| {
|
||||
let traceables = traceables.borrow();
|
||||
traceables.trace(tracer);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,13 +17,12 @@ use js::typedarray::ArrayBufferView;
|
|||
use servo_rand::{RngCore, ServoRng};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
unsafe_no_jsmanaged_fields!(ServoRng);
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto
|
||||
#[dom_struct]
|
||||
pub struct Crypto {
|
||||
reflector_: Reflector,
|
||||
#[ignore_malloc_size_of = "Defined in rand"]
|
||||
#[no_trace]
|
||||
rng: DomRefCell<ServoRng>,
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ use style::stylesheets::{
|
|||
|
||||
unsafe_no_jsmanaged_fields!(RulesSource);
|
||||
|
||||
unsafe_no_jsmanaged_fields!(CssRules);
|
||||
|
||||
impl From<RulesMutateError> for Error {
|
||||
fn from(other: RulesMutateError) -> Self {
|
||||
match other {
|
||||
|
|
|
@ -269,6 +269,7 @@ pub struct Document {
|
|||
#[no_trace]
|
||||
style_shared_lock: StyleSharedRwLock,
|
||||
/// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed.
|
||||
#[custom_trace]
|
||||
stylesheets: DomRefCell<DocumentStylesheetSet<StyleSheetInDocument>>,
|
||||
stylesheet_list: MutNullableDom<StyleSheetList>,
|
||||
ready_state: Cell<DocumentReadyState>,
|
||||
|
|
|
@ -19,16 +19,15 @@ use js::rust::HandleObject;
|
|||
use keyboard_types::{Key, Modifiers};
|
||||
use std::cell::Cell;
|
||||
|
||||
unsafe_no_jsmanaged_fields!(Key);
|
||||
unsafe_no_jsmanaged_fields!(Modifiers);
|
||||
|
||||
#[dom_struct]
|
||||
pub struct KeyboardEvent {
|
||||
uievent: UIEvent,
|
||||
key: DomRefCell<DOMString>,
|
||||
#[no_trace]
|
||||
typed_key: DomRefCell<Key>,
|
||||
code: DomRefCell<DOMString>,
|
||||
location: Cell<u32>,
|
||||
#[no_trace]
|
||||
modifiers: Cell<Modifiers>,
|
||||
repeat: Cell<bool>,
|
||||
is_composing: Cell<bool>,
|
||||
|
|
|
@ -312,22 +312,6 @@ macro_rules! unsafe_no_jsmanaged_fields(
|
|||
);
|
||||
);
|
||||
|
||||
macro_rules! jsmanaged_array(
|
||||
($count:expr) => (
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl<T> $crate::dom::bindings::trace::JSTraceable for [T; $count]
|
||||
where T: $crate::dom::bindings::trace::JSTraceable
|
||||
{
|
||||
#[inline]
|
||||
unsafe fn trace(&self, tracer: *mut ::js::jsapi::JSTracer) {
|
||||
for v in self.iter() {
|
||||
v.trace(tracer);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
/// These are used to generate a event handler which has no special case.
|
||||
macro_rules! define_event_handler(
|
||||
($handler: ty, $event_type: ident, $getter: ident, $setter: ident, $setter_fn: ident) => (
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
|
||||
use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::bindings::trace::{CustomTraceable, JSTraceable};
|
||||
use crate::dom::characterdata::CharacterData;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::documentfragment::DocumentFragment;
|
||||
|
@ -101,7 +101,7 @@ impl Tokenizer {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl JSTraceable for HtmlTokenizer<TreeBuilder<Dom<Node>, Sink>> {
|
||||
unsafe impl CustomTraceable for HtmlTokenizer<TreeBuilder<Dom<Node>, Sink>> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
struct Tracer(*mut JSTracer);
|
||||
let tracer = Tracer(trc);
|
||||
|
|
|
@ -1381,6 +1381,7 @@ fn create_element_for_token(
|
|||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
struct NetworkDecoder {
|
||||
#[ignore_malloc_size_of = "Defined in tendril"]
|
||||
#[custom_trace]
|
||||
decoder: LossyDecoder<NetworkSink>,
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::bindings::trace::{CustomTraceable, JSTraceable};
|
||||
use crate::dom::document::{determine_policy_for_token, Document};
|
||||
use crate::dom::htmlimageelement::{image_fetch_request, FromPictureOrSrcSet};
|
||||
use crate::dom::htmlscriptelement::script_fetch_request;
|
||||
|
@ -42,7 +42,7 @@ pub struct Tokenizer {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl JSTraceable for HtmlTokenizer<PrefetchSink> {
|
||||
unsafe impl CustomTraceable for HtmlTokenizer<PrefetchSink> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
self.sink.trace(trc)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#![allow(unrooted_must_root)]
|
||||
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::bindings::trace::{CustomTraceable, JSTraceable};
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::htmlscriptelement::HTMLScriptElement;
|
||||
use crate::dom::node::Node;
|
||||
|
@ -59,7 +59,7 @@ impl Tokenizer {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl JSTraceable for XmlTokenizer<XmlTreeBuilder<Dom<Node>, Sink>> {
|
||||
unsafe impl CustomTraceable for XmlTokenizer<XmlTreeBuilder<Dom<Node>, Sink>> {
|
||||
unsafe fn trace(&self, trc: *mut JSTracer) {
|
||||
struct Tracer(*mut JSTracer);
|
||||
let tracer = Tracer(trc);
|
||||
|
|
|
@ -42,6 +42,7 @@ pub struct ShadowRoot {
|
|||
document: Dom<Document>,
|
||||
host: MutNullableDom<Element>,
|
||||
/// List of author styles associated with nodes in this shadow tree.
|
||||
#[custom_trace]
|
||||
author_styles: DomRefCell<AuthorStyles<StyleSheetInDocument>>,
|
||||
stylesheet_list: MutNullableDom<StyleSheetList>,
|
||||
window: Dom<Window>,
|
||||
|
|
|
@ -43,8 +43,6 @@ enum WebGLTextureOwner {
|
|||
const MAX_LEVEL_COUNT: usize = 31;
|
||||
const MAX_FACE_COUNT: usize = 6;
|
||||
|
||||
jsmanaged_array!(MAX_LEVEL_COUNT * MAX_FACE_COUNT);
|
||||
|
||||
#[dom_struct]
|
||||
pub struct WebGLTexture {
|
||||
webgl_object: WebGLObject,
|
||||
|
|
|
@ -17,6 +17,7 @@ pub struct XRHand {
|
|||
#[ignore_malloc_size_of = "defined in webxr"]
|
||||
source: Dom<XRInputSource>,
|
||||
#[ignore_malloc_size_of = "partially defind in webxr"]
|
||||
#[custom_trace]
|
||||
spaces: Hand<Dom<XRJointSpace>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ pub struct ModuleTree {
|
|||
// By default all maps in web specs are ordered maps
|
||||
// (https://infra.spec.whatwg.org/#ordered-map), however we can usually get away with using
|
||||
// stdlib maps and sets because we rarely iterate over them.
|
||||
#[custom_trace]
|
||||
parent_identities: DomRefCell<IndexSet<ModuleIdentity>>,
|
||||
#[no_trace]
|
||||
descendant_urls: DomRefCell<IndexSet<ServoUrl>>,
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
|||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::bindings::root::trace_roots;
|
||||
use crate::dom::bindings::settings_stack;
|
||||
use crate::dom::bindings::trace::{trace_traceables, JSTraceable};
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::bindings::utils::DOM_CALLBACKS;
|
||||
use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
|
@ -825,7 +825,6 @@ unsafe extern "C" fn trace_rust_roots(tr: *mut JSTracer, _data: *mut os::raw::c_
|
|||
}
|
||||
debug!("starting custom root handler");
|
||||
trace_thread(tr);
|
||||
trace_traceables(tr);
|
||||
trace_roots(tr);
|
||||
trace_refcounted_objects(tr);
|
||||
settings_stack::trace(tr);
|
||||
|
|
|
@ -521,8 +521,6 @@ impl<'a> Iterator for DocumentsIter<'a> {
|
|||
pub struct IncompleteParserContexts(RefCell<Vec<(PipelineId, ParserContext)>>);
|
||||
|
||||
unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>);
|
||||
unsafe_no_jsmanaged_fields!(dyn BackgroundHangMonitorRegister);
|
||||
unsafe_no_jsmanaged_fields!(dyn BackgroundHangMonitor);
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
// ScriptThread instances are rooted on creation, so this is okay
|
||||
|
@ -552,8 +550,10 @@ pub struct ScriptThread {
|
|||
task_queue: TaskQueue<MainThreadScriptMsg>,
|
||||
|
||||
/// A handle to register associated layout threads for hang-monitoring.
|
||||
#[no_trace]
|
||||
background_hang_monitor_register: Box<dyn BackgroundHangMonitorRegister>,
|
||||
/// The dedicated means of communication with the background-hang-monitor for this script-thread.
|
||||
#[no_trace]
|
||||
background_hang_monitor: Box<dyn BackgroundHangMonitor>,
|
||||
/// A flag set to `true` by the BHM on exit, and checked from within the interrupt handler.
|
||||
closing: Arc<AtomicBool>,
|
||||
|
|
|
@ -98,9 +98,7 @@ fn get_must_not_have_traceable(sym: &Symbols, attrs: &[Attribute]) -> Option<usi
|
|||
|
||||
fn is_jstraceable<'tcx>(cx: &LateContext<'tcx>, ty: ty::Ty<'tcx>) -> bool {
|
||||
// TODO(sagudev): get_trait_def_id is expensive, use lazy and cache it for whole pass
|
||||
if let Some(trait_id) =
|
||||
get_trait_def_id(cx, &["script", "dom", "bindings", "trace", "JSTraceable"])
|
||||
{
|
||||
if let Some(trait_id) = get_trait_def_id(cx, &["mozjs", "gc", "Traceable"]) {
|
||||
return implements_trait(cx, ty, trait_id, &[]);
|
||||
}
|
||||
// when running tests
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue