Use trait objects in RootedTraceableSet

This commit is contained in:
Anthony Ramine 2016-12-09 08:37:39 -10:00
parent 62fb2074e1
commit f7d53b7bc1

View file

@ -59,7 +59,6 @@ use js::glue::{CallObjectTracer, CallUnbarrieredObjectTracer, CallValueTracer};
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
use js::jsval::JSVal; use js::jsval::JSVal;
use js::rust::Runtime; use js::rust::Runtime;
use libc;
use msg::constellation_msg::{FrameId, FrameType, PipelineId}; use msg::constellation_msg::{FrameId, FrameType, PipelineId};
use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
use net_traits::filemanager_thread::RelativePos; use net_traits::filemanager_thread::RelativePos;
@ -568,15 +567,9 @@ unsafe impl JSTraceable for RwLock<MediaList> {
} }
} }
/// Homemade trait object for JSTraceable things
struct TraceableInfo {
pub ptr: *const libc::c_void,
pub trace: unsafe fn(obj: *const libc::c_void, tracer: *mut JSTracer),
}
/// Holds a set of JSTraceables that need to be rooted /// Holds a set of JSTraceables that need to be rooted
pub struct RootedTraceableSet { pub struct RootedTraceableSet {
set: Vec<TraceableInfo>, set: Vec<*const JSTraceable>,
} }
thread_local!( thread_local!(
@ -592,12 +585,12 @@ impl RootedTraceableSet {
} }
} }
unsafe fn remove<T: JSTraceable>(traceable: &T) { unsafe fn remove(traceable: *const JSTraceable) {
ROOTED_TRACEABLES.with(|ref traceables| { ROOTED_TRACEABLES.with(|ref traceables| {
let mut traceables = traceables.borrow_mut(); let mut traceables = traceables.borrow_mut();
let idx = let idx =
match traceables.set.iter() match traceables.set.iter()
.rposition(|x| x.ptr == traceable as *const T as *const _) { .rposition(|x| *x == traceable) {
Some(idx) => idx, Some(idx) => idx,
None => unreachable!(), None => unreachable!(),
}; };
@ -605,25 +598,15 @@ impl RootedTraceableSet {
}); });
} }
unsafe fn add<T: JSTraceable>(traceable: &T) { unsafe fn add(traceable: *const JSTraceable) {
ROOTED_TRACEABLES.with(|ref traceables| { ROOTED_TRACEABLES.with(|ref traceables| {
unsafe fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) { traceables.borrow_mut().set.push(traceable);
let obj: &T = &*(obj as *const T);
obj.trace(tracer);
}
let mut traceables = traceables.borrow_mut();
let info = TraceableInfo {
ptr: traceable as *const T as *const libc::c_void,
trace: trace::<T>,
};
traceables.set.push(info);
}) })
} }
unsafe fn trace(&self, tracer: *mut JSTracer) { unsafe fn trace(&self, tracer: *mut JSTracer) {
for info in &self.set { for traceable in &self.set {
(info.trace)(info.ptr, tracer); (**traceable).trace(tracer);
} }
} }
} }
@ -635,11 +618,11 @@ impl RootedTraceableSet {
/// If you have an arbitrary number of DomObjects to root, use rooted_vec!. /// If you have an arbitrary number of DomObjects to root, use rooted_vec!.
/// If you know what you're doing, use this. /// If you know what you're doing, use this.
#[derive(JSTraceable)] #[derive(JSTraceable)]
pub struct RootedTraceable<'a, T: 'a + JSTraceable> { pub struct RootedTraceable<'a, T: 'static + JSTraceable> {
ptr: &'a T, ptr: &'a T,
} }
impl<'a, T: JSTraceable> RootedTraceable<'a, T> { impl<'a, T: JSTraceable + 'static> RootedTraceable<'a, T> {
/// Root a JSTraceable thing for the life of this RootedTraceable /// Root a JSTraceable thing for the life of this RootedTraceable
pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> { pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> {
unsafe { unsafe {
@ -651,7 +634,7 @@ impl<'a, T: JSTraceable> RootedTraceable<'a, T> {
} }
} }
impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> { impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
RootedTraceableSet::remove(self.ptr); RootedTraceableSet::remove(self.ptr);
@ -681,11 +664,11 @@ impl<T: JSTraceable> RootableVec<T> {
/// A vector of items that are rooted for the lifetime 'a. /// A vector of items that are rooted for the lifetime 'a.
#[allow_unrooted_interior] #[allow_unrooted_interior]
pub struct RootedVec<'a, T: 'a + JSTraceable> { pub struct RootedVec<'a, T: 'static + JSTraceable> {
root: &'a mut RootableVec<T>, root: &'a mut RootableVec<T>,
} }
impl<'a, T: JSTraceable + DomObject> RootedVec<'a, JS<T>> { impl<'a, T: 'static + JSTraceable + DomObject> RootedVec<'a, JS<T>> {
/// Create a vector of items of type T that is rooted for /// Create a vector of items of type T that is rooted for
/// the lifetime of this struct /// the lifetime of this struct
pub fn new<I: Iterator<Item = Root<T>>>(root: &'a mut RootableVec<JS<T>>, iter: I) pub fn new<I: Iterator<Item = Root<T>>>(root: &'a mut RootableVec<JS<T>>, iter: I)
@ -700,7 +683,7 @@ impl<'a, T: JSTraceable + DomObject> RootedVec<'a, JS<T>> {
} }
} }
impl<'a, T: JSTraceable> Drop for RootedVec<'a, T> { impl<'a, T: JSTraceable + 'static> Drop for RootedVec<'a, T> {
fn drop(&mut self) { fn drop(&mut self) {
self.clear(); self.clear();
unsafe { unsafe {