Remove Traceable/Untraceable entirely

This commit is contained in:
Manish Goregaokar 2014-09-29 07:06:24 +05:30
parent b7c3a1cd5d
commit 427b3b7733
4 changed files with 13 additions and 77 deletions

View file

@ -15,9 +15,9 @@ The outline is:
1. SpiderMonkey's GC calls `JSClass.trace` defined in `FooBinding` when marking phase. This JSClass is basis of each wrapper JSObject.
2. `JSClass.trace` calls `Foo::trace()` (an implementation of `JSTraceable`).
This is typically derived via a #[jstraceable] annotation
3. For all fields (except those wrapped in `Untraceable`), `Foo::trace()`
3. For all fields, `Foo::trace()`
calls `trace()` on the field. For example, for fields of type `JS<T>`, `JS<T>::trace()` calls
`trace_reflector()`.
`trace_reflector()`. Non-JS-managed types have an empty inline `trace()` method, achieved via `untraceable!` or similar.
4. `trace_reflector()` fetches the reflector that is reachable from a Rust object, and notifies it to the GC with using JSTracer.
5. This operation continues to the end of the graph.
6. Finally, GC gets whether Rust object lives or not from JSObjects which is hold by Rust object.

View file

@ -13,7 +13,7 @@
//! through `ProxyTraps.trace` otherwise.)
//! 2. `_trace` calls `Foo::trace()` (an implementation of `JSTraceable`).
//! This is typically derived via a #[jstraceable] annotation
//! 3. For all fields (except those wrapped in `Untraceable`), `Foo::trace()`
//! 3. For all fields, `Foo::trace()`
//! calls `trace()` on the field.
//! For example, for fields of type `JS<T>`, `JS<T>::trace()` calls
//! `trace_reflector()`.
@ -52,6 +52,7 @@ use std::io::timer::Timer;
use servo_msg::compositor_msg::ScriptListener;
use servo_msg::constellation_msg::ConstellationChan;
use layout_interface::{LayoutRPC, LayoutChan};
use dom::bindings::utils::WindowProxyHandler;
impl<T: Reflectable> JSTraceable for JS<T> {
fn trace(&self, trc: *mut JSTracer) {
@ -100,65 +101,6 @@ pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject
}
}
/// Encapsulates a type that cannot easily have `Encodable` derived automagically,
/// but also does not need to be made known to the SpiderMonkey garbage collector.
///
/// Use only with types that are not associated with a JS reflector and do not contain
/// fields of types associated with JS reflectors.
///
/// This should really only be used for types that are from other crates,
/// so we can't implement `Encodable`. See more details: mozilla#2662.
pub struct Untraceable<T> {
inner: T,
}
impl<T> Untraceable<T> {
pub fn new(val: T) -> Untraceable<T> {
Untraceable {
inner: val
}
}
}
impl<T> Deref<T> for Untraceable<T> {
fn deref<'a>(&'a self) -> &'a T {
&self.inner
}
}
impl<T> DerefMut<T> for Untraceable<T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
&mut self.inner
}
}
/// Encapsulates a type that can be traced but is boxed in a type we don't
/// control (such as `RefCell`).
///
/// Wrap a field in Traceable and implement the `Encodable` trait
/// for that new concrete type to achieve magic compiler-derived trace hooks.
///
/// We always prefer this, in case the contained type ever changes to something that should be traced.
/// See more details: mozilla#2662.
#[deriving(PartialEq, Clone)]
pub struct Traceable<T> {
inner: T
}
impl<T> Traceable<T> {
pub fn new(val: T) -> Traceable<T> {
Traceable {
inner: val
}
}
}
impl<T> Deref<T> for Traceable<T> {
fn deref<'a>(&'a self) -> &'a T {
&self.inner
}
}
impl<T: JSTraceable> JSTraceable for RefCell<T> {
fn trace(&self, trc: *mut JSTracer) {
self.borrow().trace(trc)
@ -177,13 +119,6 @@ impl<T: JSTraceable> JSTraceable for Box<T> {
}
}
impl<T: JSTraceable+Copy> JSTraceable for Traceable<Cell<T>> {
fn trace(&self, trc: *mut JSTracer) {
self.deref().get().trace(trc)
}
}
impl<T: JSTraceable+Copy> JSTraceable for Cell<T> {
fn trace(&self, trc: *mut JSTracer) {
self.get().trace(trc)
@ -243,7 +178,6 @@ impl<A: JSTraceable, B: JSTraceable> JSTraceable for (A, B) {
untraceable!(bool, f32, f64, String, Url)
untraceable!(uint, u8, u16, u32, u64)
untraceable!(int, i8, i16, i32, i64)
untraceable!(Untraceable<T>)
untraceable!(Sender<T>)
untraceable!(Receiver<T>)
untraceable!(ImageCacheTask, ScriptControlChan)
@ -257,6 +191,7 @@ untraceable!(Cx)
untraceable!(ResponseHeaderCollection, RequestHeaderCollection, Method)
untraceable!(ConstellationChan)
untraceable!(LayoutChan)
untraceable!(WindowProxyHandler)
impl<'a> JSTraceable for &'a str {
#[inline]

View file

@ -49,10 +49,12 @@ use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT};
use js::JSFUN_CONSTRUCTOR;
use js;
pub struct WindowProxyHandler(pub *const libc::c_void);
#[allow(raw_pointer_deriving)]
#[jstraceable]
pub struct GlobalStaticData {
pub windowproxy_handler: *const libc::c_void,
pub windowproxy_handler: WindowProxyHandler,
}
pub fn GlobalStaticData() -> GlobalStaticData {

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::utils::Reflectable;
use dom::bindings::utils::{Reflectable, WindowProxyHandler};
use dom::document::Document;
use dom::window::Window;
@ -11,7 +11,6 @@ use js::jsapi::JSObject;
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
use js::rust::with_compartment;
use libc::c_void;
use std::ptr;
#[allow(raw_pointer_deriving)]
@ -52,7 +51,7 @@ impl BrowserContext {
let page = win.deref().page();
let js_info = page.js_info();
let handler = js_info.as_ref().unwrap().dom_static.windowproxy_handler;
let WindowProxyHandler(handler) = js_info.as_ref().unwrap().dom_static.windowproxy_handler;
assert!(handler.is_not_null());
let parent = win.deref().reflector().get_jsobject();
@ -113,8 +112,8 @@ static proxy_handler: ProxyTraps = ProxyTraps {
trace: None
};
pub fn new_window_proxy_handler() -> *const c_void {
pub fn new_window_proxy_handler() -> WindowProxyHandler {
unsafe {
CreateWrapperProxyHandler(&proxy_handler)
WindowProxyHandler(CreateWrapperProxyHandler(&proxy_handler))
}
}