servo: Merge #8056 - Fix the implementation of JSTraceable for RefCell (from eefriedman:trace-refcell); r=jdm
authorEli Friedman <eli.friedman@gmail.com>
Tue, 03 Nov 2015 06:38:10 +0500
changeset 337472 5b5019c169c4b31a992574b880f719b4ecdb8c5f
parent 337471 e28046ab2bd9a05bc45c74de349098127a909230
child 337473 5e60b0fc7b31dcb24f50a34c3a56c7bcf0ee0d72
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #8056 - Fix the implementation of JSTraceable for RefCell (from eefriedman:trace-refcell); r=jdm The existing implementation could panic; make sure that doesn't happen by requiring that the contents of a RefCell are trivially traceable (i.e. the value don't contain any traceable objects). I'm not sure whether the TriviallyJSTraceable trait is actually worthwhile; maybe we should just never use RefCell in the DOM. Source-Repo: https://github.com/servo/servo Source-Revision: 4f51710ed387baa1ad0a6e4cdb0fc5eee44093d5
servo/components/script/dom/bindings/trace.rs
servo/components/script/dom/canvasrenderingcontext2d.rs
servo/components/script/dom/document.rs
servo/components/script/dom/filereader.rs
servo/components/script/dom/htmlscriptelement.rs
servo/components/script/dom/keyboardevent.rs
servo/components/script/dom/url.rs
servo/components/script/dom/webglshader.rs
servo/components/script/dom/websocket.rs
servo/components/script/dom/window.rs
servo/components/script/script_task.rs
--- a/servo/components/script/dom/bindings/trace.rs
+++ b/servo/components/script/dom/bindings/trace.rs
@@ -61,17 +61,17 @@ use profile_traits::mem::ProfilerChan as
 use profile_traits::time::ProfilerChan as TimeProfilerChan;
 use script_task::ScriptChan;
 use script_traits::{TimerEventChan, TimerEventId, TimerSource, UntrustedNodeAddress};
 use selectors::parser::PseudoElement;
 use selectors::states::*;
 use serde::{Deserialize, Serialize};
 use smallvec::SmallVec;
 use std::boxed::FnBox;
-use std::cell::{Cell, RefCell, UnsafeCell};
+use std::cell::{Cell, UnsafeCell};
 use std::collections::hash_state::HashState;
 use std::collections::{HashMap, HashSet};
 use std::ffi::CString;
 use std::hash::{Hash, Hasher};
 use std::intrinsics::return_address;
 use std::iter::{FromIterator, IntoIterator};
 use std::mem;
 use std::ops::{Deref, DerefMut};
@@ -134,54 +134,28 @@ pub fn trace_object(tracer: *mut JSTrace
         (*tracer).debugPrintIndex_ = !0;
         (*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void;
         debug!("tracing {}", description);
         JS_CallObjectTracer(tracer, obj.ptr.get() as *mut _,
                             GCTraceKindToAscii(JSGCTraceKind::JSTRACE_OBJECT));
     }
 }
 
-impl<T: JSTraceable> JSTraceable for RefCell<T> {
-    fn trace(&self, trc: *mut JSTracer) {
-        self.borrow().trace(trc)
-    }
-}
-
 impl<T: JSTraceable> JSTraceable for Rc<T> {
     fn trace(&self, trc: *mut JSTracer) {
         (**self).trace(trc)
     }
 }
 
 impl<T: JSTraceable> JSTraceable for Box<T> {
     fn trace(&self, trc: *mut JSTracer) {
         (**self).trace(trc)
     }
 }
 
-impl<T: JSTraceable> JSTraceable for *const T {
-    fn trace(&self, trc: *mut JSTracer) {
-        if !self.is_null() {
-            unsafe {
-                (**self).trace(trc)
-            }
-        }
-    }
-}
-
-impl<T: JSTraceable> JSTraceable for *mut T {
-    fn trace(&self, trc: *mut JSTracer) {
-        if !self.is_null() {
-            unsafe {
-                (**self).trace(trc)
-            }
-        }
-    }
-}
-
 impl<T: JSTraceable + Copy> JSTraceable for Cell<T> {
     fn trace(&self, trc: *mut JSTracer) {
         self.get().trace(trc)
     }
 }
 
 impl<T: JSTraceable> JSTraceable for UnsafeCell<T> {
     fn trace(&self, trc: *mut JSTracer) {
--- a/servo/components/script/dom/canvasrenderingcontext2d.rs
+++ b/servo/components/script/dom/canvasrenderingcontext2d.rs
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use canvas::canvas_paint_task::RectToi32;
 use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg};
 use canvas_traits::{CompositionOrBlending, LineCapStyle, LineJoinStyle};
 use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle, RepetitionStyle};
 use cssparser::Color as CSSColor;
 use cssparser::{Parser, RGBA};
+use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding;
 use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
 use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasWindingRule;
 use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
 use dom::bindings::codegen::UnionTypes::HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D;
 use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern;
 use dom::bindings::conversions::Castable;
 use dom::bindings::error::{Error, Fallible};
@@ -32,17 +33,16 @@ use euclid::point::Point2D;
 use euclid::rect::Rect;
 use euclid::size::Size2D;
 use ipc_channel::ipc::{self, IpcSender};
 use msg::constellation_msg::Msg as ConstellationMsg;
 use net_traits::image::base::PixelFormat;
 use net_traits::image_cache_task::ImageResponse;
 use num::{Float, ToPrimitive};
 use std::borrow::ToOwned;
-use std::cell::RefCell;
 use std::str::FromStr;
 use std::sync::mpsc::channel;
 use std::{cmp, fmt};
 use unpremultiplytable::UNPREMULTIPLY_TABLE;
 use url::Url;
 use util::str::DOMString;
 use util::vec::byte_swap;
 
@@ -58,18 +58,18 @@ enum CanvasFillOrStrokeStyle {
 #[dom_struct]
 pub struct CanvasRenderingContext2D {
     reflector_: Reflector,
     global: GlobalField,
     renderer_id: usize,
     #[ignore_heap_size_of = "Defined in ipc-channel"]
     ipc_renderer: IpcSender<CanvasMsg>,
     canvas: JS<HTMLCanvasElement>,
-    state: RefCell<CanvasContextState>,
-    saved_states: RefCell<Vec<CanvasContextState>>,
+    state: DOMRefCell<CanvasContextState>,
+    saved_states: DOMRefCell<Vec<CanvasContextState>>,
 }
 
 #[must_root]
 #[derive(JSTraceable, Clone, HeapSizeOf)]
 struct CanvasContextState {
     global_alpha: f64,
     global_composition: CompositionOrBlending,
     image_smoothing_enabled: bool,
@@ -121,18 +121,18 @@ impl CanvasRenderingContext2D {
         constellation_chan.0.send(ConstellationMsg::CreateCanvasPaintTask(size, sender)).unwrap();
         let (ipc_renderer, renderer_id) = receiver.recv().unwrap();
         CanvasRenderingContext2D {
             reflector_: Reflector::new(),
             global: GlobalField::from_rooted(&global),
             renderer_id: renderer_id,
             ipc_renderer: ipc_renderer,
             canvas: JS::from_ref(canvas),
-            state: RefCell::new(CanvasContextState::new()),
-            saved_states: RefCell::new(Vec::new()),
+            state: DOMRefCell::new(CanvasContextState::new()),
+            saved_states: DOMRefCell::new(Vec::new()),
         }
     }
 
     pub fn new(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>)
                -> Root<CanvasRenderingContext2D> {
         reflect_dom_object(box CanvasRenderingContext2D::new_inherited(global, canvas, size),
                            global, CanvasRenderingContext2DBinding::Wrap)
     }
--- a/servo/components/script/dom/document.rs
+++ b/servo/components/script/dom/document.rs
@@ -84,17 +84,17 @@ use net_traits::CookieSource::NonHTTP;
 use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
 use num::ToPrimitive;
 use script_task::{MainThreadScriptMsg, Runnable};
 use script_traits::{MouseButton, UntrustedNodeAddress};
 use selectors::states::*;
 use std::ascii::AsciiExt;
 use std::borrow::ToOwned;
 use std::boxed::FnBox;
-use std::cell::{Cell, Ref, RefCell, RefMut};
+use std::cell::{Cell, Ref, RefMut};
 use std::collections::HashMap;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::default::Default;
 use std::iter::FromIterator;
 use std::ptr;
 use std::rc::Rc;
 use std::sync::mpsc::channel;
 use string_cache::{Atom, QualName};
@@ -158,17 +158,17 @@ pub struct Document {
     /// True if scripting is enabled for all scripts in this document
     scripting_enabled: Cell<bool>,
     /// https://html.spec.whatwg.org/multipage/#animation-frame-callback-identifier
     /// Current identifier of animation frame callback
     animation_frame_ident: Cell<u32>,
     /// https://html.spec.whatwg.org/multipage/#list-of-animation-frame-callbacks
     /// List of animation frame callbacks
     #[ignore_heap_size_of = "closures are hard"]
-    animation_frame_list: RefCell<HashMap<u32, Box<FnBox(f64)>>>,
+    animation_frame_list: DOMRefCell<HashMap<u32, Box<FnBox(f64)>>>,
     /// Tracks all outstanding loads related to this document.
     loader: DOMRefCell<DocumentLoader>,
     /// The current active HTML parser, to allow resuming after interruptions.
     current_parser: MutNullableHeap<JS<ServoHTMLParser>>,
     /// When we should kick off a reflow. This happens during parsing.
     reflow_timeout: Cell<Option<u64>>,
     /// The cached first `base` element with an `href` attribute.
     base_element: MutNullableHeap<JS<HTMLBaseElement>>,
@@ -1257,17 +1257,17 @@ impl Document {
             current_script: Default::default(),
             pending_parsing_blocking_script: Default::default(),
             script_blocking_stylesheets_count: Cell::new(0u32),
             deferred_scripts: DOMRefCell::new(vec!()),
             asap_in_order_scripts_list: DOMRefCell::new(vec!()),
             asap_scripts_set: DOMRefCell::new(vec!()),
             scripting_enabled: Cell::new(true),
             animation_frame_ident: Cell::new(0),
-            animation_frame_list: RefCell::new(HashMap::new()),
+            animation_frame_list: DOMRefCell::new(HashMap::new()),
             loader: DOMRefCell::new(doc_loader),
             current_parser: Default::default(),
             reflow_timeout: Cell::new(None),
             base_element: Default::default(),
             appropriate_template_contents_owner_document: Default::default(),
             element_state_changes: DOMRefCell::new(HashMap::new()),
         }
     }
--- a/servo/components/script/dom/filereader.rs
+++ b/servo/components/script/dom/filereader.rs
@@ -1,12 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
 use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
 use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConstants, FileReaderMethods};
 use dom::bindings::conversions::Castable;
 use dom::bindings::error::{Error, ErrorResult, Fallible};
 use dom::bindings::global::{GlobalField, GlobalRef};
 use dom::bindings::js::{JS, MutNullableHeap, Root};
 use dom::bindings::refcounted::Trusted;
@@ -18,17 +19,17 @@ use dom::eventtarget::EventTarget;
 use dom::progressevent::ProgressEvent;
 use encoding::all::UTF_8;
 use encoding::label::encoding_from_whatwg_label;
 use encoding::types::{DecoderTrap, EncodingRef};
 use hyper::mime::{Attr, Mime};
 use rustc_serialize::base64::{CharacterSet, Config, Newline, ToBase64};
 use script_task::ScriptTaskEventCategory::FileRead;
 use script_task::{CommonScriptMsg, Runnable, ScriptChan, ScriptPort};
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use std::sync::mpsc;
 use std::sync::mpsc::Receiver;
 use util::str::DOMString;
 use util::task::spawn_named;
 
 #[derive(PartialEq, Clone, Copy, JSTraceable, HeapSizeOf)]
 pub enum FileReaderFunction {
     ReadAsText,
@@ -67,28 +68,28 @@ pub enum FileReaderReadyState {
 }
 
 #[dom_struct]
 pub struct FileReader {
     eventtarget: EventTarget,
     global: GlobalField,
     ready_state: Cell<FileReaderReadyState>,
     error: MutNullableHeap<JS<DOMException>>,
-    result: RefCell<Option<DOMString>>,
+    result: DOMRefCell<Option<DOMString>>,
     generation_id: Cell<GenerationId>,
 }
 
 impl FileReader {
     pub fn new_inherited(global: GlobalRef) -> FileReader {
         FileReader {
             eventtarget: EventTarget::new_inherited(),//?
             global: GlobalField::from_rooted(&global),
             ready_state: Cell::new(FileReaderReadyState::Empty),
             error: MutNullableHeap::new(None),
-            result: RefCell::new(None),
+            result: DOMRefCell::new(None),
             generation_id: Cell::new(GenerationId(0)),
         }
     }
 
     pub fn new(global: GlobalRef) -> Root<FileReader> {
         reflect_dom_object(box FileReader::new_inherited(global),
                            global, FileReaderBinding::Wrap)
     }
--- a/servo/components/script/dom/htmlscriptelement.rs
+++ b/servo/components/script/dom/htmlscriptelement.rs
@@ -32,17 +32,17 @@ use ipc_channel::ipc;
 use ipc_channel::router::ROUTER;
 use js::jsapi::RootedValue;
 use js::jsval::UndefinedValue;
 use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata};
 use network_listener::{NetworkListener, PreInvoke};
 use script_task::ScriptTaskEventCategory::ScriptEvent;
 use script_task::{CommonScriptMsg, Runnable, ScriptChan};
 use std::ascii::AsciiExt;
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use std::mem;
 use std::sync::{Arc, Mutex};
 use url::{Url, UrlParser};
 use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec};
 
 #[dom_struct]
 pub struct HTMLScriptElement {
     htmlelement: HTMLElement,
@@ -60,17 +60,17 @@ pub struct HTMLScriptElement {
 
     /// https://html.spec.whatwg.org/multipage/#ready-to-be-parser-executed
     ready_to_be_parser_executed: Cell<bool>,
 
     /// Document of the parser that created this element
     parser_document: JS<Document>,
 
     /// The source this script was loaded from
-    load: RefCell<Option<ScriptOrigin>>,
+    load: DOMRefCell<Option<ScriptOrigin>>,
 
     #[ignore_heap_size_of = "Defined in rust-encoding"]
     /// https://html.spec.whatwg.org/multipage/#concept-script-encoding
     block_character_encoding: DOMRefCell<EncodingRef>,
 }
 
 impl HTMLScriptElement {
     fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document,
@@ -78,17 +78,17 @@ impl HTMLScriptElement {
         HTMLScriptElement {
             htmlelement:
                 HTMLElement::new_inherited(localName, prefix, document),
             already_started: Cell::new(false),
             parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
             non_blocking: Cell::new(creator != ElementCreator::ParserCreated),
             ready_to_be_parser_executed: Cell::new(false),
             parser_document: JS::from_ref(document),
-            load: RefCell::new(None),
+            load: DOMRefCell::new(None),
             block_character_encoding: DOMRefCell::new(UTF_8 as EncodingRef),
         }
     }
 
     #[allow(unrooted_must_root)]
     pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document,
                creator: ElementCreator) -> Root<HTMLScriptElement> {
         let element = HTMLScriptElement::new_inherited(localName, prefix, document, creator);
--- a/servo/components/script/dom/keyboardevent.rs
+++ b/servo/components/script/dom/keyboardevent.rs
@@ -1,56 +1,57 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::KeyboardEventBinding;
 use dom::bindings::codegen::Bindings::KeyboardEventBinding::{KeyboardEventConstants, KeyboardEventMethods};
 use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
 use dom::bindings::conversions::Castable;
 use dom::bindings::error::Fallible;
 use dom::bindings::global::GlobalRef;
 use dom::bindings::js::{Root, RootedReference};
 use dom::bindings::utils::{Reflectable, reflect_dom_object};
 use dom::event::Event;
 use dom::uievent::UIEvent;
 use dom::window::Window;
 use msg::constellation_msg;
 use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
 use msg::constellation_msg::{Key, KeyModifiers};
 use std::borrow::ToOwned;
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use util::str::DOMString;
 
 no_jsmanaged_fields!(Key);
 
 #[dom_struct]
 pub struct KeyboardEvent {
     uievent: UIEvent,
     key: Cell<Option<Key>>,
-    key_string: RefCell<DOMString>,
-    code: RefCell<DOMString>,
+    key_string: DOMRefCell<DOMString>,
+    code: DOMRefCell<DOMString>,
     location: Cell<u32>,
     ctrl: Cell<bool>,
     alt: Cell<bool>,
     shift: Cell<bool>,
     meta: Cell<bool>,
     repeat: Cell<bool>,
     is_composing: Cell<bool>,
     char_code: Cell<Option<u32>>,
     key_code: Cell<u32>,
 }
 
 impl KeyboardEvent {
     fn new_inherited() -> KeyboardEvent {
         KeyboardEvent {
             uievent: UIEvent::new_inherited(),
             key: Cell::new(None),
-            key_string: RefCell::new("".to_owned()),
-            code: RefCell::new("".to_owned()),
+            key_string: DOMRefCell::new("".to_owned()),
+            code: DOMRefCell::new("".to_owned()),
             location: Cell::new(0),
             ctrl: Cell::new(false),
             alt: Cell::new(false),
             shift: Cell::new(false),
             meta: Cell::new(false),
             repeat: Cell::new(false),
             is_composing: Cell::new(false),
             char_code: Cell::new(None),
--- a/servo/components/script/dom/url.rs
+++ b/servo/components/script/dom/url.rs
@@ -1,41 +1,41 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::URLBinding::{self, URLMethods};
 use dom::bindings::error::{Error, ErrorResult, Fallible};
 use dom::bindings::global::GlobalRef;
 use dom::bindings::js::Root;
 use dom::bindings::str::USVString;
 use dom::bindings::utils::{Reflector, reflect_dom_object};
 use dom::urlhelper::UrlHelper;
 use std::borrow::ToOwned;
-use std::cell::RefCell;
 use url::{Host, ParseResult, Url, UrlParser};
 use util::str::DOMString;
 
 // https://url.spec.whatwg.org/#url
 #[dom_struct]
 pub struct URL {
     reflector_: Reflector,
 
     // https://url.spec.whatwg.org/#concept-urlutils-url
-    url: RefCell<Url>,
+    url: DOMRefCell<Url>,
 
     // https://url.spec.whatwg.org/#concept-urlutils-get-the-base
     base: Option<Url>,
 }
 
 impl URL {
     fn new_inherited(url: Url, base: Option<Url>) -> URL {
         URL {
             reflector_: Reflector::new(),
-            url: RefCell::new(url),
+            url: DOMRefCell::new(url),
             base: base,
         }
     }
 
     pub fn new(global: GlobalRef, url: Url, base: Option<Url>) -> Root<URL> {
         reflect_dom_object(box URL::new_inherited(url, base),
                            global, URLBinding::Wrap)
     }
--- a/servo/components/script/dom/webglshader.rs
+++ b/servo/components/script/dom/webglshader.rs
@@ -1,39 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
 use angle::hl::{BuiltInResources, Output, ShaderValidator};
 use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLError, WebGLResult, WebGLShaderParameter};
+use dom::bindings::cell::DOMRefCell;
 use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
 use dom::bindings::codegen::Bindings::WebGLShaderBinding;
 use dom::bindings::global::GlobalRef;
 use dom::bindings::js::Root;
 use dom::bindings::utils::reflect_dom_object;
 use dom::webglobject::WebGLObject;
 use ipc_channel::ipc::{self, IpcSender};
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use std::sync::{ONCE_INIT, Once};
 
 #[derive(Clone, Copy, PartialEq, Debug, JSTraceable, HeapSizeOf)]
 pub enum ShaderCompilationStatus {
     NotCompiled,
     Succeeded,
     Failed,
 }
 
 #[dom_struct]
 pub struct WebGLShader {
     webgl_object: WebGLObject,
     id: u32,
     gl_type: u32,
-    source: RefCell<Option<String>>,
-    info_log: RefCell<Option<String>>,
+    source: DOMRefCell<Option<String>>,
+    info_log: DOMRefCell<Option<String>>,
     is_deleted: Cell<bool>,
     compilation_status: Cell<ShaderCompilationStatus>,
     #[ignore_heap_size_of = "Defined in ipc-channel"]
     renderer: IpcSender<CanvasMsg>,
 }
 
 #[cfg(not(target_os = "android"))]
 const SHADER_OUTPUT_FORMAT: Output = Output::Glsl;
@@ -45,18 +46,18 @@ static GLSLANG_INITIALIZATION: Once = ON
 
 impl WebGLShader {
     fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32, shader_type: u32) -> WebGLShader {
         GLSLANG_INITIALIZATION.call_once(|| ::angle::hl::initialize().unwrap());
         WebGLShader {
             webgl_object: WebGLObject::new_inherited(),
             id: id,
             gl_type: shader_type,
-            source: RefCell::new(None),
-            info_log: RefCell::new(None),
+            source: DOMRefCell::new(None),
+            info_log: DOMRefCell::new(None),
             is_deleted: Cell::new(false),
             compilation_status: Cell::new(ShaderCompilationStatus::NotCompiled),
             renderer: renderer,
         }
     }
 
     pub fn maybe_new(global: GlobalRef,
                      renderer: IpcSender<CanvasMsg>,
--- a/servo/components/script/dom/websocket.rs
+++ b/servo/components/script/dom/websocket.rs
@@ -23,17 +23,17 @@ use hyper::header::Host;
 use js::jsapi::{JSAutoCompartment, JSAutoRequest, RootedValue};
 use js::jsapi::{JS_GetArrayBufferData, JS_NewArrayBuffer};
 use js::jsval::UndefinedValue;
 use libc::{uint32_t, uint8_t};
 use net_traits::hosts::replace_hosts;
 use script_task::ScriptTaskEventCategory::WebSocketEvent;
 use script_task::{CommonScriptMsg, Runnable};
 use std::borrow::ToOwned;
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use std::sync::{Arc, Mutex};
 use std::{ptr, slice};
 use util::str::DOMString;
 use util::task::spawn_named;
 use websocket::client::receiver::Receiver;
 use websocket::client::request::Url;
 use websocket::client::sender::Sender;
 use websocket::header::Origin;
@@ -128,17 +128,17 @@ const BLOCKED_PORTS_LIST: &'static [u16]
 pub struct WebSocket {
     eventtarget: EventTarget,
     url: Url,
     global: GlobalField,
     ready_state: Cell<WebSocketRequestState>,
     buffered_amount: Cell<u32>,
     clearing_buffer: Cell<bool>, //Flag to tell if there is a running task to clear buffered_amount
     #[ignore_heap_size_of = "Defined in std"]
-    sender: RefCell<Option<Arc<Mutex<Sender<WebSocketStream>>>>>,
+    sender: DOMRefCell<Option<Arc<Mutex<Sender<WebSocketStream>>>>>,
     failed: Cell<bool>, //Flag to tell if websocket was closed due to failure
     full: Cell<bool>, //Flag to tell if websocket queue is full
     clean_close: Cell<bool>, //Flag to tell if the websocket closed cleanly (not due to full or fail)
     code: Cell<u16>, //Closing code
     reason: DOMRefCell<DOMString>, //Closing reason
     binary_type: Cell<BinaryType>,
 }
 
@@ -170,17 +170,17 @@ impl WebSocket {
         WebSocket {
             eventtarget: EventTarget::new_inherited(),
             url: url,
             global: GlobalField::from_rooted(&global),
             ready_state: Cell::new(WebSocketRequestState::Connecting),
             buffered_amount: Cell::new(0),
             clearing_buffer: Cell::new(false),
             failed: Cell::new(false),
-            sender: RefCell::new(None),
+            sender: DOMRefCell::new(None),
             full: Cell::new(false),
             clean_close: Cell::new(true),
             code: Cell::new(0),
             reason: DOMRefCell::new("".to_owned()),
             binary_type: Cell::new(BinaryType::Blob),
         }
 
     }
--- a/servo/components/script/dom/window.rs
+++ b/servo/components/script/dom/window.rs
@@ -53,17 +53,17 @@ use page::Page;
 use profile_traits::mem;
 use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
 use script_task::{ScriptChan, ScriptPort, MainThreadScriptMsg};
 use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan, MainThreadTimerEventChan};
 use script_traits::{ConstellationControlMsg, TimerEventChan, TimerEventId, TimerEventRequest, TimerSource};
 use selectors::parser::PseudoElement;
 use std::ascii::AsciiExt;
 use std::borrow::ToOwned;
-use std::cell::{Cell, Ref, RefCell};
+use std::cell::{Cell, Ref};
 use std::collections::HashSet;
 use std::default::Default;
 use std::ffi::CString;
 use std::io::{Write, stderr, stdout};
 use std::rc::Rc;
 use std::sync::Arc;
 use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
 use std::sync::mpsc::{Sender, channel};
@@ -139,19 +139,19 @@ pub struct Window {
     mem_profiler_chan: mem::ProfilerChan,
 
     /// For providing instructions to an optional devtools server.
     #[ignore_heap_size_of = "channels are hard"]
     devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
     /// For sending timeline markers. Will be ignored if
     /// no devtools server
     #[ignore_heap_size_of = "TODO(#6909) need to measure HashSet"]
-    devtools_markers: RefCell<HashSet<TimelineMarkerType>>,
+    devtools_markers: DOMRefCell<HashSet<TimelineMarkerType>>,
     #[ignore_heap_size_of = "channels are hard"]
-    devtools_marker_sender: RefCell<Option<IpcSender<TimelineMarker>>>,
+    devtools_marker_sender: DOMRefCell<Option<IpcSender<TimelineMarker>>>,
 
     /// A flag to indicate whether the developer tools have requested live updates of
     /// page changes.
     devtools_wants_updates: Cell<bool>,
 
     next_subpage_id: Cell<SubpageId>,
 
     /// Pending resize event, if any.
@@ -203,17 +203,17 @@ pub struct Window {
     /// to prevent creating display list items for content that is far away from the viewport.
     page_clip_rect: Cell<Rect<Au>>,
 
     /// A counter of the number of pending reflows for this window.
     pending_reflow_count: Cell<u32>,
 
     /// A channel for communicating results of async scripts back to the webdriver server
     #[ignore_heap_size_of = "channels are hard"]
-    webdriver_script_chan: RefCell<Option<IpcSender<WebDriverJSResult>>>,
+    webdriver_script_chan: DOMRefCell<Option<IpcSender<WebDriverJSResult>>>,
 
     /// The current state of the window object
     current_state: Cell<WindowState>,
 
     current_viewport: Cell<Rect<Au>>
 }
 
 impl Window {
@@ -1271,20 +1271,20 @@ impl Window {
             next_subpage_id: Cell::new(SubpageId(0)),
             layout_chan: layout_chan,
             layout_rpc: layout_rpc,
             window_size: Cell::new(window_size),
             current_viewport: Cell::new(Rect::zero()),
             pending_reflow_count: Cell::new(0),
             current_state: Cell::new(WindowState::Alive),
 
-            devtools_marker_sender: RefCell::new(None),
-            devtools_markers: RefCell::new(HashSet::new()),
+            devtools_marker_sender: DOMRefCell::new(None),
+            devtools_markers: DOMRefCell::new(HashSet::new()),
             devtools_wants_updates: Cell::new(false),
-            webdriver_script_chan: RefCell::new(None),
+            webdriver_script_chan: DOMRefCell::new(None),
         };
 
         WindowBinding::Wrap(runtime.cx(), win)
     }
 }
 
 fn should_move_clip_rect(clip_rect: Rect<Au>, new_viewport: Rect<f32>) -> bool {
     let clip_rect = Rect::new(Point2D::new(clip_rect.origin.x.to_f32_px(),
--- a/servo/components/script/script_task.rs
+++ b/servo/components/script/script_task.rs
@@ -409,17 +409,17 @@ pub struct ScriptTask {
     devtools_sender: IpcSender<DevtoolScriptControlMsg>,
 
     /// The JavaScript runtime.
     js_runtime: Rc<Runtime>,
 
     mouse_over_targets: DOMRefCell<Vec<JS<Element>>>,
 
     /// List of pipelines that have been owned and closed by this script task.
-    closed_pipelines: RefCell<HashSet<PipelineId>>,
+    closed_pipelines: DOMRefCell<HashSet<PipelineId>>,
 
     scheduler_chan: Sender<TimerEventRequest>,
     timer_event_chan: Sender<TimerEvent>,
     timer_event_port: Receiver<TimerEvent>,
 }
 
 /// In the event of task failure, all data on the stack runs its destructor. However, there
 /// are no reachable, owning pointers to the DOM memory, so it never gets freed by default
@@ -638,17 +638,17 @@ impl ScriptTask {
             mem_profiler_chan: state.mem_profiler_chan,
 
             devtools_chan: state.devtools_chan,
             devtools_port: devtools_port,
             devtools_sender: ipc_devtools_sender,
 
             js_runtime: Rc::new(runtime),
             mouse_over_targets: DOMRefCell::new(vec!()),
-            closed_pipelines: RefCell::new(HashSet::new()),
+            closed_pipelines: DOMRefCell::new(HashSet::new()),
 
             scheduler_chan: state.scheduler_chan,
             timer_event_chan: timer_event_chan,
             timer_event_port: timer_event_port,
         }
     }
 
     pub fn new_rt_and_cx() -> Runtime {