tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 04b013b47241e496684d5f7eb4368c0898166d87
parent cfbe87ee22857758128bf11690eb33f7c6662a18
Author: Denis Palmeiro <dpalmeiro@mozilla.com>
Date:   Tue, 30 Dec 2025 15:43:09 +0000

Bug 2006172: Compare style attributes by value instead of just pointer identity when style sharing.  r=emilio,firefox-style-system-reviewers

Inline styles set by JS (i.e. element.style.display = "block") allocate new
PropertyDeclarationBlock pointers causing identical inline styles to have
different pointers.

Differential Revision: https://phabricator.services.mozilla.com/D277605

Diffstat:
Mservo/components/style/properties/declaration_block.rs | 9+++++++++
Mservo/components/style/sharing/checks.rs | 13+++++++++++--
Mservo/components/style/sharing/mod.rs | 2+-
3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/servo/components/style/properties/declaration_block.rs b/servo/components/style/properties/declaration_block.rs @@ -261,6 +261,15 @@ pub struct PropertyDeclarationBlock { property_ids: PropertyDeclarationIdSet, } +impl PartialEq for PropertyDeclarationBlock { + fn eq(&self, other: &Self) -> bool { + // property_ids must be equal if declarations are equal, so we don't + // need to compare them explicitly. + self.declarations == other.declarations + && self.declarations_importance == other.declarations_importance + } +} + /// Iterator over `(PropertyDeclaration, Importance)` pairs. pub struct DeclarationImportanceIterator<'a> { iter: Zip<Iter<'a, PropertyDeclaration>, smallbitvec::Iter<'a>>, diff --git a/servo/components/style/sharing/checks.rs b/servo/components/style/sharing/checks.rs @@ -53,10 +53,13 @@ where true } -/// Whether two elements have the same same style attribute (by pointer identity). +/// Whether two elements have the same style attribute. +/// +/// First checks pointer identity (fast path), then falls back to value comparison. pub fn have_same_style_attribute<E>( target: &mut StyleSharingTarget<E>, candidate: &mut StyleSharingCandidate<E>, + shared_context: &SharedStyleContext, ) -> bool where E: TElement, @@ -64,7 +67,13 @@ where match (target.style_attribute(), candidate.style_attribute()) { (None, None) => true, (Some(_), None) | (None, Some(_)) => false, - (Some(a), Some(b)) => &*a as *const _ == &*b as *const _, + (Some(a), Some(b)) => { + if std::ptr::eq(&*a, &*b) { + return true; + } + let guard = shared_context.guards.author; + *a.read_with(guard) == *b.read_with(guard) + }, } } diff --git a/servo/components/style/sharing/mod.rs b/servo/components/style/sharing/mod.rs @@ -847,7 +847,7 @@ impl<E: TElement> StyleSharingCache<E> { return None; } - if !checks::have_same_style_attribute(target, candidate) { + if !checks::have_same_style_attribute(target, candidate, shared_context) { trace!("Miss: Style Attr"); return None; }