diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 357a3282f9d5..62848346fd9c 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -50,6 +50,7 @@ //! `Option>` easy use dom::bindings::trace::JSTraceable; +use dom::bindings::trace::RootedVec; use dom::bindings::utils::{Reflector, Reflectable}; use dom::node::Node; use js::jsapi::JSObject; @@ -57,11 +58,11 @@ use js::jsval::JSVal; use layout_interface::TrustedNodeAddress; use script_task::STACK_ROOTS; -use util::smallvec::{SmallVec, SmallVec32}; - use core::nonzero::NonZero; +use libc; use std::cell::{Cell, UnsafeCell}; use std::default::Default; +use std::intrinsics::return_address; use std::marker::PhantomData; use std::mem; use std::ops::Deref; @@ -610,7 +611,7 @@ impl, U: Reflectable> TemporaryPushable for Vec> { /// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*] /// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting). pub struct RootCollection { - roots: UnsafeCell>, + roots: UnsafeCell>, } /// A pointer to a RootCollection, for use in global variables. @@ -621,8 +622,12 @@ impl Copy for RootCollectionPtr {} impl RootCollection { /// Create an empty collection of roots pub fn new() -> RootCollection { + let addr = unsafe { + return_address() as *const libc::c_void + }; + RootCollection { - roots: UnsafeCell::new(SmallVec32::new()), + roots: UnsafeCell::new(RootedVec::new_with_destination_address(addr)), } } @@ -632,7 +637,6 @@ impl RootCollection { let roots = self.roots.get(); (*roots).push(untracked_js_ptr); debug!(" rooting {:?}", untracked_js_ptr); - assert!(!(*roots).spilled()); } } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index bfdb1e83a6c5..f77b42648d9c 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -389,12 +389,21 @@ impl RootedVec { /// Create a vector of items of type T that is rooted for /// the lifetime of this struct pub fn new() -> RootedVec { + let addr = unsafe { + return_address() as *const libc::c_void + }; + + RootedVec::new_with_destination_address(addr) + } + + /// Create a vector of items of type T. This constructor is specific + /// for RootCollection. + pub fn new_with_destination_address(addr: *const libc::c_void) -> RootedVec { unsafe { - RootedCollectionSet::add::(&*(return_address() as *const _)); + RootedCollectionSet::add::(&*(addr as *const _)); } RootedVec:: { v: vec!() } } - } #[unsafe_destructor]