Auto merge of #13459 - servo:no-arc-heapsize, r=emilio

Use parking_lot::RwLock for PropertyDeclarationBlock

<!-- Please describe your changes on the following line: -->

As discussed in https://bugzilla.mozilla.org/show_bug.cgi?id=1305141

Closes #13176

---

Original PR title: Stop relying on `impl<T: HeapSizeOf> HeapSizeOf for Arc<T>`
https://github.com/servo/heapsize/issues/37#issuecomment-249861171

This builds on top of that.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because refactor

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13459)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-04 11:58:56 -05:00 committed by GitHub
commit aea9545e16
46 changed files with 313 additions and 265 deletions

View file

@ -15,10 +15,10 @@ use dom::element::{AttributeMutation, Element};
use dom::virtualmethods::vtable_for;
use dom::window::Window;
use std::borrow::ToOwned;
use std::cell::Ref;
use std::mem;
use string_cache::{Atom, Namespace};
use style::attr::{AttrIdentifier, AttrValue};
use style::refcell::Ref;
// https://dom.spec.whatwg.org/#interface-attr
#[dom_struct]

View file

@ -0,0 +1,128 @@
/* 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/. */
//! A shareable mutable container for the DOM.
use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
use style::thread_state;
/// A mutable field in the DOM.
///
/// This extends the API of `core::cell::RefCell` to allow unsafe access in
/// certain situations, with dynamic checking in debug builds.
#[derive(Clone, PartialEq, Debug, HeapSizeOf)]
pub struct DOMRefCell<T> {
value: RefCell<T>,
}
// Functionality specific to Servo's `DOMRefCell` type
// ===================================================
impl<T> DOMRefCell<T> {
/// Return a reference to the contents.
///
/// For use in the layout thread only.
#[allow(unsafe_code)]
pub unsafe fn borrow_for_layout(&self) -> &T {
debug_assert!(thread_state::get().is_layout());
&*self.value.as_ptr()
}
/// Borrow the contents for the purpose of GC tracing.
///
/// This succeeds even if the object is mutably borrowed,
/// so you have to be careful in trace code!
#[allow(unsafe_code)]
pub unsafe fn borrow_for_gc_trace(&self) -> &T {
// FIXME: IN_GC isn't reliable enough - doesn't catch minor GCs
// https://github.com/servo/servo/issues/6389
// debug_assert!(thread_state::get().contains(SCRIPT | IN_GC));
&*self.value.as_ptr()
}
/// Borrow the contents for the purpose of script deallocation.
///
#[allow(unsafe_code)]
pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T {
debug_assert!(thread_state::get().contains(thread_state::SCRIPT));
&mut *self.value.as_ptr()
}
/// Version of the above that we use during restyle while the script thread
/// is blocked.
pub fn borrow_mut_for_layout(&self) -> RefMut<T> {
debug_assert!(thread_state::get().is_layout());
self.value.borrow_mut()
}
}
// Functionality duplicated with `core::cell::RefCell`
// ===================================================
impl<T> DOMRefCell<T> {
/// Create a new `DOMRefCell` containing `value`.
pub fn new(value: T) -> DOMRefCell<T> {
DOMRefCell {
value: RefCell::new(value),
}
}
/// Immutably borrows the wrapped value.
///
/// The borrow lasts until the returned `Ref` exits scope. Multiple
/// immutable borrows can be taken out at the same time.
///
/// # Panics
///
/// Panics if this is called off the script thread.
///
/// Panics if the value is currently mutably borrowed.
pub fn borrow(&self) -> Ref<T> {
self.try_borrow().expect("DOMRefCell<T> already mutably borrowed")
}
/// Mutably borrows the wrapped value.
///
/// The borrow lasts until the returned `RefMut` exits scope. The value
/// cannot be borrowed while this borrow is active.
///
/// # Panics
///
/// Panics if this is called off the script thread.
///
/// Panics if the value is currently borrowed.
pub fn borrow_mut(&self) -> RefMut<T> {
self.try_borrow_mut().expect("DOMRefCell<T> already borrowed")
}
/// Attempts to immutably borrow the wrapped value.
///
/// The borrow lasts until the returned `Ref` exits scope. Multiple
/// immutable borrows can be taken out at the same time.
///
/// Returns `None` if the value is currently mutably borrowed.
///
/// # Panics
///
/// Panics if this is called off the script thread.
pub fn try_borrow(&self) -> Result<Ref<T>, BorrowError<T>> {
debug_assert!(thread_state::get().is_script());
self.value.try_borrow()
}
/// Mutably borrows the wrapped value.
///
/// The borrow lasts until the returned `RefMut` exits scope. The value
/// cannot be borrowed while this borrow is active.
///
/// Returns `None` if the value is currently borrowed.
///
/// # Panics
///
/// Panics if this is called off the script thread.
pub fn try_borrow_mut(&self) -> Result<RefMut<T>, BorrowMutError<T>> {
debug_assert!(thread_state::get().is_script());
self.value.try_borrow_mut()
}
}

View file

@ -128,9 +128,8 @@
//! return `Err()` from the method with the appropriate [error value]
//! (error/enum.Error.html).
pub use style::domrefcell as cell;
pub mod callback;
pub mod cell;
pub mod constant;
pub mod conversions;
pub mod error;

View file

@ -35,6 +35,7 @@ use cssparser::RGBA;
use devtools_traits::CSSError;
use devtools_traits::WorkerId;
use dom::abstractworker::SharedRt;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::js::{JS, Root};
use dom::bindings::refcounted::{Trusted, TrustedPromise};
use dom::bindings::reflector::{Reflectable, Reflector};
@ -89,7 +90,6 @@ use std::sync::mpsc::{Receiver, Sender};
use std::time::{SystemTime, Instant};
use string_cache::{Atom, Namespace, QualName};
use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto};
use style::domrefcell::DOMRefCell;
use style::element_state::*;
use style::properties::PropertyDeclarationBlock;
use style::selector_impl::{ElementSnapshot, PseudoElement};

View file

@ -19,7 +19,7 @@ use dom::element::Element;
use dom::node::{Node, NodeDamage};
use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
use style::refcell::Ref;
use std::cell::Ref;
use util::opts;
// https://dom.spec.whatwg.org/#characterdata

View file

@ -13,14 +13,13 @@ use dom::bindings::str::DOMString;
use dom::element::Element;
use dom::node::{Node, NodeDamage, window_from_node};
use dom::window::Window;
use parking_lot::RwLock;
use std::ascii::AsciiExt;
use std::slice;
use std::sync::Arc;
use string_cache::Atom;
use style::parser::ParserContextExtraData;
use style::properties::{PropertyDeclaration, Shorthand, Importance};
use style::properties::{Shorthand, Importance};
use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
use style::refcell::Ref;
use style::selector_impl::PseudoElement;
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
@ -93,7 +92,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
fn Length(&self) -> u32 {
let elem = self.owner.upcast::<Element>();
let len = match *elem.style_attribute().borrow() {
Some(ref declarations) => declarations.declarations.len(),
Some(ref declarations) => declarations.read().declarations.len(),
None => 0,
};
len as u32
@ -119,43 +118,42 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// Step 2
if let Some(shorthand) = Shorthand::from_name(&property) {
let style_attribute = owner.style_attribute().borrow();
let style_attribute = if let Some(ref style_attribute) = *style_attribute {
style_attribute.read()
} else {
// shorthand.longhands() is never empty, so with no style attribute
// step 2.2.2 would do this:
return DOMString::new()
};
// Step 2.1
let mut list = vec![];
// Step 2.2
for longhand in shorthand.longhands() {
// Step 2.2.1
let declaration = owner.get_inline_style_declaration(&Atom::from(*longhand));
let declaration = style_attribute.get(longhand);
// Step 2.2.2 & 2.2.3
match declaration {
Some(declaration) => list.push(declaration),
Some(&(ref declaration, _importance)) => list.push(declaration),
None => return DOMString::new(),
}
}
// Step 2.3
// Work around closures not being Clone
#[derive(Clone)]
struct Map<'a, 'b: 'a>(slice::Iter<'a, Ref<'b, (PropertyDeclaration, Importance)>>);
impl<'a, 'b> Iterator for Map<'a, 'b> {
type Item = &'a PropertyDeclaration;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|r| &r.0)
}
}
// TODO: important is hardcoded to false because method does not implement it yet
let serialized_value = shorthand.serialize_shorthand_value_to_string(
Map(list.iter()), Importance::Normal);
list, Importance::Normal);
return DOMString::from(serialized_value);
}
// Step 3 & 4
match owner.get_inline_style_declaration(&property) {
owner.get_inline_style_declaration(&property, |d| match d {
Some(declaration) => DOMString::from(declaration.0.value()),
None => DOMString::new(),
}
})
}
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
@ -172,13 +170,18 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
.all(|priority| priority == "important") {
return DOMString::from("important");
}
// Step 3
} else {
if let Some(decl) = self.owner.get_inline_style_declaration(&property) {
if decl.1.important() {
return DOMString::from("important");
// Step 3
return self.owner.get_inline_style_declaration(&property, |d| {
if let Some(decl) = d {
if decl.1.important() {
return DOMString::from("important");
}
}
}
// Step 4
DOMString::new()
})
}
// Step 4
@ -328,13 +331,14 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
let elem = self.owner.upcast::<Element>();
let style_attribute = elem.style_attribute().borrow();
style_attribute.as_ref().and_then(|declarations| {
declarations.declarations.get(index)
}).map(|&(ref declaration, importance)| {
let mut css = declaration.to_css_string();
if importance.important() {
css += " !important";
}
DOMString::from(css)
declarations.read().declarations.get(index).map(|entry| {
let (ref declaration, importance) = *entry;
let mut css = declaration.to_css_string();
if importance.important() {
css += " !important";
}
DOMString::from(css)
})
})
}
@ -344,7 +348,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
let style_attribute = elem.style_attribute().borrow();
if let Some(declarations) = style_attribute.as_ref() {
DOMString::from(declarations.to_css_string())
DOMString::from(declarations.read().to_css_string())
} else {
DOMString::new()
}
@ -366,7 +370,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
*element.style_attribute().borrow_mut() = if decl_block.declarations.is_empty() {
None // Step 2
} else {
Some(Arc::new(decl_block))
Some(Arc::new(RwLock::new(decl_block)))
};
element.sync_property_with_attrs_style();
let node = element.upcast::<Node>();

View file

@ -113,7 +113,7 @@ use script_traits::UntrustedNodeAddress;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::cell::Cell;
use std::cell::{Cell, Ref, RefMut};
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default;
@ -125,7 +125,6 @@ use std::time::{Duration, Instant};
use string_cache::{Atom, QualName};
use style::attr::AttrValue;
use style::context::ReflowGoal;
use style::refcell::{Ref, RefMut};
use style::selector_impl::ElementSnapshot;
use style::str::{split_html_space_chars, str_join};
use style::stylesheets::Stylesheet;
@ -146,6 +145,14 @@ enum ParserBlockedByScript {
Unblocked,
}
#[derive(JSTraceable, HeapSizeOf)]
#[must_root]
struct StylesheetInDocument {
node: JS<Node>,
#[ignore_heap_size_of = "Arc"]
stylesheet: Arc<Stylesheet>,
}
// https://dom.spec.whatwg.org/#document
#[dom_struct]
pub struct Document {
@ -174,7 +181,7 @@ pub struct Document {
anchors: MutNullableHeap<JS<HTMLCollection>>,
applets: MutNullableHeap<JS<HTMLCollection>>,
/// List of stylesheets associated with nodes in this document. |None| if the list needs to be refreshed.
stylesheets: DOMRefCell<Option<Vec<(JS<Node>, Arc<Stylesheet>)>>>,
stylesheets: DOMRefCell<Option<Vec<StylesheetInDocument>>>,
/// Whether the list of stylesheets has changed since the last reflow was triggered.
stylesheets_changed_since_reflow: Cell<bool>,
ready_state: Cell<DocumentReadyState>,
@ -1879,13 +1886,16 @@ impl Document {
node.get_stylesheet()
} else {
None
}.map(|stylesheet| (JS::from_ref(&*node), stylesheet))
}.map(|stylesheet| StylesheetInDocument {
node: JS::from_ref(&*node),
stylesheet: stylesheet
})
})
.collect());
};
}
self.stylesheets.borrow().as_ref().unwrap().iter()
.map(|&(_, ref stylesheet)| stylesheet.clone())
.map(|s| s.stylesheet.clone())
.collect()
}

View file

@ -14,9 +14,8 @@ use dom::bindings::reflector::{reflect_dom_object, Reflectable, Reflector};
use dom::dommatrix::DOMMatrix;
use dom::dompoint::DOMPoint;
use euclid::{Matrix4D, Point4D, Radians};
use std::cell::Cell;
use std::cell::{Cell, Ref};
use std::f64;
use style::refcell::Ref;
#[dom_struct]
pub struct DOMMatrixReadOnly {

View file

@ -70,12 +70,13 @@ use html5ever::serialize::SerializeOpts;
use html5ever::serialize::TraversalScope;
use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks};
use parking_lot::RwLock;
use selectors::matching::{ElementFlags, MatchingReason, matches};
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str};
use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::cell::Cell;
use std::cell::{Cell, Ref};
use std::convert::TryFrom;
use std::default::Default;
use std::fmt;
@ -89,7 +90,6 @@ use style::parser::ParserContextExtraData;
use style::properties::{DeclaredValue, Importance};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x};
use style::refcell::Ref;
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
use style::selector_matching::ApplicableDeclarationBlock;
use style::sink::Push;
@ -109,7 +109,8 @@ pub struct Element {
prefix: Option<DOMString>,
attrs: DOMRefCell<Vec<JS<Attr>>>,
id_attribute: DOMRefCell<Option<Atom>>,
style_attribute: DOMRefCell<Option<Arc<PropertyDeclarationBlock>>>,
#[ignore_heap_size_of = "Arc"]
style_attribute: DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>>,
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
class_list: MutNullableHeap<JS<DOMTokenList>>,
state: Cell<ElementState>,
@ -297,7 +298,7 @@ pub trait LayoutElementHelpers {
#[allow(unsafe_code)]
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
fn id_attribute(&self) -> *const Option<Atom>;
fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>>;
fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>>;
fn local_name(&self) -> &Atom;
fn namespace(&self) -> &Namespace;
fn get_checked_state_for_layout(&self) -> bool;
@ -329,10 +330,10 @@ impl LayoutElementHelpers for LayoutJS<Element> {
#[inline]
fn from_declaration(rule: PropertyDeclaration) -> ApplicableDeclarationBlock {
ApplicableDeclarationBlock::from_declarations(
Arc::new(PropertyDeclarationBlock {
Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: vec![(rule, Importance::Normal)],
important_count: 0,
}),
})),
Importance::Normal)
}
@ -618,7 +619,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
}
#[allow(unsafe_code)]
fn style_attribute(&self) -> *const Option<Arc<PropertyDeclarationBlock>> {
fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>> {
unsafe {
(*self.unsafe_get()).style_attribute.borrow_for_layout()
}
@ -707,7 +708,7 @@ impl Element {
self.attrs.borrow()
}
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<PropertyDeclarationBlock>>> {
pub fn style_attribute(&self) -> &DOMRefCell<Option<Arc<RwLock<PropertyDeclarationBlock>>>> {
&self.style_attribute
}
@ -737,7 +738,7 @@ impl Element {
// therefore, it should not trigger subsequent mutation events
pub fn sync_property_with_attrs_style(&self) {
let style_str = if let &Some(ref declarations) = &*self.style_attribute().borrow() {
declarations.to_css_string()
declarations.read().to_css_string()
} else {
String::new()
};
@ -769,7 +770,7 @@ impl Element {
let mut inline_declarations = element.style_attribute.borrow_mut();
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
let mut importance = None;
let index = declarations.declarations.iter().position(|&(ref decl, i)| {
let index = declarations.read().declarations.iter().position(|&(ref decl, i)| {
let matching = decl.matches(property);
if matching {
importance = Some(i)
@ -777,7 +778,7 @@ impl Element {
matching
});
if let Some(index) = index {
let declarations = Arc::make_mut(declarations);
let mut declarations = declarations.write();
declarations.declarations.remove(index);
if importance.unwrap().important() {
declarations.important_count -= 1;
@ -798,9 +799,8 @@ impl Element {
let mut inline_declarations = element.style_attribute().borrow_mut();
if let &mut Some(ref mut declaration_block) = &mut *inline_declarations {
{
// Usually, the reference count will be 1 here. But transitions could make it greater
// than that.
let declaration_block = Arc::make_mut(declaration_block);
let mut declaration_block = declaration_block.write();
let declaration_block = &mut *declaration_block;
let existing_declarations = &mut declaration_block.declarations;
'outer: for incoming_declaration in declarations {
@ -834,10 +834,10 @@ impl Element {
0
};
*inline_declarations = Some(Arc::new(PropertyDeclarationBlock {
*inline_declarations = Some(Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: declarations.into_iter().map(|d| (d, importance)).collect(),
important_count: important_count,
}));
})));
}
update(self, declarations, importance);
@ -850,9 +850,8 @@ impl Element {
{
let mut inline_declarations = self.style_attribute().borrow_mut();
if let &mut Some(ref mut block) = &mut *inline_declarations {
// Usually, the reference counts of `from` and `to` will be 1 here. But transitions
// could make them greater than that.
let block = Arc::make_mut(block);
let mut block = block.write();
let block = &mut *block;
let declarations = &mut block.declarations;
for &mut (ref declaration, ref mut importance) in declarations {
if properties.iter().any(|p| declaration.name() == **p) {
@ -874,16 +873,15 @@ impl Element {
self.sync_property_with_attrs_style();
}
pub fn get_inline_style_declaration(&self,
property: &Atom)
-> Option<Ref<(PropertyDeclaration, Importance)>> {
Ref::filter_map(self.style_attribute.borrow(), |inline_declarations| {
inline_declarations.as_ref().and_then(|declarations| {
declarations.declarations
.iter()
.find(|&&(ref decl, _)| decl.matches(&property))
})
})
pub fn get_inline_style_declaration<F, R>(&self, property: &str, f: F) -> R
where F: FnOnce(Option<&(PropertyDeclaration, Importance)>) -> R {
let style_attr = self.style_attribute.borrow();
if let Some(ref block) = *style_attr {
let block = block.read();
f(block.get(property))
} else {
f(None)
}
}
pub fn serialize(&self, traversal_scope: TraversalScope) -> Fallible<DOMString> {
@ -2129,11 +2127,11 @@ impl VirtualMethods for Element {
*self.style_attribute.borrow_mut() =
mutation.new_value(attr).map(|value| {
let win = window_from_node(self);
Arc::new(parse_style_attribute(
Arc::new(RwLock::new(parse_style_attribute(
&value,
&doc.base_url(),
win.css_error_reporter(),
ParserContextExtraData::default()))
ParserContextExtraData::default())))
});
if node.is_in_doc() {
node.dirty(NodeDamage::NodeStyleDamaged);

View file

@ -47,6 +47,7 @@ struct ImageRequest {
state: State,
parsed_url: Option<Url>,
source_url: Option<DOMString>,
#[ignore_heap_size_of = "Arc"]
image: Option<Arc<Image>>,
metadata: Option<ImageMetadata>,
}

View file

@ -52,6 +52,7 @@ no_jsmanaged_fields!(Stylesheet);
pub struct HTMLLinkElement {
htmlelement: HTMLElement,
rel_list: MutNullableHeap<JS<DOMTokenList>>,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts

View file

@ -27,6 +27,7 @@ use style::viewport::ViewportRule;
#[dom_struct]
pub struct HTMLMetaElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
}

View file

@ -24,6 +24,7 @@ use string_cache::Atom;
#[dom_struct]
pub struct HTMLObjectElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
image: DOMRefCell<Option<Arc<Image>>>,
}

View file

@ -24,6 +24,7 @@ use style::stylesheets::{Stylesheet, Origin};
#[dom_struct]
pub struct HTMLStyleElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
}

View file

@ -35,10 +35,9 @@ use net_traits::request::Referrer as NetTraitsRequestReferrer;
use net_traits::request::Request as NetTraitsRequest;
use net_traits::request::RequestMode as NetTraitsRequestMode;
use net_traits::request::Type as NetTraitsRequestType;
use std::cell::Cell;
use std::cell::{Cell, Ref};
use std::mem;
use std::rc::Rc;
use style::refcell::Ref;
use url::Url;
#[dom_struct]

View file

@ -22,10 +22,10 @@ use hyper::header::Headers as HyperHeaders;
use hyper::status::StatusCode;
use hyper_serde::Serde;
use net_traits::response::{ResponseBody as NetTraitsResponseBody};
use std::cell::Ref;
use std::mem;
use std::rc::Rc;
use std::str::FromStr;
use style::refcell::Ref;
use url::Position;
use url::Url;

View file

@ -83,6 +83,7 @@ pub struct WorkerGlobalScope {
worker_id: WorkerId,
pipeline_id: PipelineId,
worker_url: Url,
#[ignore_heap_size_of = "Arc"]
closing: Option<Arc<AtomicBool>>,
#[ignore_heap_size_of = "Defined in js"]
runtime: Runtime,