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 <jo.steven.novaryo@huawei.com>
This commit is contained in:
Jo Steven Novaryo 2025-08-01 13:17:39 +08:00 committed by GitHub
parent 09f0e20e29
commit a8886c1222
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 8 deletions

View file

@ -1362,7 +1362,7 @@ impl<'a> BuilderForBoxFragment<'a> {
fn build_collapsed_table_borders(&mut self, builder: &mut DisplayListBuilder) { fn build_collapsed_table_borders(&mut self, builder: &mut DisplayListBuilder) {
let Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(table_info)) = let Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(table_info)) =
&self.fragment.specific_layout_info self.fragment.specific_layout_info()
else { else {
return; return;
}; };

View file

@ -1334,7 +1334,7 @@ impl BoxFragment {
} }
if matches!(&fragment, Fragment::Box(box_fragment) if matches!( if matches!(&fragment, Fragment::Box(box_fragment) if matches!(
box_fragment.borrow().specific_layout_info, box_fragment.borrow().specific_layout_info(),
Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_)) Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_))
)) { )) {
stacking_context stacking_context

View file

@ -68,6 +68,24 @@ pub(crate) struct BlockLevelLayoutInfo {
pub block_margins_collapsed_with_children: CollapsedBlockMargins, 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<SpecificLayoutInfo>,
}
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<SpecificLayoutInfo>) -> Option<Box<Self>> {
specific_layout_info.map(|info| {
Box::new(BoxFragmentRareData {
specific_layout_info: Some(info),
})
})
}
}
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
pub(crate) struct BoxFragment { pub(crate) struct BoxFragment {
pub base: BaseFragment, pub base: BaseFragment,
@ -105,8 +123,8 @@ pub(crate) struct BoxFragment {
pub background_mode: BackgroundMode, pub background_mode: BackgroundMode,
/// Additional information of from layout that could be used by Javascripts and devtools. /// Rare data that not all kinds of [`BoxFragment`] would have.
pub specific_layout_info: Option<SpecificLayoutInfo>, pub rare_data: Option<Box<BoxFragmentRareData>>,
/// Additional information for block-level boxes. /// Additional information for block-level boxes.
pub block_level_layout_info: Option<Box<BlockLevelLayoutInfo>>, pub block_level_layout_info: Option<Box<BlockLevelLayoutInfo>>,
@ -130,6 +148,8 @@ impl BoxFragment {
margin: PhysicalSides<Au>, margin: PhysicalSides<Au>,
specific_layout_info: Option<SpecificLayoutInfo>, specific_layout_info: Option<SpecificLayoutInfo>,
) -> BoxFragment { ) -> BoxFragment {
let rare_data = BoxFragmentRareData::try_boxed_from(specific_layout_info);
BoxFragment { BoxFragment {
base: base_fragment_info.into(), base: base_fragment_info.into(),
style, style,
@ -143,7 +163,7 @@ impl BoxFragment {
scrollable_overflow: None, scrollable_overflow: None,
resolved_sticky_insets: AtomicRefCell::default(), resolved_sticky_insets: AtomicRefCell::default(),
background_mode: BackgroundMode::Normal, background_mode: BackgroundMode::Normal,
specific_layout_info, rare_data,
block_level_layout_info: None, block_level_layout_info: None,
spatial_tree_node: AtomicRefCell::default(), spatial_tree_node: AtomicRefCell::default(),
} }
@ -198,6 +218,10 @@ impl BoxFragment {
self.background_mode = BackgroundMode::None; 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( pub fn with_block_level_layout_info(
mut self, mut self,
block_margins_collapsed_with_children: CollapsedBlockMargins, block_margins_collapsed_with_children: CollapsedBlockMargins,
@ -512,13 +536,13 @@ impl BoxFragment {
/// <https://www.w3.org/TR/css-tables-3/#table-wrapper-box> /// <https://www.w3.org/TR/css-tables-3/#table-wrapper-box>
pub(crate) fn is_table_wrapper(&self) -> bool { pub(crate) fn is_table_wrapper(&self) -> bool {
matches!( matches!(
self.specific_layout_info, self.specific_layout_info(),
Some(SpecificLayoutInfo::TableWrapper) Some(SpecificLayoutInfo::TableWrapper)
) )
} }
pub(crate) fn has_collapsed_borders(&self) -> bool { pub(crate) fn has_collapsed_borders(&self) -> bool {
match &self.specific_layout_info { match self.specific_layout_info() {
Some(SpecificLayoutInfo::TableCellWithCollapsedBorders) => true, Some(SpecificLayoutInfo::TableCellWithCollapsedBorders) => true,
Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_)) => true, Some(SpecificLayoutInfo::TableGridWithCollapsedBorders(_)) => true,
Some(SpecificLayoutInfo::TableWrapper) => { Some(SpecificLayoutInfo::TableWrapper) => {

View file

@ -257,7 +257,7 @@ pub fn process_resolved_style_request(
let content_rect = box_fragment.content_rect; let content_rect = box_fragment.content_rect;
let margins = box_fragment.margin; let margins = box_fragment.margin;
let padding = box_fragment.padding; 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) (content_rect, margins, padding, specific_layout_info)
}, },
Fragment::Positioning(positioning_fragment) => { Fragment::Positioning(positioning_fragment) => {