From e883eaa322e5a54099cb31810612863248c41fc3 Mon Sep 17 00:00:00 2001 From: webbeef Date: Fri, 21 Feb 2025 10:41:25 -0800 Subject: [PATCH] dom: move node ranges to raredata (#35554) Signed-off-by: webbeef --- components/script/dom/node.rs | 34 ++++++++++++++++--------------- components/script/dom/range.rs | 5 ----- components/script/dom/raredata.rs | 7 +++++++ tests/unit/script/size_of.rs | 14 ++++++------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 320a4b1b02e..00125588433 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -158,12 +158,6 @@ pub struct Node { /// The maximum version of any inclusive descendant of this node. inclusive_descendants_version: Cell, - /// A vector of weak references to Range instances of which the start - /// or end containers are this node. No range should ever be found - /// twice in this vector, even if both the start and end containers - /// are this node. - ranges: WeakRangeVec, - /// Style data for this node. This is accessed and mutated by style /// passes and is used to lay out this node and populate layout data. #[no_trace] @@ -674,8 +668,15 @@ impl Node { self.children_count.get() } - pub(crate) fn ranges(&self) -> &WeakRangeVec { - &self.ranges + pub(crate) fn ranges(&self) -> RefMut { + RefMut::map(self.ensure_rare_data(), |rare_data| &mut rare_data.ranges) + } + + pub(crate) fn ranges_is_empty(&self) -> bool { + match self.rare_data().as_ref() { + Some(data) => data.ranges.is_empty(), + None => false, + } } #[inline] @@ -1971,7 +1972,6 @@ impl Node { children_count: Cell::new(0u32), flags: Cell::new(flags), inclusive_descendants_version: Cell::new(0), - ranges: WeakRangeVec::new(), style_data: Default::default(), layout_data: Default::default(), } @@ -2201,10 +2201,10 @@ impl Node { }; // Step 2. if let Some(child) = child { - if !parent.ranges.is_empty() { + if !parent.ranges_is_empty() { let index = child.index(); // Steps 2.1-2. - parent.ranges.increase_above(parent, index, count); + parent.ranges().increase_above(parent, index, count); } } rooted_vec!(let mut new_nodes); @@ -2419,14 +2419,14 @@ impl Node { .GetParentNode() .is_some_and(|node_parent| &*node_parent == parent)); let cached_index = { - if parent.ranges.is_empty() { + if parent.ranges_is_empty() { None } else { // Step 1. let index = node.index(); // Steps 2-3 are handled in Node::unbind_from_tree. // Steps 4-5. - parent.ranges.decrease_above(parent, index, 1); + parent.ranges().decrease_above(parent, index, 1); // Parent had ranges, we needed the index, let's keep track of // it to avoid computing it for other ranges when calling // unbind_from_tree recursively. @@ -3204,9 +3204,9 @@ impl NodeMethods for Node { { let (index, sibling) = children.next().unwrap(); sibling - .ranges + .ranges() .drain_to_preceding_text_sibling(&sibling, &node, length); - self.ranges + self.ranges() .move_to_text_child_at(self, index as u32, &node, length); let sibling_cdata = sibling.downcast::().unwrap(); length += sibling_cdata.Length(); @@ -3618,7 +3618,9 @@ impl VirtualMethods for Node { /// fn unbind_from_tree(&self, context: &UnbindContext) { self.super_type().unwrap().unbind_from_tree(context); - self.ranges.drain_to_parent(context, self); + if !self.ranges_is_empty() { + self.ranges().drain_to_parent(context, self); + } } } diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index 83a1ef533b4..a4db9944dfd 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -1121,11 +1121,6 @@ impl Default for WeakRangeVec { #[allow(unsafe_code)] impl WeakRangeVec { - /// Create a new vector of weak references. - pub(crate) fn new() -> Self { - Self::default() - } - /// Whether that vector of ranges is empty. pub(crate) fn is_empty(&self) -> bool { unsafe { (*self.cell.get()).is_empty() } diff --git a/components/script/dom/raredata.rs b/components/script/dom/raredata.rs index 9e866bf5f43..943319177c4 100644 --- a/components/script/dom/raredata.rs +++ b/components/script/dom/raredata.rs @@ -16,6 +16,7 @@ use crate::dom::htmlslotelement::SlottableData; use crate::dom::intersectionobserver::IntersectionObserverRegistration; use crate::dom::mutationobserver::RegisteredObserver; use crate::dom::node::UniqueId; +use crate::dom::range::WeakRangeVec; use crate::dom::shadowroot::ShadowRoot; use crate::dom::window::LayoutValue; @@ -35,6 +36,12 @@ pub(crate) struct NodeRareData { pub(crate) unique_id: Option, pub(crate) slottable_data: SlottableData, + + /// A vector of weak references to Range instances of which the start + /// or end containers are this node. No range should ever be found + /// twice in this vector, even if both the start and end containers + /// are this node. + pub(crate) ranges: WeakRangeVec, } #[derive(Default, JSTraceable, MallocSizeOf)] diff --git a/tests/unit/script/size_of.rs b/tests/unit/script/size_of.rs index d39f6ebacd7..6231f2e8a26 100644 --- a/tests/unit/script/size_of.rs +++ b/tests/unit/script/size_of.rs @@ -30,10 +30,10 @@ macro_rules! sizeof_checker ( // Update the sizes here sizeof_checker!(size_event_target, EventTarget, 48); -sizeof_checker!(size_node, Node, 200); -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, 232); -sizeof_checker!(size_characterdata, CharacterData, 232); +sizeof_checker!(size_node, Node, 176); +sizeof_checker!(size_element, Element, 352); +sizeof_checker!(size_htmlelement, HTMLElement, 368); +sizeof_checker!(size_div, HTMLDivElement, 368); +sizeof_checker!(size_span, HTMLSpanElement, 368); +sizeof_checker!(size_text, Text, 208); +sizeof_checker!(size_characterdata, CharacterData, 208);