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::jsval::JSVal;
use js::rust::Runtime;
use libc;
use msg::constellation_msg::{FrameId, FrameType, PipelineId};
use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
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
pub struct RootedTraceableSet {
set: Vec<TraceableInfo>,
set: Vec<*const JSTraceable>,
}
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| {
let mut traceables = traceables.borrow_mut();
let idx =
match traceables.set.iter()
.rposition(|x| x.ptr == traceable as *const T as *const _) {
.rposition(|x| *x == traceable) {
Some(idx) => idx,
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| {
unsafe fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) {
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);
traceables.borrow_mut().set.push(traceable);
})
}
unsafe fn trace(&self, tracer: *mut JSTracer) {
for info in &self.set {
(info.trace)(info.ptr, tracer);
for traceable in &self.set {
(**traceable).trace(tracer);
}
}
}
@ -635,11 +618,11 @@ impl RootedTraceableSet {
/// If you have an arbitrary number of DomObjects to root, use rooted_vec!.
/// If you know what you're doing, use this.
#[derive(JSTraceable)]
pub struct RootedTraceable<'a, T: 'a + JSTraceable> {
pub struct RootedTraceable<'a, T: 'static + JSTraceable> {
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
pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> {
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) {
unsafe {
RootedTraceableSet::remove(self.ptr);
@ -681,11 +664,11 @@ impl<T: JSTraceable> RootableVec<T> {
/// A vector of items that are rooted for the lifetime 'a.
#[allow_unrooted_interior]
pub struct RootedVec<'a, T: 'a + JSTraceable> {
pub struct RootedVec<'a, T: 'static + JSTraceable> {
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
/// the lifetime of this struct
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) {
self.clear();
unsafe {