Add trace hooks for Window and Document, and remove explicit rooting for the root DOM node. Fixes #901.

This commit is contained in:
Josh Matthews 2013-09-11 12:18:23 -07:00
parent 9640324721
commit 636c30affe
7 changed files with 66 additions and 39 deletions

View file

@ -143,6 +143,7 @@ DOMInterfaces = {
'Document': { 'Document': {
'nativeType': 'AbstractDocument', 'nativeType': 'AbstractDocument',
'pointerType': '', 'pointerType': '',
'customTrace': 'trace'
}, },
'DOMParser': { 'DOMParser': {
@ -228,6 +229,7 @@ DOMInterfaces = {
'HTMLDocument': { 'HTMLDocument': {
'nativeType': 'AbstractDocument', 'nativeType': 'AbstractDocument',
'pointerType': '', 'pointerType': '',
'customTrace': 'trace'
}, },
'HTMLFormElement': { 'HTMLFormElement': {
@ -433,7 +435,8 @@ DOMInterfaces = {
}], }],
'Window': { 'Window': {
'createGlobal': True 'createGlobal': True,
'customTrace': 'trace'
}, },
'WindowProxy': { 'WindowProxy': {

View file

@ -2221,13 +2221,13 @@ static Class_name: [u8, ..%i] = %s;
static Class: DOMJSClass = DOMJSClass { static Class: DOMJSClass = DOMJSClass {
base: JSClass { name: &Class_name as *u8 as *libc::c_char, base: JSClass { name: &Class_name as *u8 as *libc::c_char,
flags: JSCLASS_IS_DOMJSCLASS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s), flags: JSCLASS_IS_DOMJSCLASS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s),
addProperty: %s, /* addProperty */ addProperty: Some(%s), /* addProperty */
delProperty: crust::JS_PropertyStub, /* delProperty */ delProperty: Some(crust::JS_PropertyStub), /* delProperty */
getProperty: crust::JS_PropertyStub, /* getProperty */ getProperty: Some(crust::JS_PropertyStub), /* getProperty */
setProperty: crust::JS_StrictPropertyStub, /* setProperty */ setProperty: Some(crust::JS_StrictPropertyStub), /* setProperty */
enumerate: crust::JS_EnumerateStub, enumerate: Some(crust::JS_EnumerateStub),
resolve: crust::JS_ResolveStub, resolve: Some(crust::JS_ResolveStub),
convert: crust::JS_ConvertStub, convert: Some(crust::JS_ConvertStub),
finalize: Some(%s), /* finalize */ finalize: Some(%s), /* finalize */
checkAccess: None, /* checkAccess */ checkAccess: None, /* checkAccess */
call: None, /* call */ call: None, /* call */
@ -2269,13 +2269,13 @@ static PrototypeClassName__: [u8, ..%s] = %s;
static PrototypeClass: JSClass = JSClass { static PrototypeClass: JSClass = JSClass {
name: &PrototypeClassName__ as *u8 as *libc::c_char, name: &PrototypeClassName__ as *u8 as *libc::c_char,
flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT, //JSCLASS_HAS_RESERVED_SLOTS(1) flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT, //JSCLASS_HAS_RESERVED_SLOTS(1)
addProperty: crust::JS_PropertyStub, /* addProperty */ addProperty: Some(crust::JS_PropertyStub), /* addProperty */
delProperty: crust::JS_PropertyStub, /* delProperty */ delProperty: Some(crust::JS_PropertyStub), /* delProperty */
getProperty: crust::JS_PropertyStub, /* getProperty */ getProperty: Some(crust::JS_PropertyStub), /* getProperty */
setProperty: crust::JS_StrictPropertyStub, /* setProperty */ setProperty: Some(crust::JS_StrictPropertyStub), /* setProperty */
enumerate: crust::JS_EnumerateStub, enumerate: Some(crust::JS_EnumerateStub),
resolve: crust::JS_ResolveStub, resolve: Some(crust::JS_ResolveStub),
convert: crust::JS_ConvertStub, convert: Some(crust::JS_ConvertStub),
finalize: None, /* finalize */ finalize: None, /* finalize */
checkAccess: None, /* checkAccess */ checkAccess: None, /* checkAccess */
call: None, /* call */ call: None, /* call */

View file

@ -130,7 +130,7 @@ impl Traceable for Node<ScriptView> {
} }
} }
} }
error!("tracing %p?:", self.wrapper.get_wrapper()); debug!("tracing %p?:", self.wrapper.get_wrapper());
trace_node(tracer, self.parent_node, "parent"); trace_node(tracer, self.parent_node, "parent");
trace_node(tracer, self.first_child, "first child"); trace_node(tracer, self.first_child, "first child");
trace_node(tracer, self.last_child, "last child"); trace_node(tracer, self.last_child, "last child");

View file

@ -5,6 +5,7 @@
use dom::bindings::codegen::DocumentBinding; use dom::bindings::codegen::DocumentBinding;
use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, null_string, str}; use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, null_string, str};
use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box, DerivedWrapper}; use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box, DerivedWrapper};
use dom::bindings::utils::Traceable;
use dom::element::{Element}; use dom::element::{Element};
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId}; use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::event::Event; use dom::event::Event;
@ -18,13 +19,15 @@ use dom::window::Window;
use dom::windowproxy::WindowProxy; use dom::windowproxy::WindowProxy;
use dom::htmltitleelement::HTMLTitleElement; use dom::htmltitleelement::HTMLTitleElement;
use html::hubbub_html_parser::build_element_from_tag; use html::hubbub_html_parser::build_element_from_tag;
use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSObject, JSContext, JSVal}; use js::jsapi::{JSObject, JSContext, JSVal};
use js::jsapi::{JSTRACE_OBJECT, JSTracer, JS_CallTracer};
use js::glue::RUST_OBJECT_TO_JSVAL; use js::glue::RUST_OBJECT_TO_JSVAL;
use servo_util::tree::TreeNodeRef; use servo_util::tree::TreeNodeRef;
use std::cast; use std::cast;
use std::ptr; use std::ptr;
use std::str::eq_slice; use std::str::eq_slice;
use std::libc;
pub trait WrappableDocument { pub trait WrappableDocument {
fn init_wrapper(@mut self, cx: *JSContext); fn init_wrapper(@mut self, cx: *JSContext);
@ -89,14 +92,6 @@ pub struct Document {
impl Document { impl Document {
#[fixed_stack_segment] #[fixed_stack_segment]
pub fn new(root: AbstractNode<ScriptView>, window: Option<@mut Window>, doctype: DocumentType) -> Document { pub fn new(root: AbstractNode<ScriptView>, window: Option<@mut Window>, doctype: DocumentType) -> Document {
let compartment = unsafe {(*window.get_ref().page).js_info.get_ref().js_compartment };
do root.with_base |base| {
assert!(base.wrapper.get_wrapper().is_not_null());
let rootable = base.wrapper.get_rootable();
unsafe {
JS_AddObjectRoot(compartment.cx.ptr, rootable);
}
}
Document { Document {
root: root, root: root,
wrapper: WrapperCache::new(), wrapper: WrapperCache::new(),
@ -460,17 +455,23 @@ impl Document {
window.content_changed() window.content_changed()
} }
} }
}
impl Traceable for Document {
#[fixed_stack_segment] #[fixed_stack_segment]
pub fn teardown(&self) { fn trace(&self, tracer: *mut JSTracer) {
unsafe { unsafe {
let compartment = (*self.window.get_ref().page).js_info.get_ref().js_compartment; (*tracer).debugPrinter = ptr::null();
do self.root.with_base |node| { (*tracer).debugPrintIndex = -1;
assert!(node.wrapper.get_wrapper().is_not_null()); do "root".to_c_str().with_ref |name| {
let rootable = node.wrapper.get_rootable(); (*tracer).debugPrintArg = name as *libc::c_void;
JS_RemoveObjectRoot(compartment.cx.ptr, rootable); debug!("tracing root node");
do self.root.with_base |node| {
JS_CallTracer(tracer as *JSTracer,
node.wrapper.wrapper,
JSTRACE_OBJECT as u32);
}
} }
} }
} }
} }

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::WindowBinding; use dom::bindings::codegen::WindowBinding;
use dom::bindings::utils::{WrapperCache, DOMString, null_string}; use dom::bindings::utils::{WrapperCache, DOMString, null_string, Traceable};
use dom::bindings::utils::{CacheableWrapper, BindingObject}; use dom::bindings::utils::{CacheableWrapper, BindingObject};
use dom::document::AbstractDocument; use dom::document::AbstractDocument;
use dom::node::{AbstractNode, ScriptView}; use dom::node::{AbstractNode, ScriptView};
@ -14,8 +14,8 @@ use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
use servo_msg::compositor_msg::ScriptListener; use servo_msg::compositor_msg::ScriptListener;
use js::glue::*; use js::glue::*;
use js::jsapi::{JSObject, JSContext, JS_DefineProperty}; use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JS_CallTracer};
use js::jsapi::{JSPropertyOp, JSStrictPropertyOp}; use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JSTracer, JSTRACE_OBJECT};
use js::{JSVAL_NULL, JSPROP_ENUMERATE}; use js::{JSVAL_NULL, JSPROP_ENUMERATE};
use std::cast; use std::cast;
@ -25,6 +25,7 @@ use std::comm::SharedChan;
use std::io; use std::io;
use std::ptr; use std::ptr;
use std::int; use std::int;
use std::libc;
use std::rt::rtio::RtioTimer; use std::rt::rtio::RtioTimer;
use std::rt::io::timer::Timer; use std::rt::io::timer::Timer;
use js::jsapi::JSVal; use js::jsapi::JSVal;
@ -214,3 +215,28 @@ impl Window {
} }
} }
impl Traceable for Window {
#[fixed_stack_segment]
fn trace(&self, tracer: *mut JSTracer) {
debug!("tracing window");
unsafe {
match (*self.page).frame {
Some(frame) => {
do frame.document.with_base |doc| {
(*tracer).debugPrinter = ptr::null();
(*tracer).debugPrintIndex = -1;
do "document".to_c_str().with_ref |name| {
(*tracer).debugPrintArg = name as *libc::c_void;
debug!("tracing document");
JS_CallTracer(tracer as *JSTracer,
doc.wrapper.wrapper,
JSTRACE_OBJECT as u32);
}
}
}
None => ()
}
}
}
}

View file

@ -555,9 +555,6 @@ impl ScriptTask {
fn handle_exit_msg(&mut self) { fn handle_exit_msg(&mut self) {
for page in self.page_tree.iter() { for page in self.page_tree.iter() {
page.join_layout(); page.join_layout();
do page.frame.unwrap().document.with_mut_base |doc| {
doc.teardown();
}
page.layout_chan.send(layout_interface::ExitMsg); page.layout_chan.send(layout_interface::ExitMsg);
} }
self.compositor.close(); self.compositor.close();

@ -1 +1 @@
Subproject commit a9bc3b5cf968e279cfb082e58207c60e4f4a1a9b Subproject commit 5b83f5f77a6215864738a5636a9bc9db2a097070