From a8886c122225b1e50232c745ec5c738bc835d9d3 Mon Sep 17 00:00:00 2001 From: Jo Steven Novaryo <65610990+stevennovaryo@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:17:39 +0800 Subject: [PATCH] layout: Add BoxFragment rare data (#38325) Introduce `BoxFragmentRareData`, rare data for `BoxFragment`, which would store the specific data that is relevant to several fragments. This would reduce the `BoxFragment` size to 256 from 264 and add 8 bytes for fragment that have rare data (due to the additional pointer to the rare data). Testing: Existing WPT coverage Signed-off-by: Jo Steven Novaryo --- components/layout/display_list/mod.rs | 2 +- .../layout/display_list/stacking_context.rs | 2 +- .../layout/fragment_tree/box_fragment.rs | 34 ++++++++++++++++--- components/layout/query.rs | 2 +- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/components/layout/display_list/mod.rs b/components/layout/display_list/mod.rs index e345a65a7e1..83c249426ce 100644 --- a/components/layout/display_list/mod.rs +++ b/components/layout/display_list/mod.rs @@ -1362,7 +1362,7 @@ impl<'a> BuilderForBoxFragment<'a> { fn build_collapsed_table_borders(&mut self, builder: &mut DisplayListBuilder) { let Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(table_info)) = - &self.fragment.specific_layout_info + self.fragment.specific_layout_info() else { return; }; diff --git a/components/layout/display_list/stacking_context.rs b/components/layout/display_list/stacking_context.rs index e2e3eb6c671..9dda6db2852 100644 --- a/components/layout/display_list/stacking_context.rs +++ b/components/layout/display_list/stacking_context.rs @@ -1334,7 +1334,7 @@ impl BoxFragment { } if matches!(&fragment, Fragment::Box(box_fragment) if matches!( - box_fragment.borrow().specific_layout_info, + box_fragment.borrow().specific_layout_info(), Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_)) )) { stacking_context diff --git a/components/layout/fragment_tree/box_fragment.rs b/components/layout/fragment_tree/box_fragment.rs index b11126d80ad..12b0206f26a 100644 --- a/components/layout/fragment_tree/box_fragment.rs +++ b/components/layout/fragment_tree/box_fragment.rs @@ -68,6 +68,24 @@ pub(crate) struct BlockLevelLayoutInfo { pub block_margins_collapsed_with_children: CollapsedBlockMargins, } +#[derive(MallocSizeOf)] +pub(crate) struct BoxFragmentRareData { + /// Information that is specific to a layout system (e.g., grid, table, etc.). + pub specific_layout_info: Option, +} + +impl BoxFragmentRareData { + /// Create a new rare data based on information given to the fragment. Ideally, We should + /// avoid creating rare data as much as possible to reduce the memory cost. + fn try_boxed_from(specific_layout_info: Option) -> Option> { + specific_layout_info.map(|info| { + Box::new(BoxFragmentRareData { + specific_layout_info: Some(info), + }) + }) + } +} + #[derive(MallocSizeOf)] pub(crate) struct BoxFragment { pub base: BaseFragment, @@ -105,8 +123,8 @@ pub(crate) struct BoxFragment { pub background_mode: BackgroundMode, - /// Additional information of from layout that could be used by Javascripts and devtools. - pub specific_layout_info: Option, + /// Rare data that not all kinds of [`BoxFragment`] would have. + pub rare_data: Option>, /// Additional information for block-level boxes. pub block_level_layout_info: Option>, @@ -130,6 +148,8 @@ impl BoxFragment { margin: PhysicalSides, specific_layout_info: Option, ) -> BoxFragment { + let rare_data = BoxFragmentRareData::try_boxed_from(specific_layout_info); + BoxFragment { base: base_fragment_info.into(), style, @@ -143,7 +163,7 @@ impl BoxFragment { scrollable_overflow: None, resolved_sticky_insets: AtomicRefCell::default(), background_mode: BackgroundMode::Normal, - specific_layout_info, + rare_data, block_level_layout_info: None, spatial_tree_node: AtomicRefCell::default(), } @@ -198,6 +218,10 @@ impl BoxFragment { self.background_mode = BackgroundMode::None; } + pub fn specific_layout_info(&self) -> Option<&SpecificLayoutInfo> { + self.rare_data.as_ref()?.specific_layout_info.as_ref() + } + pub fn with_block_level_layout_info( mut self, block_margins_collapsed_with_children: CollapsedBlockMargins, @@ -512,13 +536,13 @@ impl BoxFragment { /// pub(crate) fn is_table_wrapper(&self) -> bool { matches!( - self.specific_layout_info, + self.specific_layout_info(), Some(SpecificLayoutInfo::TableWrapper) ) } pub(crate) fn has_collapsed_borders(&self) -> bool { - match &self.specific_layout_info { + match self.specific_layout_info() { Some(SpecificLayoutInfo::TableCellWithCollapsedBorders) => true, Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_)) => true, Some(SpecificLayoutInfo::TableWrapper) => { diff --git a/components/layout/query.rs b/components/layout/query.rs index 28d710b7ef8..64364e9551e 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -257,7 +257,7 @@ pub fn process_resolved_style_request( let content_rect = box_fragment.content_rect; let margins = box_fragment.margin; let padding = box_fragment.padding; - let specific_layout_info = box_fragment.specific_layout_info.clone(); + let specific_layout_info = box_fragment.specific_layout_info().cloned(); (content_rect, margins, padding, specific_layout_info) }, Fragment::Positioning(positioning_fragment) => {