From 74519cc1a7bdc5ff31921fc2e59b3cb697774efa Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 17 Jul 2017 11:41:56 -0700 Subject: [PATCH] stylo: Make Servo Arc types use ptr to T instead of ptr to ArcInner --- components/servo_arc/lib.rs | 104 +++++++++++++++++- components/style/dom.rs | 6 +- components/style/gecko/restyle_damage.rs | 2 +- components/style/gecko/wrapper.rs | 42 ++++--- .../style/gecko_bindings/sugar/ownership.rs | 54 +++++---- .../style/gecko_bindings/sugar/refptr.rs | 2 +- components/style/matching.rs | 6 +- components/style/rule_tree/mod.rs | 10 +- components/style/sharing/checks.rs | 2 +- components/style/stylesheets/rule_list.rs | 4 +- components/style/stylist.rs | 10 +- ports/geckolib/glue.rs | 42 +++---- 12 files changed, 203 insertions(+), 81 deletions(-) diff --git a/components/servo_arc/lib.rs b/components/servo_arc/lib.rs index 6d031802961..b1f4f277a49 100644 --- a/components/servo_arc/lib.rs +++ b/components/servo_arc/lib.rs @@ -194,6 +194,30 @@ impl Arc { p: NonZeroPtrMut::new(ptr as *mut ArcInner), } } + + /// Produce a pointer to the data that can be converted back + /// to an arc + pub fn borrow_arc<'a>(&'a self) -> ArcBorrow<'a, T> { + ArcBorrow(&**self) + } + /// Temporarily converts |self| into a bonafide RawOffsetArc and exposes it to the + /// provided callback. The refcount is not modified. + #[inline(always)] + pub fn with_raw_offset_arc(&self, f: F) -> U + where F: FnOnce(&RawOffsetArc) -> U + { + // Synthesize transient Arc, which never touches the refcount of the ArcInner. + let transient = unsafe { NoDrop::new(Arc::into_raw_offset(ptr::read(self))) }; + + // Expose the transient Arc to the callback, which may clone it if it wants. + let result = f(&transient); + + // Forget the transient Arc to leave the refcount untouched. + mem::forget(transient); + + // Forward the result. + result + } } impl Arc { @@ -717,6 +741,7 @@ impl Eq for ThinArc {} /// This means that this is a direct pointer to /// its contained data (and can be read from by both C++ and Rust), /// but we can also convert it to a "regular" Arc by removing the offset +#[derive(Eq)] pub struct RawOffsetArc { ptr: NonZeroPtrMut, } @@ -733,7 +758,7 @@ impl Deref for RawOffsetArc { impl Clone for RawOffsetArc { fn clone(&self) -> Self { - RawOffsetArc::with_arc(self, |a| Arc::into_raw_offset(a.clone())) + Arc::into_raw_offset(self.clone_arc()) } } @@ -750,6 +775,16 @@ impl fmt::Debug for RawOffsetArc { } } +impl PartialEq for RawOffsetArc { + fn eq(&self, other: &RawOffsetArc) -> bool { + *(*self) == *(*other) + } + + fn ne(&self, other: &RawOffsetArc) -> bool { + *(*self) != *(*other) + } +} + impl RawOffsetArc { /// Temporarily converts |self| into a bonafide Arc and exposes it to the /// provided callback. The refcount is not modified. @@ -789,6 +824,17 @@ impl RawOffsetArc { &mut *ret } } + + /// Clone it as an Arc + pub fn clone_arc(&self) -> Arc { + RawOffsetArc::with_arc(self, |a| a.clone()) + } + + /// Produce a pointer to the data that can be converted back + /// to an arc + pub fn borrow_arc<'a>(&'a self) -> ArcBorrow<'a, T> { + ArcBorrow(&**self) + } } impl Arc { @@ -811,6 +857,62 @@ impl Arc { } } +/// A "borrowed Arc". This is a pointer to +/// a T that is known to have been allocated within an +/// Arc. +/// +/// This is equivalent in guarantees to `&Arc`, however it is +/// a bit more flexible. To obtain an `&Arc` you must have +/// an Arc instance somewhere pinned down until we're done with it. +/// +/// However, Gecko hands us refcounted things as pointers to T directly, +/// so we have to conjure up a temporary Arc on the stack each time. The +/// same happens for when the object is managed by a RawOffsetArc. +/// +/// ArcBorrow lets us deal with borrows of known-refcounted objects +/// without needing to worry about how they're actually stored. +#[derive(PartialEq, Eq)] +pub struct ArcBorrow<'a, T: 'a>(&'a T); + +impl<'a, T> Copy for ArcBorrow<'a, T> {} +impl<'a, T> Clone for ArcBorrow<'a, T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> ArcBorrow<'a, T> { + pub fn clone_arc(&self) -> Arc { + let arc = unsafe { Arc::from_raw(self.0) }; + // addref it! + mem::forget(arc.clone()); + arc + } + + pub fn with_arc(&self, f: F) -> U where F: FnOnce(&Arc) -> U, T: 'static { + // Synthesize transient Arc, which never touches the refcount. + let transient = unsafe { NoDrop::new(Arc::from_raw(self.0)) }; + + // Expose the transient Arc to the callback, which may clone it if it wants. + let result = f(&transient); + + // Forget the transient Arc to leave the refcount untouched. + // XXXManishearth this can be removed when unions stabilize, + // since then NoDrop becomes zero overhead + mem::forget(transient); + + // Forward the result. + result + } +} + +impl<'a, T> Deref for ArcBorrow<'a, T> { + type Target = T; + fn deref(&self) -> &T { + &*self.0 + } +} + #[cfg(test)] mod tests { use std::clone::Clone; diff --git a/components/style/dom.rs b/components/style/dom.rs index 8a3e9e7643e..f9173fa4f32 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -30,7 +30,7 @@ use std::fmt; use std::fmt::Debug; use std::hash::Hash; use std::ops::Deref; -use stylearc::Arc; +use stylearc::{Arc, ArcBorrow}; use stylist::Stylist; use thread_state; @@ -360,7 +360,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + } /// Get this element's style attribute. - fn style_attribute(&self) -> Option<&Arc>>; + fn style_attribute(&self) -> Option>>; /// Unset the style attribute's dirty bit. /// Servo doesn't need to manage ditry bit for style attribute. @@ -368,7 +368,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + } /// Get this element's SMIL override declarations. - fn get_smil_override(&self) -> Option<&Arc>> { + fn get_smil_override(&self) -> Option>> { None } diff --git a/components/style/gecko/restyle_damage.rs b/components/style/gecko/restyle_damage.rs index e9be48644ca..a4a8fc1704a 100644 --- a/components/style/gecko/restyle_damage.rs +++ b/components/style/gecko/restyle_damage.rs @@ -56,7 +56,7 @@ impl GeckoRestyleDamage { let mut any_style_changed: bool = false; let hint = unsafe { bindings::Gecko_CalcStyleDifference(context, - new_style.as_borrowed_opt().unwrap(), + new_style.as_borrowed(), &mut any_style_changed) }; let change = if any_style_changed { StyleChange::Changed } else { StyleChange::Unchanged }; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 75044c4080b..5fc618fee6c 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -64,7 +64,7 @@ use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS; use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme; -use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI}; +use gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasSimpleFFI}; use logical_geometry::WritingMode; use media_queries::Device; use properties::{ComputedValues, parse_style_attribute}; @@ -88,7 +88,7 @@ use std::mem; use std::ops::DerefMut; use std::ptr; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; -use stylearc::Arc; +use stylearc::{Arc, ArcBorrow, RawOffsetArc}; use stylesheets::UrlExtraData; use stylist::Stylist; @@ -860,13 +860,15 @@ impl<'le> TElement for GeckoElement<'le> { device.pres_context().mDocument.raw::() } - fn style_attribute(&self) -> Option<&Arc>> { + fn style_attribute(&self) -> Option>> { if !self.may_have_style_attribute() { return None; } let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) }; - declarations.map_or(None, |s| s.as_arc_opt()) + let declarations: Option<&RawOffsetArc>> + = declarations.and_then(|s| s.as_arc_opt()); + declarations.map(|s| s.borrow_arc()) } fn unset_dirty_style_attribute(&self) { @@ -877,9 +879,11 @@ impl<'le> TElement for GeckoElement<'le> { unsafe { Gecko_UnsetDirtyStyleAttr(self.0) }; } - fn get_smil_override(&self) -> Option<&Arc>> { + fn get_smil_override(&self) -> Option>> { let declarations = unsafe { Gecko_GetSMILOverrideDeclarationBlock(self.0) }; - declarations.map(|s| s.as_arc_opt()).unwrap_or(None) + let declarations: Option<&RawOffsetArc>> + = declarations.and_then(|s| s.as_arc_opt()); + declarations.map(|s| s.borrow_arc()) } fn get_animation_rule_by_cascade(&self, cascade_level: ServoCascadeLevel) @@ -1098,9 +1102,9 @@ impl<'le> TElement for GeckoElement<'le> { let computed_values = computed_data.as_ref().map(|d| d.styles.primary()); let computed_values_opt = - computed_values.map(|v| *HasArcFFI::arc_as_borrowed(v)); + computed_values.map(|v| v.as_borrowed()); let before_change_values = - before_change_style.as_ref().map(|v| *HasArcFFI::arc_as_borrowed(v)); + before_change_style.as_ref().map(|v| v.as_borrowed()); unsafe { Gecko_UpdateAnimations(self.0, before_change_values, @@ -1182,7 +1186,7 @@ impl<'le> TElement for GeckoElement<'le> { }; let end_value = AnimationValue::arc_from_borrowed(&raw_end_value); debug_assert!(end_value.is_some()); - map.insert(property, end_value.unwrap().clone()); + map.insert(property, end_value.unwrap().clone_arc()); } map } @@ -1428,17 +1432,19 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> { } } let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; - let declarations = declarations.and_then(|s| s.as_arc_opt()); + let declarations: Option<&RawOffsetArc>> + = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push( - ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints) + ApplicableDeclarationBlock::from_declarations(decl.clone_arc(), ServoCascadeLevel::PresHints) ); } let declarations = unsafe { Gecko_GetExtraContentStyleDeclarations(self.0) }; - let declarations = declarations.and_then(|s| s.as_arc_opt()); + let declarations: Option<&RawOffsetArc>> + = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push( - ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints) + ApplicableDeclarationBlock::from_declarations(decl.clone_arc(), ServoCascadeLevel::PresHints) ); } @@ -1458,20 +1464,22 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> { Gecko_GetVisitedLinkAttrDeclarationBlock(self.0) }, }; - let declarations = declarations.and_then(|s| s.as_arc_opt()); + let declarations: Option<&RawOffsetArc>> = + declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push( - ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints) + ApplicableDeclarationBlock::from_declarations(decl.clone_arc(), ServoCascadeLevel::PresHints) ); } let active = self.get_state().intersects(NonTSPseudoClass::Active.state_flag()); if active { let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0) }; - let declarations = declarations.and_then(|s| s.as_arc_opt()); + let declarations: Option<&RawOffsetArc>> + = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push( - ApplicableDeclarationBlock::from_declarations(Clone::clone(decl), ServoCascadeLevel::PresHints) + ApplicableDeclarationBlock::from_declarations(decl.clone_arc(), ServoCascadeLevel::PresHints) ); } } diff --git a/components/style/gecko_bindings/sugar/ownership.rs b/components/style/gecko_bindings/sugar/ownership.rs index 0b5111b3870..b4e0677bb9e 100644 --- a/components/style/gecko_bindings/sugar/ownership.rs +++ b/components/style/gecko_bindings/sugar/ownership.rs @@ -8,7 +8,7 @@ use std::marker::PhantomData; use std::mem::{forget, transmute}; use std::ops::{Deref, DerefMut}; use std::ptr; -use stylearc::Arc; +use stylearc::{Arc, RawOffsetArc}; /// Indicates that a given Servo type has a corresponding Gecko FFI type. pub unsafe trait HasFFI : Sized + 'static { @@ -88,7 +88,7 @@ pub unsafe trait HasArcFFI : HasFFI { /// (usually on the C++ side) without running the Arc destructor. unsafe fn release_opt(ptr: Option<&Self::FFIType>) { if let Some(arc) = Self::arc_from_borrowed(&ptr) { - let _: Arc<_> = ptr::read(arc as *const Arc<_>); + let _: RawOffsetArc<_> = ptr::read(arc as *const RawOffsetArc<_>); } } @@ -102,16 +102,16 @@ pub unsafe trait HasArcFFI : HasFFI { /// know that a strong reference to the backing Arc is disappearing /// (usually on the C++ side) without running the Arc destructor. unsafe fn release(ptr: &Self::FFIType) { - let _: Arc<_> = ptr::read(Self::as_arc(&ptr) as *const Arc<_>); + let _: RawOffsetArc<_> = ptr::read(Self::as_arc(&ptr) as *const RawOffsetArc<_>); } #[inline] /// Converts a borrowed FFI reference to a borrowed Arc. /// /// &GeckoType -> &Arc - fn as_arc<'a>(ptr: &'a &Self::FFIType) -> &'a Arc { + fn as_arc<'a>(ptr: &'a &Self::FFIType) -> &'a RawOffsetArc { debug_assert!(!(ptr as *const _).is_null()); unsafe { - transmute::<&&Self::FFIType, &Arc>(ptr) + transmute::<&&Self::FFIType, &RawOffsetArc>(ptr) } } @@ -119,9 +119,9 @@ pub unsafe trait HasArcFFI : HasFFI { /// Converts a borrowed Arc to a borrowed FFI reference. /// /// &Arc -> &GeckoType - fn arc_as_borrowed<'a>(arc: &'a Arc) -> &'a &Self::FFIType { + fn arc_as_borrowed<'a>(arc: &'a RawOffsetArc) -> &'a &Self::FFIType { unsafe { - transmute::<&Arc, &&Self::FFIType>(arc) + transmute::<&RawOffsetArc, &&Self::FFIType>(arc) } } @@ -129,10 +129,10 @@ pub unsafe trait HasArcFFI : HasFFI { /// Converts a borrowed nullable FFI reference to a borrowed Arc. /// /// &GeckoType -> &Arc - fn arc_from_borrowed<'a>(ptr: &'a Option<&Self::FFIType>) -> Option<&'a Arc> { + fn arc_from_borrowed<'a>(ptr: &'a Option<&Self::FFIType>) -> Option<&'a RawOffsetArc> { unsafe { if let Some(ref reference) = *ptr { - Some(transmute::<&&Self::FFIType, &Arc<_>>(reference)) + Some(transmute::<&&Self::FFIType, &RawOffsetArc<_>>(reference)) } else { None } @@ -165,7 +165,7 @@ impl Strong { /// Panics on null. /// /// Strong -> Arc - pub fn into_arc(self) -> Arc + pub fn into_arc(self) -> RawOffsetArc where ServoType: HasArcFFI, { self.into_arc_opt().unwrap() @@ -177,7 +177,7 @@ impl Strong { /// Returns None on null. /// /// Strong -> Arc - pub fn into_arc_opt(self) -> Option> + pub fn into_arc_opt(self) -> Option> where ServoType: HasArcFFI, { if self.is_null() { @@ -194,7 +194,7 @@ impl Strong { /// Returns None on null. /// /// Strong -> Arc - pub fn as_arc_opt(&self) -> Option<&Arc> + pub fn as_arc_opt(&self) -> Option<&RawOffsetArc> where ServoType: HasArcFFI, { if self.is_null() { @@ -222,18 +222,15 @@ pub unsafe trait FFIArcHelpers { /// Arc -> Strong fn into_strong(self) -> Strong<::FFIType>; - /// Produces a (nullable) borrowed FFI reference by borrowing an Arc. + /// Produces a borrowed FFI reference by borrowing an Arc. /// - /// &Arc -> Option<&GeckoType> - /// - /// FIXME(emilio): What's the point of the nullability? Arc should be - /// non-null, right? + /// &Arc -> &GeckoType /// /// Then the `arc_as_borrowed` method can go away. - fn as_borrowed_opt(&self) -> Option<&::FFIType>; + fn as_borrowed(&self) -> &::FFIType; } -unsafe impl FFIArcHelpers for Arc { +unsafe impl FFIArcHelpers for RawOffsetArc { type Inner = T; #[inline] @@ -242,9 +239,22 @@ unsafe impl FFIArcHelpers for Arc { } #[inline] - fn as_borrowed_opt(&self) -> Option<&T::FFIType> { - let borrowedptr = self as *const Arc as *const Option<&T::FFIType>; - unsafe { ptr::read(borrowedptr) } + fn as_borrowed(&self) -> &T::FFIType { + unsafe { &*(&**self as *const T as *const T::FFIType) } + } +} + +unsafe impl FFIArcHelpers for Arc { + type Inner = T; + + #[inline] + fn into_strong(self) -> Strong { + Arc::into_raw_offset(self).into_strong() + } + + #[inline] + fn as_borrowed(&self) -> &T::FFIType { + unsafe { &*(&**self as *const T as *const T::FFIType) } } } diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index 77c6ca4f3c3..048e12151ca 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -211,7 +211,7 @@ impl structs::RefPtr { /// Sets the contents to an Arc /// will leak existing contents pub fn set_arc_leaky(&mut self, other: Arc) where U: HasArcFFI { - *self = unsafe { mem::transmute(other) }; // Arc::into_raw is unstable :( + *self = unsafe { mem::transmute(Arc::into_raw_offset(other)) }; } } diff --git a/components/style/matching.rs b/components/style/matching.rs index b720c5de04a..5b06c08b5b3 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -18,7 +18,7 @@ use properties::longhands::display::computed_value as display; use rule_tree::{CascadeLevel, StrongRuleNode}; use selector_parser::{PseudoElement, RestyleDamage}; use selectors::matching::ElementSelectorFlags; -use stylearc::Arc; +use stylearc::{Arc, ArcBorrow}; /// Represents the result of comparing an element's old and new style. pub struct StyleDifference { @@ -690,7 +690,7 @@ pub trait MatchMethods : TElement { }; let replace_rule_node = |level: CascadeLevel, - pdb: Option<&Arc>>, + pdb: Option>>, path: &mut StrongRuleNode| -> bool { let new_node = stylist.rule_tree() .update_rule_at_level(level, pdb, path, guards); @@ -737,7 +737,7 @@ pub trait MatchMethods : TElement { primary_rules: &mut StrongRuleNode| { let animation_rule = self.get_animation_rule_by_cascade(level); replace_rule_node(level, - animation_rule.as_ref(), + animation_rule.as_ref().map(|a| a.borrow_arc()), primary_rules); }; diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index a6a729fe2d5..e9a76731f3b 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -16,7 +16,7 @@ use std::io::{self, Write}; use std::mem; use std::ptr; use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; -use stylearc::{Arc, NonZeroPtrMut}; +use stylearc::{Arc, ArcBorrow, NonZeroPtrMut}; use stylesheets::StyleRule; use thread_state; @@ -308,7 +308,7 @@ impl RuleTree { /// the old path is still valid. pub fn update_rule_at_level(&self, level: CascadeLevel, - pdb: Option<&Arc>>, + pdb: Option>>, path: &StrongRuleNode, guards: &StylesheetGuards) -> Option { @@ -347,7 +347,7 @@ impl RuleTree { // so let's skip it for now. let is_here_already = match ¤t.get().source { &StyleSource::Declarations(ref already_here) => { - Arc::ptr_eq(pdb, already_here) + pdb.with_arc(|arc| Arc::ptr_eq(arc, already_here)) }, _ => unreachable!("Replacing non-declarations style?"), }; @@ -371,13 +371,13 @@ impl RuleTree { if level.is_important() { if pdb.read_with(level.guard(guards)).any_important() { current = current.ensure_child(self.root.downgrade(), - StyleSource::Declarations(pdb.clone()), + StyleSource::Declarations(pdb.clone_arc()), level); } } else { if pdb.read_with(level.guard(guards)).any_normal() { current = current.ensure_child(self.root.downgrade(), - StyleSource::Declarations(pdb.clone()), + StyleSource::Declarations(pdb.clone_arc()), level); } } diff --git a/components/style/sharing/checks.rs b/components/style/sharing/checks.rs index 17875cb061a..b710dffdc4d 100644 --- a/components/style/sharing/checks.rs +++ b/components/style/sharing/checks.rs @@ -43,7 +43,7 @@ pub fn have_same_style_attribute( match (target.style_attribute(), candidate.style_attribute()) { (None, None) => true, (Some(_), None) | (None, Some(_)) => false, - (Some(a), Some(b)) => Arc::ptr_eq(a, b) + (Some(a), Some(b)) => &*a as *const _ == &*b as *const _ } } diff --git a/components/style/stylesheets/rule_list.rs b/components/style/stylesheets/rule_list.rs index 9b939ddf131..8764b8f89b6 100644 --- a/components/style/stylesheets/rule_list.rs +++ b/components/style/stylesheets/rule_list.rs @@ -5,7 +5,7 @@ //! A list of CSS rules. use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard}; -use stylearc::Arc; +use stylearc::{Arc, RawOffsetArc}; use stylesheets::{CssRule, RulesMutateError}; use stylesheets::loader::StylesheetLoader; use stylesheets::memory::{MallocSizeOfFn, MallocSizeOfWithGuard}; @@ -109,7 +109,7 @@ pub trait CssRulesHelpers { -> Result; } -impl CssRulesHelpers for Arc> { +impl CssRulesHelpers for RawOffsetArc> { fn insert_rule(&self, lock: &SharedRwLock, rule: &str, diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 395a1cccf42..b4dad68f699 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -37,7 +37,7 @@ use std::fmt::Debug; #[cfg(feature = "servo")] use std::marker::PhantomData; use style_traits::viewport::ViewportConstraints; -use stylearc::Arc; +use stylearc::{Arc, ArcBorrow}; #[cfg(feature = "gecko")] use stylesheets::{CounterStyleRule, FontFaceRule}; use stylesheets::{CssRule, StyleRule}; @@ -1103,8 +1103,8 @@ impl Stylist { &self, element: &E, pseudo_element: Option<&PseudoElement>, - style_attribute: Option<&Arc>>, - smil_override: Option<&Arc>>, + style_attribute: Option>>, + smil_override: Option>>, animation_rules: AnimationRules, rule_inclusion: RuleInclusion, applicable_declarations: &mut V, @@ -1208,7 +1208,7 @@ impl Stylist { if let Some(sa) = style_attribute { Push::push( applicable_declarations, - ApplicableDeclarationBlock::from_declarations(sa.clone(), + ApplicableDeclarationBlock::from_declarations(sa.clone_arc(), CascadeLevel::StyleAttributeNormal)); } @@ -1217,7 +1217,7 @@ impl Stylist { if let Some(so) = smil_override { Push::push( applicable_declarations, - ApplicableDeclarationBlock::from_declarations(so.clone(), + ApplicableDeclarationBlock::from_declarations(so.clone_arc(), CascadeLevel::SMILOverride)); } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index d98ceb34531..05c03334f9b 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -90,7 +90,7 @@ use style::invalidation::element::restyle_hints::{self, RestyleHint}; use style::media_queries::{MediaList, parse_media_query_list}; use style::parallel; use style::parser::ParserContext; -use style::properties::{ComputedValues, Importance, SourcePropertyDeclaration}; +use style::properties::{ComputedValues, ComputedValuesInner, Importance, SourcePropertyDeclaration}; use style::properties::{LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId, StyleBuilder}; use style::properties::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP; use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue}; @@ -101,7 +101,7 @@ use style::sequential; use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked}; use style::string_cache::Atom; use style::style_adjuster::StyleAdjuster; -use style::stylearc::Arc; +use style::stylearc::{Arc, RawOffsetArc}; use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule}; use style::stylesheets::{ImportRule, KeyframesRule, MallocSizeOfWithGuard, MediaRule}; use style::stylesheets::{NamespaceRule, Origin, PageRule, StyleRule, SupportsRule}; @@ -429,7 +429,7 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa let previous_composed_value = value_map.get(&property).cloned(); previous_composed_value.or_else(|| { let raw_base_style = unsafe { Gecko_AnimationGetBaseStyle(base_values, css_property) }; - AnimationValue::arc_from_borrowed(&raw_base_style).map(|v| v.as_ref()).cloned() + AnimationValue::arc_from_borrowed(&raw_base_style).map(|v| &**v).cloned() }) } else { None @@ -459,7 +459,7 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa // Composite with underlying value. // A return value of None means, "Just use keyframe_value as-is." - let composite_endpoint = |keyframe_value: Option<&Arc>, + let composite_endpoint = |keyframe_value: Option<&RawOffsetArc>, composite_op: CompositeOperation| -> Option { match keyframe_value { Some(keyframe_value) => { @@ -498,7 +498,7 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa let raw_last_value; let last_value = if !last_segment.mToValue.mServo.mRawPtr.is_null() { raw_last_value = unsafe { &*last_segment.mToValue.mServo.mRawPtr }; - AnimationValue::as_arc(&raw_last_value).as_ref() + &*AnimationValue::as_arc(&raw_last_value) } else { debug_assert!(need_underlying_value, "Should have detected we need an underlying value"); @@ -506,7 +506,7 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa }; // As with composite_endpoint, a return value of None means, "Use keyframe_value as-is." - let apply_iteration_composite = |keyframe_value: Option<&Arc>, + let apply_iteration_composite = |keyframe_value: Option<&RawOffsetArc>, composited_value: Option| -> Option { let count = computed_timing.mCurrentIteration; @@ -1244,7 +1244,7 @@ pub extern "C" fn Servo_StyleRule_SetStyle(rule: RawServoStyleRuleBorrowed, declarations: RawServoDeclarationBlockBorrowed) { let declarations = Locked::::as_arc(&declarations); write_locked_arc(rule, |rule: &mut StyleRule| { - rule.block = declarations.clone(); + rule.block = declarations.clone_arc(); }) } @@ -1382,7 +1382,7 @@ pub extern "C" fn Servo_Keyframe_SetStyle(keyframe: RawServoKeyframeBorrowed, declarations: RawServoDeclarationBlockBorrowed) { let declarations = Locked::::as_arc(&declarations); write_locked_arc(keyframe, |keyframe: &mut Keyframe| { - keyframe.block = declarations.clone(); + keyframe.block = declarations.clone_arc(); }) } @@ -1480,7 +1480,7 @@ pub extern "C" fn Servo_PageRule_SetStyle(rule: RawServoPageRuleBorrowed, declarations: RawServoDeclarationBlockBorrowed) { let declarations = Locked::::as_arc(&declarations); write_locked_arc(rule, |rule: &mut PageRule| { - rule.block = declarations.clone(); + rule.block = declarations.clone_arc(); }) } @@ -1559,7 +1559,7 @@ pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed, &pseudo, RuleInclusion::All, &data.styles, - ComputedValues::arc_from_borrowed(&inherited_style), + ComputedValues::arc_from_borrowed(&inherited_style).map(|x| &***x), &*doc_data, is_probe ); @@ -1584,7 +1584,7 @@ pub extern "C" fn Servo_SetExplicitStyle(element: RawGeckoElementBorrowed, // work for other things, we just haven't had a reason to do so. debug_assert!(element.get_data().is_none()); let mut data = unsafe { element.ensure_data() }; - data.styles.primary = Some(style.clone()); + data.styles.primary = Some(style.clone_arc()); } #[no_mangle] @@ -1613,7 +1613,7 @@ fn get_pseudo_style( pseudo: &PseudoElement, rule_inclusion: RuleInclusion, styles: &ElementStyles, - inherited_styles: Option<&Arc>, + inherited_styles: Option<&ComputedValuesInner>, doc_data: &PerDocumentStyleDataImpl, is_probe: bool, ) -> Option> { @@ -1642,8 +1642,8 @@ fn get_pseudo_style( }, _ => { debug_assert!(inherited_styles.is_none() || - ptr::eq(&**inherited_styles.unwrap(), - &**styles.primary())); + ptr::eq(&*inherited_styles.unwrap(), + &***styles.primary())); styles.pseudos.get(&pseudo).cloned() }, } @@ -1651,8 +1651,8 @@ fn get_pseudo_style( PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"), PseudoElementCascadeType::Lazy => { debug_assert!(inherited_styles.is_none() || - ptr::eq(&**inherited_styles.unwrap(), - &**styles.primary())); + ptr::eq(&*inherited_styles.unwrap(), + &***styles.primary())); let base = if pseudo.inherits_from_default_values() { doc_data.default_computed_values() } else { @@ -1761,12 +1761,14 @@ pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(values: ServoComputedVal let mut result = vec![]; for node in rule_node.self_and_ancestors() { if let &StyleSource::Style(ref rule) = node.style_source() { - result.push(Locked::::arc_as_borrowed(&rule)); + result.push(rule); } } unsafe { rules.set_len(result.len() as u32) }; - for (&src, dest) in result.into_iter().zip(rules.iter_mut()) { - *dest = src; + for (ref src, ref mut dest) in result.into_iter().zip(rules.iter_mut()) { + src.with_raw_offset_arc(|arc| { + **dest = *Locked::::arc_as_borrowed(arc); + }) } } } @@ -3274,7 +3276,7 @@ pub extern "C" fn Servo_StyleSet_ResolveForDeclarations( doc_data.stylist.compute_for_declarations(&guards, parent_style, - declarations.clone()).into_strong() + declarations.clone_arc()).into_strong() } #[no_mangle]