Bug 1367904 - Part 16: stylo: Stop using mStyleIfVisited in Servo; r?bholley draft
authorManish Goregaokar <manishearth@gmail.com>
Mon, 17 Jul 2017 11:42:20 -0700
changeset 610223 8f0b4dc8f613f5003a9af5e790975fb077e3893e
parent 610222 5ad948bcd4ca105845bdb3231612387a36cb9313
child 610224 7822f2f19bad0885fefa5609e02a2c7a6344bfb4
push id68805
push userbmo:manishearth@gmail.com
push dateTue, 18 Jul 2017 00:30:54 +0000
reviewersbholley
bugs1367904
milestone56.0a1
Bug 1367904 - Part 16: stylo: Stop using mStyleIfVisited in Servo; r?bholley MozReview-Commit-ID: JxoMr6fz7lh
layout/base/ServoRestyleManager.cpp
layout/style/ServoBindingList.h
layout/style/ServoBindings.toml
layout/style/ServoStyleSet.cpp
layout/style/ServoTypes.h
layout/style/nsStyleContext.h
layout/style/nsStyleContextInlines.h
servo/components/style/gecko/generated/bindings.rs
servo/components/style/gecko/generated/structs_debug.rs
servo/components/style/gecko/generated/structs_release.rs
servo/components/style/properties/gecko.mako.rs
servo/ports/geckolib/glue.rs
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -550,18 +550,21 @@ ServoRestyleManager::ProcessPostTraversa
 
   RefPtr<ServoStyleContext> newContext = nullptr;
   if (wasRestyled && oldStyleContext) {
     MOZ_ASSERT(styleFrame || displayContentsNode);
     RefPtr<ServoStyleContext> currentContext =
       aRestyleState.StyleSet().ResolveServoStyle(aElement);
     MOZ_ASSERT(oldStyleContext->ComputedValues() != currentContext->ComputedValues());
 
+    auto pseudo = aElement->GetPseudoElementType();
 
-    newContext = currentContext;
+    nsIAtom* pseudoTag = pseudo == CSSPseudoElementType::NotPseudo ? nullptr : nsCSSPseudoElements::GetPseudoAtom(pseudo);
+
+    newContext = aRestyleState.StyleSet().GetContext(currentContext.forget(), aParentContext, pseudoTag, pseudo, aElement);
 
     newContext->ResolveSameStructsAs(PresContext(), oldStyleContext);
 
     // We want to walk all the continuations here, even the ones with different
     // styles.  In practice, the only reason we get continuations with different
     // styles here is ::first-line (::first-letter never affects element
     // styles).  But in that case, newContext is the right context for the
     // _later_ continuations anyway (the ones not affected by ::first-line), not
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -465,19 +465,16 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_
                    nsIAtom* pseudo_tag,
                    RawServoStyleSetBorrowed set)
 SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoStyleContextStrong,
                    RawServoStyleSetBorrowed set,
                    mozilla::CSSPseudoElementType pseudo_type,
                    nsIAtom* pseudo_tag,
                    ServoStyleContextBorrowedOrNull parent_style,
                    mozilla::InheritTarget target)
-SERVO_BINDING_FUNC(Servo_ComputedValues_GetVisitedStyle,
-                   ServoStyleContextStrong,
-                   ServoComputedValuesBorrowed values)
 SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint64_t,
                    ServoComputedValuesBorrowed values)
 SERVO_BINDING_FUNC(Servo_ComputedValues_EqualCustomProperties, bool,
                    ServoComputedValuesBorrowed first,
                    ServoComputedValuesBorrowed second)
 // Gets the source style rules for the computed values. This returns
 // the result via rules, which would include a list of unowned pointers
 // to RawServoStyleRule.
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -317,17 +317,17 @@ opaque-types = [
 mapped-generic-types = [
     { generic = true, gecko = "mozilla::ServoUnsafeCell", servo = "::std::cell::UnsafeCell" },
     { generic = true, gecko = "mozilla::ServoCell", servo = "::std::cell::Cell" },
     { generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
     { generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
     { generic = false, gecko = "mozilla::ServoFontComputationData", servo = "::properties::FontComputationData" },
     { generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>" },
     { generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
-    { generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::stylearc::Arc<::properties::ComputedValues>>" },
+    { generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::stylearc::RawOffsetArc<::properties::ComputedValues>>" },
     { generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
     { generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::stylearc::RawOffsetArc" },
     { generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>" },
 ]
 fixups = [
     { pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
 ]
 
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -221,50 +221,23 @@ ServoStyleSet::GetContext(already_AddRef
                                        .HasState(NS_EVENT_STATE_VISITED);
   }
 
   RefPtr<ServoStyleContext> result = Move(aComputedValues);
 
   MOZ_ASSERT(result->GetPseudoType() == aPseudoType);
   MOZ_ASSERT(result->GetPseudo() == aPseudoTag);
 
-  RefPtr<ServoStyleContext> resultIfVisited =
-    Servo_ComputedValues_GetVisitedStyle(result->ComputedValues()).Consume();
-
-  // If `resultIfVisited` is non-null, then there was a relevant link and
-  // visited styles were computed.  This corresponds to the cases where Gecko's
-  // style system produces `aVisitedRuleNode`.
-  // Set up `parentIfVisited` depending on whether our parent context has a
-  // a visited style.  If it doesn't but we do have visited styles, use the
-  // regular parent context for visited.
-  nsStyleContext *parentIfVisited =
-    aParentContext ? aParentContext->GetStyleIfVisited() : nullptr;
-  if (!parentIfVisited) {
-    if (resultIfVisited) {
-      parentIfVisited = aParentContext;
-    }
-  }
-
-  ServoStyleContext* parentIfVisitedServo = parentIfVisited ? parentIfVisited->AsServo() : nullptr;
-
   // The true visited state of the relevant link is used to decided whether
   // visited styles should be consulted for all visited dependent properties.
   bool relevantLinkVisited = isLink ? isVisitedLink :
     (aParentContext && aParentContext->RelevantLinkVisited());
 
-  if (resultIfVisited) {
-    RefPtr<ServoStyleContext> visitedContext =
-    Servo_StyleContext_NewContext(resultIfVisited->ComputedValues(), parentIfVisitedServo,
-                                  mPresContext, aPseudoType, aPseudoTag).Consume();
-    visitedContext->SetIsStyleIfVisited();
-    result->SetStyleIfVisited(visitedContext.forget());
-
-    if (relevantLinkVisited) {
-      result->AddStyleBit(NS_STYLE_RELEVANT_LINK_VISITED);
-    }
+  if (relevantLinkVisited && result->GetStyleIfVisited()) {
+    result->AddStyleBit(NS_STYLE_RELEVANT_LINK_VISITED);
   }
 
   // Set the body color on the pres context. See nsStyleSet::GetContext
   if (aElementForAnimation &&
       aElementForAnimation->IsHTMLElement(nsGkAtoms::body) &&
       aPseudoType == CSSPseudoElementType::NotPseudo &&
       mPresContext->CompatibilityMode() == eCompatibility_NavQuirks) {
     nsIDocument* doc = aElementForAnimation->GetUncomposedDoc();
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -145,22 +145,31 @@ struct ServoFontComputationData {
 struct ServoCustomPropertiesMap {
   uintptr_t mPtr;
 };
 
 struct ServoRuleNode {
   uintptr_t mPtr;
 };
 
+
+class ServoStyleContext;
+
 struct ServoVisitedStyle {
-  uintptr_t mPtr;
+  // This is actually a strong reference
+  // but ServoComputedValues' destructor is
+  // managed by the Rust code so we just use a
+  // regular pointer
+  ServoStyleContext* mPtr;
 };
 
 template <typename T>
 struct ServoRawOffsetArc {
+  // Again, a strong reference, but
+  // managed by the Rust code
   T* mPtr;
 };
 
 struct ServoComputedValueFlags {
   uint8_t mFlags;
 };
 
 #define STYLE_STRUCT(name_, checkdata_cb_) struct Gecko##name_;
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -184,18 +184,17 @@ public:
   // calls until null is returned) is the same as |this|, since its
   // parent is either |this|'s parent or |this|'s parent's
   // style-if-visited.
   //
   // Structs on this context should never be examined without also
   // examining the corresponding struct on |this|.  Doing so will likely
   // both (1) lead to a privacy leak and (2) lead to dynamic change bugs
   // related to the Peek code in nsStyleContext::CalcStyleDifference.
-  nsStyleContext* GetStyleIfVisited() const
-    { return mStyleIfVisited; }
+  inline nsStyleContext* GetStyleIfVisited() const;
 
   // To be called only from nsStyleSet / ServoStyleSet.
   void SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited);
 
   // Does any descendant of this style context have any style values
   // that were computed based on this style context's ancestors?
   bool HasChildThatUsesGrandancestorStyle() const
     { return !!(mBits & NS_STYLE_CHILD_USES_GRANDANCESTOR_STYLE); }
--- a/layout/style/nsStyleContextInlines.h
+++ b/layout/style/nsStyleContextInlines.h
@@ -179,16 +179,26 @@ const nsStyle##name_ * nsStyleContext::D
 
 
 nsPresContext*
 nsStyleContext::PresContext() const
 {
     MOZ_STYLO_FORWARD(PresContext, ())
 }
 
+
+nsStyleContext*
+nsStyleContext::GetStyleIfVisited() const
+{
+  if (auto servo = GetAsServo()) {
+    return servo->ComputedValues()->visited_style.mPtr;
+  }
+  return mStyleIfVisited;
+}
+
 mozilla::GeckoStyleContext*
 nsStyleContext::GetParent() const
 {
   MOZ_ASSERT(IsGecko(),
              "This should be used only in Gecko-backed style system!");
   if (mParent) {
     return mParent->AsGecko();
   } else {
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -2683,21 +2683,16 @@ extern "C" {
                                         pseudo_type: CSSPseudoElementType,
                                         pseudo_tag: *mut nsIAtom,
                                         parent_style:
                                             ServoStyleContextBorrowedOrNull,
                                         target: InheritTarget)
      -> ServoStyleContextStrong;
 }
 extern "C" {
-    pub fn Servo_ComputedValues_GetVisitedStyle(values:
-                                                    ServoComputedValuesBorrowed)
-     -> ServoStyleContextStrong;
-}
-extern "C" {
     pub fn Servo_ComputedValues_GetStyleBits(values:
                                                  ServoComputedValuesBorrowed)
      -> u64;
 }
 extern "C" {
     pub fn Servo_ComputedValues_EqualCustomProperties(first:
                                                           ServoComputedValuesBorrowed,
                                                       second:
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -8,17 +8,17 @@ use atomic_refcell::AtomicRefCell;
 use data::ElementData;
 pub type ServoUnsafeCell<T> = ::std::cell::UnsafeCell<T>;
 pub type ServoCell<T> = ::std::cell::Cell<T>;
 pub type ServoNodeData = AtomicRefCell<ElementData>;
 pub type ServoWritingMode = ::logical_geometry::WritingMode;
 pub type ServoFontComputationData = ::properties::FontComputationData;
 pub type ServoCustomPropertiesMap = Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>;
 pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
-pub type ServoVisitedStyle = Option<::stylearc::Arc<::properties::ComputedValues>>;
+pub type ServoVisitedStyle = Option<::stylearc::RawOffsetArc<::properties::ComputedValues>>;
 pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
 pub type ServoRawOffsetArc<T> = ::stylearc::RawOffsetArc<T>;
 pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>;
 
 #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
 pub mod root {
     #[repr(C)]
     pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
@@ -7598,16 +7598,46 @@ pub mod root {
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum InheritTarget {
             Text = 0,
             FirstLetterContinuation = 1,
             PlaceholderFrame = 2,
         }
         #[repr(C)]
         #[derive(Debug)]
+        pub struct ServoStyleContext {
+            pub _base: root::nsStyleContext,
+            pub mPresContext: *mut root::nsPresContext,
+            pub mSource: root::ServoComputedValues,
+        }
+        #[test]
+        fn bindgen_test_layout_ServoStyleContext() {
+            assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 280usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( ServoStyleContext ) ));
+            assert_eq! (::std::mem::align_of::<ServoStyleContext>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( ServoStyleContext )
+                        ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoStyleContext ) ) .
+                        mPresContext as * const _ as usize } , 40usize ,
+                        concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoStyleContext ) , "::" , stringify ! (
+                        mPresContext ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoStyleContext ) ) . mSource
+                        as * const _ as usize } , 48usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoStyleContext ) , "::" , stringify ! ( mSource )
+                        ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
         pub struct GeckoFont {
             pub gecko: root::nsStyleFont,
         }
         #[test]
         fn bindgen_test_layout_GeckoFont() {
             assert_eq!(::std::mem::size_of::<GeckoFont>() , 120usize , concat
                        ! ( "Size of: " , stringify ! ( GeckoFont ) ));
             assert_eq! (::std::mem::align_of::<GeckoFont>() , 8usize , concat
@@ -10839,46 +10869,16 @@ pub mod root {
                               (64u64 as u8))
                  } |
                      ((mOtherAttributeChanged as u8 as u8) << 7usize) &
                          (128u64 as u8))
             }
         }
         #[repr(C)]
         #[derive(Debug)]
-        pub struct ServoStyleContext {
-            pub _base: root::nsStyleContext,
-            pub mPresContext: *mut root::nsPresContext,
-            pub mSource: root::ServoComputedValues,
-        }
-        #[test]
-        fn bindgen_test_layout_ServoStyleContext() {
-            assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 280usize ,
-                       concat ! (
-                       "Size of: " , stringify ! ( ServoStyleContext ) ));
-            assert_eq! (::std::mem::align_of::<ServoStyleContext>() , 8usize ,
-                        concat ! (
-                        "Alignment of " , stringify ! ( ServoStyleContext )
-                        ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const ServoStyleContext ) ) .
-                        mPresContext as * const _ as usize } , 40usize ,
-                        concat ! (
-                        "Alignment of field: " , stringify ! (
-                        ServoStyleContext ) , "::" , stringify ! (
-                        mPresContext ) ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const ServoStyleContext ) ) . mSource
-                        as * const _ as usize } , 48usize , concat ! (
-                        "Alignment of field: " , stringify ! (
-                        ServoStyleContext ) , "::" , stringify ! ( mSource )
-                        ));
-        }
-        #[repr(C)]
-        #[derive(Debug)]
         pub struct AnimationPropertySegment {
             pub mFromKey: f32,
             pub mToKey: f32,
             pub mFromValue: root::mozilla::AnimationValue,
             pub mToValue: root::mozilla::AnimationValue,
             pub mTimingFunction: [u64; 18usize],
             pub mFromComposite: root::mozilla::dom::CompositeOperation,
             pub mToComposite: root::mozilla::dom::CompositeOperation,
@@ -40109,26 +40109,26 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
         assert_eq!(::std::mem::align_of::<root::nsCharTraits>() , 1usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_195320_instantiation_33() {
+    fn __bindgen_test_layout__bindgen_ty_id_195318_instantiation_33() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_195356_instantiation_34() {
+    fn __bindgen_test_layout__bindgen_ty_id_195354_instantiation_34() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
--- a/servo/components/style/gecko/generated/structs_release.rs
+++ b/servo/components/style/gecko/generated/structs_release.rs
@@ -8,17 +8,17 @@ use atomic_refcell::AtomicRefCell;
 use data::ElementData;
 pub type ServoUnsafeCell<T> = ::std::cell::UnsafeCell<T>;
 pub type ServoCell<T> = ::std::cell::Cell<T>;
 pub type ServoNodeData = AtomicRefCell<ElementData>;
 pub type ServoWritingMode = ::logical_geometry::WritingMode;
 pub type ServoFontComputationData = ::properties::FontComputationData;
 pub type ServoCustomPropertiesMap = Option<::stylearc::Arc<::custom_properties::CustomPropertiesMap>>;
 pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
-pub type ServoVisitedStyle = Option<::stylearc::Arc<::properties::ComputedValues>>;
+pub type ServoVisitedStyle = Option<::stylearc::RawOffsetArc<::properties::ComputedValues>>;
 pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
 pub type ServoRawOffsetArc<T> = ::stylearc::RawOffsetArc<T>;
 pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>;
 
 #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
 pub mod root {
     #[repr(C)]
     pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
@@ -7450,16 +7450,46 @@ pub mod root {
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum InheritTarget {
             Text = 0,
             FirstLetterContinuation = 1,
             PlaceholderFrame = 2,
         }
         #[repr(C)]
         #[derive(Debug)]
+        pub struct ServoStyleContext {
+            pub _base: root::nsStyleContext,
+            pub mPresContext: *mut root::nsPresContext,
+            pub mSource: root::ServoComputedValues,
+        }
+        #[test]
+        fn bindgen_test_layout_ServoStyleContext() {
+            assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 280usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( ServoStyleContext ) ));
+            assert_eq! (::std::mem::align_of::<ServoStyleContext>() , 8usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( ServoStyleContext )
+                        ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoStyleContext ) ) .
+                        mPresContext as * const _ as usize } , 40usize ,
+                        concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoStyleContext ) , "::" , stringify ! (
+                        mPresContext ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const ServoStyleContext ) ) . mSource
+                        as * const _ as usize } , 48usize , concat ! (
+                        "Alignment of field: " , stringify ! (
+                        ServoStyleContext ) , "::" , stringify ! ( mSource )
+                        ));
+        }
+        #[repr(C)]
+        #[derive(Debug)]
         pub struct GeckoFont {
             pub gecko: root::nsStyleFont,
         }
         #[test]
         fn bindgen_test_layout_GeckoFont() {
             assert_eq!(::std::mem::size_of::<GeckoFont>() , 120usize , concat
                        ! ( "Size of: " , stringify ! ( GeckoFont ) ));
             assert_eq! (::std::mem::align_of::<GeckoFont>() , 8usize , concat
@@ -10576,46 +10606,16 @@ pub mod root {
                               (64u64 as u8))
                  } |
                      ((mOtherAttributeChanged as u8 as u8) << 7usize) &
                          (128u64 as u8))
             }
         }
         #[repr(C)]
         #[derive(Debug)]
-        pub struct ServoStyleContext {
-            pub _base: root::nsStyleContext,
-            pub mPresContext: *mut root::nsPresContext,
-            pub mSource: root::ServoComputedValues,
-        }
-        #[test]
-        fn bindgen_test_layout_ServoStyleContext() {
-            assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 280usize ,
-                       concat ! (
-                       "Size of: " , stringify ! ( ServoStyleContext ) ));
-            assert_eq! (::std::mem::align_of::<ServoStyleContext>() , 8usize ,
-                        concat ! (
-                        "Alignment of " , stringify ! ( ServoStyleContext )
-                        ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const ServoStyleContext ) ) .
-                        mPresContext as * const _ as usize } , 40usize ,
-                        concat ! (
-                        "Alignment of field: " , stringify ! (
-                        ServoStyleContext ) , "::" , stringify ! (
-                        mPresContext ) ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const ServoStyleContext ) ) . mSource
-                        as * const _ as usize } , 48usize , concat ! (
-                        "Alignment of field: " , stringify ! (
-                        ServoStyleContext ) , "::" , stringify ! ( mSource )
-                        ));
-        }
-        #[repr(C)]
-        #[derive(Debug)]
         pub struct AnimationPropertySegment {
             pub mFromKey: f32,
             pub mToKey: f32,
             pub mFromValue: root::mozilla::AnimationValue,
             pub mToValue: root::mozilla::AnimationValue,
             pub mTimingFunction: [u64; 18usize],
             pub mFromComposite: root::mozilla::dom::CompositeOperation,
             pub mToComposite: root::mozilla::dom::CompositeOperation,
@@ -39457,26 +39457,26 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
         assert_eq!(::std::mem::align_of::<root::nsCharTraits>() , 1usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_192842_instantiation_33() {
+    fn __bindgen_test_layout__bindgen_ty_id_192840_instantiation_33() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_192878_instantiation_34() {
+    fn __bindgen_test_layout__bindgen_ty_id_192876_instantiation_34() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -126,17 +126,17 @@ impl ComputedValuesInner {
                ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
                % endfor
     ) -> Self {
         ComputedValuesInner {
             custom_properties: custom_properties,
             writing_mode: writing_mode,
             font_computation_data: FontComputationData::new(font_size_keyword),
             rules: rules,
-            visited_style: visited_style,
+            visited_style: visited_style.map(|x| Arc::into_raw_offset(x)),
             flags: flags,
             % for style_struct in data.style_structs:
             ${style_struct.gecko_name}: Arc::into_raw_offset(${style_struct.ident}),
             % endfor
         }
     }
 
     pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Self {
@@ -245,17 +245,17 @@ impl ComputedValuesInner {
     /// Gets a reference to the visited style. Panic if no visited style exists.
     pub fn visited_style(&self) -> &ComputedValues {
         self.get_visited_style().unwrap()
     }
 
     /// Clone the visited style.  Used for inheriting parent styles in
     /// StyleBuilder::for_inheritance.
     pub fn clone_visited_style(&self) -> Option<Arc<ComputedValues>> {
-        self.visited_style.clone()
+        self.visited_style.as_ref().map(|x| x.clone_arc())
     }
 
     /// Gets a reference to the custom properties map (if one exists).
     pub fn get_custom_properties(&self) -> Option<<&::custom_properties::CustomPropertiesMap> {
         self.custom_properties.as_ref().map(|x| &**x)
     }
 
     pub fn custom_properties(&self) -> Option<Arc<CustomPropertiesMap>> {
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1728,25 +1728,16 @@ pub extern "C" fn Servo_ComputedValues_I
     } else {
         Some((pseudo_tag, pseudo_type))
     };
 
     style.to_outer(data.stylist.device(), parent_style_context, pseudo_info).into_strong()
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ComputedValues_GetVisitedStyle(values: ServoComputedValuesBorrowed)
-                                                       -> ServoStyleContextStrong {
-    match values.clone_visited_style() {
-        Some(v) => v.into_strong(),
-        None => Strong::null(),
-    }
-}
-
-#[no_mangle]
 pub extern "C" fn Servo_StyleContext_NewContext(values: ServoComputedValuesBorrowed,
                                                 parent: ServoStyleContextBorrowedOrNull,
                                                 pres_context: bindings::RawGeckoPresContextBorrowed,
                                                 pseudo_type: CSSPseudoElementType,
                                                 pseudo_tag: *mut nsIAtom)
                                                        -> ServoStyleContextStrong {
     unsafe {
         (*values).clone().to_outer_helper(pres_context, parent,