dom: move node ranges to raredata (#35554)

Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
webbeef 2025-02-21 10:41:25 -08:00 committed by GitHub
parent 57ed444498
commit e883eaa322
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 28 deletions

View file

@ -158,12 +158,6 @@ pub struct Node {
/// The maximum version of any inclusive descendant of this node. /// The maximum version of any inclusive descendant of this node.
inclusive_descendants_version: Cell<u64>, inclusive_descendants_version: Cell<u64>,
/// 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 /// 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. /// passes and is used to lay out this node and populate layout data.
#[no_trace] #[no_trace]
@ -674,8 +668,15 @@ impl Node {
self.children_count.get() self.children_count.get()
} }
pub(crate) fn ranges(&self) -> &WeakRangeVec { pub(crate) fn ranges(&self) -> RefMut<WeakRangeVec> {
&self.ranges 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] #[inline]
@ -1971,7 +1972,6 @@ impl Node {
children_count: Cell::new(0u32), children_count: Cell::new(0u32),
flags: Cell::new(flags), flags: Cell::new(flags),
inclusive_descendants_version: Cell::new(0), inclusive_descendants_version: Cell::new(0),
ranges: WeakRangeVec::new(),
style_data: Default::default(), style_data: Default::default(),
layout_data: Default::default(), layout_data: Default::default(),
} }
@ -2201,10 +2201,10 @@ impl Node {
}; };
// Step 2. // Step 2.
if let Some(child) = child { if let Some(child) = child {
if !parent.ranges.is_empty() { if !parent.ranges_is_empty() {
let index = child.index(); let index = child.index();
// Steps 2.1-2. // Steps 2.1-2.
parent.ranges.increase_above(parent, index, count); parent.ranges().increase_above(parent, index, count);
} }
} }
rooted_vec!(let mut new_nodes); rooted_vec!(let mut new_nodes);
@ -2419,14 +2419,14 @@ impl Node {
.GetParentNode() .GetParentNode()
.is_some_and(|node_parent| &*node_parent == parent)); .is_some_and(|node_parent| &*node_parent == parent));
let cached_index = { let cached_index = {
if parent.ranges.is_empty() { if parent.ranges_is_empty() {
None None
} else { } else {
// Step 1. // Step 1.
let index = node.index(); let index = node.index();
// Steps 2-3 are handled in Node::unbind_from_tree. // Steps 2-3 are handled in Node::unbind_from_tree.
// Steps 4-5. // 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 // Parent had ranges, we needed the index, let's keep track of
// it to avoid computing it for other ranges when calling // it to avoid computing it for other ranges when calling
// unbind_from_tree recursively. // unbind_from_tree recursively.
@ -3204,9 +3204,9 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
{ {
let (index, sibling) = children.next().unwrap(); let (index, sibling) = children.next().unwrap();
sibling sibling
.ranges .ranges()
.drain_to_preceding_text_sibling(&sibling, &node, length); .drain_to_preceding_text_sibling(&sibling, &node, length);
self.ranges self.ranges()
.move_to_text_child_at(self, index as u32, &node, length); .move_to_text_child_at(self, index as u32, &node, length);
let sibling_cdata = sibling.downcast::<CharacterData>().unwrap(); let sibling_cdata = sibling.downcast::<CharacterData>().unwrap();
length += sibling_cdata.Length(); length += sibling_cdata.Length();
@ -3618,7 +3618,9 @@ impl VirtualMethods for Node {
/// <https://dom.spec.whatwg.org/#concept-node-remove> /// <https://dom.spec.whatwg.org/#concept-node-remove>
fn unbind_from_tree(&self, context: &UnbindContext) { fn unbind_from_tree(&self, context: &UnbindContext) {
self.super_type().unwrap().unbind_from_tree(context); 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);
}
} }
} }

View file

@ -1121,11 +1121,6 @@ impl Default for WeakRangeVec {
#[allow(unsafe_code)] #[allow(unsafe_code)]
impl WeakRangeVec { impl WeakRangeVec {
/// Create a new vector of weak references.
pub(crate) fn new() -> Self {
Self::default()
}
/// Whether that vector of ranges is empty. /// Whether that vector of ranges is empty.
pub(crate) fn is_empty(&self) -> bool { pub(crate) fn is_empty(&self) -> bool {
unsafe { (*self.cell.get()).is_empty() } unsafe { (*self.cell.get()).is_empty() }

View file

@ -16,6 +16,7 @@ use crate::dom::htmlslotelement::SlottableData;
use crate::dom::intersectionobserver::IntersectionObserverRegistration; use crate::dom::intersectionobserver::IntersectionObserverRegistration;
use crate::dom::mutationobserver::RegisteredObserver; use crate::dom::mutationobserver::RegisteredObserver;
use crate::dom::node::UniqueId; use crate::dom::node::UniqueId;
use crate::dom::range::WeakRangeVec;
use crate::dom::shadowroot::ShadowRoot; use crate::dom::shadowroot::ShadowRoot;
use crate::dom::window::LayoutValue; use crate::dom::window::LayoutValue;
@ -35,6 +36,12 @@ pub(crate) struct NodeRareData {
pub(crate) unique_id: Option<UniqueId>, pub(crate) unique_id: Option<UniqueId>,
pub(crate) slottable_data: SlottableData, 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)] #[derive(Default, JSTraceable, MallocSizeOf)]

View file

@ -30,10 +30,10 @@ macro_rules! sizeof_checker (
// Update the sizes here // Update the sizes here
sizeof_checker!(size_event_target, EventTarget, 48); sizeof_checker!(size_event_target, EventTarget, 48);
sizeof_checker!(size_node, Node, 200); sizeof_checker!(size_node, Node, 176);
sizeof_checker!(size_element, Element, 376); sizeof_checker!(size_element, Element, 352);
sizeof_checker!(size_htmlelement, HTMLElement, 392); sizeof_checker!(size_htmlelement, HTMLElement, 368);
sizeof_checker!(size_div, HTMLDivElement, 392); sizeof_checker!(size_div, HTMLDivElement, 368);
sizeof_checker!(size_span, HTMLSpanElement, 392); sizeof_checker!(size_span, HTMLSpanElement, 368);
sizeof_checker!(size_text, Text, 232); sizeof_checker!(size_text, Text, 208);
sizeof_checker!(size_characterdata, CharacterData, 232); sizeof_checker!(size_characterdata, CharacterData, 208);