diff options
-rw-r--r-- | components/script/dom/element.rs | 66 | ||||
-rw-r--r-- | components/script/dom/macros.rs | 30 | ||||
-rw-r--r-- | components/script/dom/mutationobserver.rs | 26 | ||||
-rw-r--r-- | components/script/dom/node.rs | 45 | ||||
-rw-r--r-- | components/script/dom/raredata.rs | 16 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 5 | ||||
-rw-r--r-- | components/style/stylesheet_set.rs | 102 | ||||
-rw-r--r-- | tests/unit/script/size_of.rs | 15 |
8 files changed, 183 insertions, 122 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 169fb7b9013..6983b8be2c1 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -106,7 +106,7 @@ use selectors::Element as SelectorsElement; use servo_arc::Arc; use servo_atoms::Atom; use std::borrow::Cow; -use std::cell::{Cell, Ref}; +use std::cell::{Cell, Ref, RefMut}; use std::default::Default; use std::fmt; use std::mem; @@ -166,7 +166,7 @@ pub struct Element { /// when it has exclusive access to the element. #[ignore_malloc_size_of = "bitflags defined in rust-selectors"] selector_flags: Cell<ElementSelectorFlags>, - rare_data: Box<ElementRareData>, + rare_data: DomRefCell<Option<Box<ElementRareData>>>, } impl fmt::Debug for Element { @@ -308,6 +308,8 @@ impl Element { ) } + impl_rare_data!(ElementRareData); + pub fn restyle(&self, damage: NodeDamage) { let doc = self.node.owner_doc(); let mut restyle = doc.ensure_pending_restyle(self); @@ -330,39 +332,49 @@ impl Element { } pub fn set_custom_element_state(&self, state: CustomElementState) { - self.rare_data.custom_element_state.set(state); + self.rare_data_mut().as_mut().unwrap().custom_element_state = state; } pub fn get_custom_element_state(&self) -> CustomElementState { - self.rare_data.custom_element_state.get() + self.rare_data().as_ref().unwrap().custom_element_state } pub fn set_custom_element_definition(&self, definition: Rc<CustomElementDefinition>) { - *self.rare_data.custom_element_definition.borrow_mut() = Some(definition); + self.rare_data_mut() + .as_mut() + .unwrap() + .custom_element_definition = Some(definition); } pub fn get_custom_element_definition(&self) -> Option<Rc<CustomElementDefinition>> { - (*self.rare_data.custom_element_definition.borrow()).clone() + self.rare_data() + .as_ref() + .unwrap() + .custom_element_definition + .clone() } pub fn push_callback_reaction(&self, function: Rc<Function>, args: Box<[Heap<JSVal>]>) { - self.rare_data + self.rare_data_mut() + .as_mut() + .unwrap() .custom_element_reaction_queue - .borrow_mut() .push(CustomElementReaction::Callback(function, args)); } pub fn push_upgrade_reaction(&self, definition: Rc<CustomElementDefinition>) { - self.rare_data + self.rare_data_mut() + .as_mut() + .unwrap() .custom_element_reaction_queue - .borrow_mut() .push(CustomElementReaction::Upgrade(definition)); } pub fn clear_reaction_queue(&self) { - self.rare_data + self.rare_data_mut() + .as_mut() + .unwrap() .custom_element_reaction_queue - .borrow_mut() .clear(); } @@ -371,14 +383,19 @@ impl Element { // after clear_reaction_queue has been called. rooted_vec!(let mut reactions); while !self - .rare_data + .rare_data() + .as_ref() + .unwrap() .custom_element_reaction_queue - .borrow() .is_empty() { mem::swap( &mut *reactions, - &mut *self.rare_data.custom_element_reaction_queue.borrow_mut(), + &mut self + .rare_data_mut() + .as_mut() + .unwrap() + .custom_element_reaction_queue, ); for reaction in reactions.iter() { reaction.invoke(self); @@ -441,7 +458,7 @@ impl Element { } pub fn is_shadow_host(&self) -> bool { - self.rare_data.shadow_root.get().is_some() + self.rare_data().as_ref().unwrap().shadow_root.is_some() } /// https://dom.spec.whatwg.org/#dom-element-attachshadow @@ -484,10 +501,8 @@ impl Element { } // Steps 4, 5 and 6. - let shadow_root = self - .rare_data - .shadow_root - .or_init(|| ShadowRoot::new(self, &*self.node.owner_doc())); + let shadow_root = ShadowRoot::new(self, &*self.node.owner_doc()); + self.rare_data_mut().as_mut().unwrap().shadow_root = Some(Dom::from_ref(&*shadow_root)); if self.is_connected() { self.node.owner_doc().register_shadow_root(&*shadow_root); @@ -1063,9 +1078,12 @@ impl LayoutElementHelpers for LayoutDom<Element> { #[allow(unsafe_code)] unsafe fn get_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> { (*self.unsafe_get()) - .rare_data + .rare_data_for_layout() + .as_ref() + .unwrap() .shadow_root - .get_inner_as_layout() + .as_ref() + .map(|sr| sr.to_layout()) } } @@ -2809,7 +2827,7 @@ impl VirtualMethods for Element { let doc = document_from_node(self); - if let Some(shadow_root) = self.rare_data.shadow_root.get() { + if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().shadow_root { doc.register_shadow_root(&shadow_root); let shadow_root = shadow_root.upcast::<Node>(); shadow_root.set_flag(NodeFlags::IS_CONNECTED, context.tree_connected); @@ -2847,7 +2865,7 @@ impl VirtualMethods for Element { let doc = document_from_node(self); - if let Some(shadow_root) = self.rare_data.shadow_root.get() { + if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().shadow_root { doc.unregister_shadow_root(&shadow_root); let shadow_root = shadow_root.upcast::<Node>(); shadow_root.set_flag(NodeFlags::IS_CONNECTED, false); diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index a566fee4fb6..0fb51c7d8fd 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -632,3 +632,33 @@ macro_rules! handle_potential_webgl_error { handle_potential_webgl_error!($context, $call, ()); }; } + +macro_rules! impl_rare_data ( + ($type:ty) => ( + fn init_rare_data(&self) { + let mut rare_data = self.rare_data.borrow_mut(); + if rare_data.is_none() { + *rare_data = Some(Default::default()); + } + } + + fn rare_data(&self) -> Ref<Option<Box<$type>>> { + self.init_rare_data(); + self.rare_data.borrow() + } + + fn rare_data_mut(&self) -> RefMut<Option<Box<$type>>> { + self.init_rare_data(); + self.rare_data.borrow_mut() + } + + #[allow(unsafe_code)] + fn rare_data_for_layout(&self) -> &Option<Box<$type>> { + let mut rare_data = self.rare_data.borrow_mut_for_layout(); + if rare_data.is_none() { + *rare_data = Some(Default::default()); + } + unsafe { self.rare_data.borrow_for_layout() } + } + ); +); diff --git a/components/script/dom/mutationobserver.rs b/components/script/dom/mutationobserver.rs index 2d303950b8c..bb87a10f4b2 100644 --- a/components/script/dom/mutationobserver.rs +++ b/components/script/dom/mutationobserver.rs @@ -318,20 +318,18 @@ impl MutationObserverMethods for MutationObserver { // Step 8 if add_new_observer { - target - .registered_mutation_observers() - .push(RegisteredObserver { - observer: DomRoot::from_ref(self), - options: ObserverOptions { - attributes, - attribute_old_value, - character_data, - character_data_old_value, - subtree, - attribute_filter, - child_list, - }, - }); + target.add_mutation_observer(RegisteredObserver { + observer: DomRoot::from_ref(self), + options: ObserverOptions { + attributes, + attribute_old_value, + character_data, + character_data_old_value, + subtree, + attribute_filter, + child_list, + }, + }); self.node_list.borrow_mut().push(DomRoot::from_ref(target)); } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 4ceb4305ddf..3238727267e 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -5,6 +5,7 @@ //! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. use crate::document_loader::DocumentLoader; +use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; @@ -82,7 +83,7 @@ use servo_arc::Arc; use servo_url::ServoUrl; use smallvec::SmallVec; use std::borrow::ToOwned; -use std::cell::{Cell, RefMut, UnsafeCell}; +use std::cell::{Cell, Ref, RefMut, UnsafeCell}; use std::cmp; use std::default::Default; use std::iter; @@ -125,7 +126,7 @@ pub struct Node { owner_doc: MutNullableDom<Document>, /// Rare node data. - rare_data: Box<NodeRareData>, + rare_data: DomRefCell<Option<Box<NodeRareData>>>, /// The live list of children return by .childNodes. child_list: MutNullableDom<NodeList>, @@ -430,6 +431,8 @@ impl<'a> Iterator for QuerySelectorIterator { } impl Node { + impl_rare_data!(NodeRareData); + pub fn teardown(&self) { self.style_and_layout_data.get().map(|d| self.dispose(d)); for kid in self.children() { @@ -450,14 +453,26 @@ impl Node { /// Return all registered mutation observers for this node. pub fn registered_mutation_observers(&self) -> RefMut<Vec<RegisteredObserver>> { - self.rare_data.mutation_observers.borrow_mut() + RefMut::map(self.rare_data_mut(), |rare_data| { + &mut rare_data.as_mut().unwrap().mutation_observers + }) + } + + /// Add a new mutation observer for a given node. + pub fn add_mutation_observer(&self, observer: RegisteredObserver) { + self.rare_data_mut() + .as_mut() + .unwrap() + .mutation_observers + .push(observer); } /// Removes the mutation observer for a given node. pub fn remove_mutation_observer(&self, observer: &MutationObserver) { - self.rare_data + self.rare_data_mut() + .as_mut() + .unwrap() .mutation_observers - .borrow_mut() .retain(|reg_obs| &*reg_obs.observer != observer) } @@ -930,11 +945,16 @@ impl Node { if let Some(ref shadow_root) = self.downcast::<ShadowRoot>() { return Some(DomRoot::from_ref(shadow_root)); } - self.rare_data.owner_shadow_root.get() + self.rare_data() + .as_ref() + .unwrap() + .owner_shadow_root + .as_ref() + .map(|sr| DomRoot::from_ref(&**sr)) } pub fn set_owner_shadow_root(&self, shadow_root: &ShadowRoot) { - self.rare_data.owner_shadow_root.set(Some(shadow_root)); + self.rare_data_mut().as_mut().unwrap().owner_shadow_root = Some(Dom::from_ref(shadow_root)); } pub fn is_in_html_doc(&self) -> bool { @@ -1266,9 +1286,12 @@ impl LayoutNodeHelpers for LayoutDom<Node> { #[allow(unsafe_code)] unsafe fn owner_shadow_root_for_layout(&self) -> Option<LayoutDom<ShadowRoot>> { (*self.unsafe_get()) - .rare_data + .rare_data_for_layout() + .as_ref() + .unwrap() .owner_shadow_root - .get_inner_as_layout() + .as_ref() + .map(|sr| sr.to_layout()) } #[inline] @@ -2274,12 +2297,12 @@ impl NodeMethods for Node { // https://dom.spec.whatwg.org/#dom-node-getrootnode fn GetRootNode(&self, options: &GetRootNodeOptions) -> DomRoot<Node> { if options.composed { - if let Some(shadow_root) = self.rare_data.owner_shadow_root.get() { + if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().owner_shadow_root { // shadow-including root. return shadow_root.Host().upcast::<Node>().GetRootNode(options); } } - if let Some(shadow_root) = self.rare_data.owner_shadow_root.get() { + if let Some(ref shadow_root) = self.rare_data().as_ref().unwrap().owner_shadow_root { DomRoot::from_ref(shadow_root.upcast::<Node>()) } else if self.is_in_doc() { DomRoot::from_ref(self.owner_doc().upcast::<Node>()) diff --git a/components/script/dom/raredata.rs b/components/script/dom/raredata.rs index 9ebf8e7d787..874db7b48ad 100644 --- a/components/script/dom/raredata.rs +++ b/components/script/dom/raredata.rs @@ -2,14 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::root::MutNullableDom; +use crate::dom::bindings::root::Dom; use crate::dom::customelementregistry::{ CustomElementDefinition, CustomElementReaction, CustomElementState, }; use crate::dom::mutationobserver::RegisteredObserver; use crate::dom::shadowroot::ShadowRoot; -use std::cell::Cell; use std::rc::Rc; #[derive(Default, JSTraceable, MallocSizeOf)] @@ -18,9 +16,9 @@ pub struct NodeRareData { /// The shadow root the node belongs to. /// This is None if the node is not in a shadow tree or /// if it is a ShadowRoot. - pub owner_shadow_root: MutNullableDom<ShadowRoot>, + pub owner_shadow_root: Option<Dom<ShadowRoot>>, /// Registered observers for this node. - pub mutation_observers: DomRefCell<Vec<RegisteredObserver>>, + pub mutation_observers: Vec<RegisteredObserver>, } #[derive(Default, JSTraceable, MallocSizeOf)] @@ -29,12 +27,12 @@ pub struct ElementRareData { /// https://dom.spec.whatwg.org/#dom-element-shadowroot /// XXX This is currently not exposed to web content. Only for /// internal use. - pub shadow_root: MutNullableDom<ShadowRoot>, + pub shadow_root: Option<Dom<ShadowRoot>>, /// <https://html.spec.whatwg.org/multipage/#custom-element-reaction-queue> - pub custom_element_reaction_queue: DomRefCell<Vec<CustomElementReaction>>, + pub custom_element_reaction_queue: Vec<CustomElementReaction>, /// <https://dom.spec.whatwg.org/#concept-element-custom-element-definition> #[ignore_malloc_size_of = "Rc"] - pub custom_element_definition: DomRefCell<Option<Rc<CustomElementDefinition>>>, + pub custom_element_definition: Option<Rc<CustomElementDefinition>>, /// <https://dom.spec.whatwg.org/#concept-element-custom-element-state> - pub custom_element_state: Cell<CustomElementState>, + pub custom_element_state: CustomElementState, } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index e8e5078c53a..0fa354fb139 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -421,11 +421,6 @@ impl<'ln> TNode for GeckoNode<'ln> { self.get_bool_flag(nsINode_BooleanFlag::IsInDocument) } - #[inline] - fn is_connected(&self) -> bool { - self.get_bool_flag(nsINode_BooleanFlag::IsConnected) - } - fn traversal_parent(&self) -> Option<GeckoElement<'ln>> { self.flattened_tree_parent().and_then(|n| n.as_element()) } diff --git a/components/style/stylesheet_set.rs b/components/style/stylesheet_set.rs index e668ba0d03d..1d803e5dd01 100644 --- a/components/style/stylesheet_set.rs +++ b/components/style/stylesheet_set.rs @@ -443,61 +443,61 @@ where /// documents, which is slightly annoying. macro_rules! sheet_set_methods { ($set_name:expr) => { - fn collect_invalidations_for( - &mut self, - device: Option<&Device>, - sheet: &S, - guard: &SharedRwLockReadGuard, - ) { - if let Some(device) = device { - self.invalidations - .collect_invalidations_for(device, sheet, guard); - } + fn collect_invalidations_for( + &mut self, + device: Option<&Device>, + sheet: &S, + guard: &SharedRwLockReadGuard, + ) { + if let Some(device) = device { + self.invalidations + .collect_invalidations_for(device, sheet, guard); } + } - /// Appends a new stylesheet to the current set. - /// - /// No device implies not computing invalidations. - pub fn append_stylesheet( - &mut self, - device: Option<&Device>, - sheet: S, - guard: &SharedRwLockReadGuard, - ) { - debug!(concat!($set_name, "::append_stylesheet")); - self.collect_invalidations_for(device, &sheet, guard); - let collection = self.collection_for(&sheet, guard); - collection.append(sheet); - } + /// Appends a new stylesheet to the current set. + /// + /// No device implies not computing invalidations. + pub fn append_stylesheet( + &mut self, + device: Option<&Device>, + sheet: S, + guard: &SharedRwLockReadGuard, + ) { + debug!(concat!($set_name, "::append_stylesheet")); + self.collect_invalidations_for(device, &sheet, guard); + let collection = self.collection_for(&sheet, guard); + collection.append(sheet); + } - /// Insert a given stylesheet before another stylesheet in the document. - pub fn insert_stylesheet_before( - &mut self, - device: Option<&Device>, - sheet: S, - before_sheet: S, - guard: &SharedRwLockReadGuard, - ) { - debug!(concat!($set_name, "::insert_stylesheet_before")); - self.collect_invalidations_for(device, &sheet, guard); - - let collection = self.collection_for(&sheet, guard); - collection.insert_before(sheet, &before_sheet); - } + /// Insert a given stylesheet before another stylesheet in the document. + pub fn insert_stylesheet_before( + &mut self, + device: Option<&Device>, + sheet: S, + before_sheet: S, + guard: &SharedRwLockReadGuard, + ) { + debug!(concat!($set_name, "::insert_stylesheet_before")); + self.collect_invalidations_for(device, &sheet, guard); + + let collection = self.collection_for(&sheet, guard); + collection.insert_before(sheet, &before_sheet); + } - /// Remove a given stylesheet from the set. - pub fn remove_stylesheet( - &mut self, - device: Option<&Device>, - sheet: S, - guard: &SharedRwLockReadGuard, - ) { - debug!(concat!($set_name, "::remove_stylesheet")); - self.collect_invalidations_for(device, &sheet, guard); - - let collection = self.collection_for(&sheet, guard); - collection.remove(&sheet) - } + /// Remove a given stylesheet from the set. + pub fn remove_stylesheet( + &mut self, + device: Option<&Device>, + sheet: S, + guard: &SharedRwLockReadGuard, + ) { + debug!(concat!($set_name, "::remove_stylesheet")); + self.collect_invalidations_for(device, &sheet, guard); + + let collection = self.collection_for(&sheet, guard); + collection.remove(&sheet) + } }; } diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs index 8496506ef9f..1c5bcace945 100644 --- a/tests/unit/script/size_of.rs +++ b/tests/unit/script/size_of.rs @@ -30,11 +30,10 @@ macro_rules! sizeof_checker ( // Update the sizes here sizeof_checker!(size_event_target, EventTarget, 56); -sizeof_checker!(size_node, Node, 176); -sizeof_checker!(size_element, Element, 376); -sizeof_checker!(size_htmlelement, HTMLElement, 392); -sizeof_checker!(size_div, HTMLDivElement, 392); -sizeof_checker!(size_span, HTMLSpanElement, 392); -sizeof_checker!(size_text, Text, 208); -sizeof_checker!(size_characterdata, CharacterData, 208); - +sizeof_checker!(size_node, Node, 184); +sizeof_checker!(size_element, Element, 392); +sizeof_checker!(size_htmlelement, HTMLElement, 408); +sizeof_checker!(size_div, HTMLDivElement, 408); +sizeof_checker!(size_span, HTMLSpanElement, 408); +sizeof_checker!(size_text, Text, 216); +sizeof_checker!(size_characterdata, CharacterData, 216); |