Bug 1382017 - stylo: Remove usage of ServoComputedValues from binding functions; r?xidorn draft
authorManish Goregaokar <manishearth@gmail.com>
Tue, 18 Jul 2017 23:17:34 -0700
changeset 612014 fc55145a8e798376e0432521ae0ff3ee16048c81
parent 612013 bf61ec7b8898e765071ab4aac15e9aad0c60907b
child 638293 935f4ce35e80061f1a094b6546379a98aa24be77
push id69366
push userbmo:manishearth@gmail.com
push dateThu, 20 Jul 2017 08:13:58 +0000
reviewersxidorn
bugs1382017
milestone56.0a1
Bug 1382017 - stylo: Remove usage of ServoComputedValues from binding functions; r?xidorn MozReview-Commit-ID: 3KygTIIMVvF
layout/base/nsCSSFrameConstructor.cpp
layout/inspector/inDOMUtils.cpp
layout/style/ServoBindingList.h
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
layout/style/ServoStyleContext.cpp
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsStyleContext.cpp
servo/components/servo_arc/lib.rs
servo/components/style/gecko/arc_types.rs
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/gecko_bindings/sugar/ownership.rs
servo/components/style/properties/gecko.mako.rs
servo/ports/geckolib/glue.rs
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1924,17 +1924,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
   // just stick the style on the element and avoid an additional traversal.
   //
   // We don't do this for pseudos that may trigger animations or transitions,
   // since those need to be kicked off by the traversal machinery.
   bool hasServoAnimations = false;
   ServoStyleContext* servoStyle = pseudoStyleContext->GetAsServo();
   if (servoStyle) {
     hasServoAnimations =
-      Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle->ComputedValues());
+      Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle);
     if (!hasServoAnimations) {
       Servo_SetExplicitStyle(container, servoStyle);
     }
   }
 
   // stylo: ServoRestyleManager does not handle transitions yet, and when it
   // does it probably won't need to track reframed style contexts to start
   // transitions correctly.
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -267,18 +267,17 @@ inDOMUtils::GetCSSStyleRules(nsIDOMEleme
     nsIDocument* doc = element->GetOwnerDocument();
     nsIPresShell* shell = doc->GetShell();
     if (!shell) {
       return NS_OK;
     }
 
     ServoStyleContext* servo = styleContext->AsServo();
     nsTArray<const RawServoStyleRule*> rawRuleList;
-    Servo_ComputedValues_GetStyleRuleList(servo->ComputedValues(),
-                                          &rawRuleList);
+    Servo_ComputedValues_GetStyleRuleList(servo, &rawRuleList);
 
     ServoStyleSet* styleSet = shell->StyleSet()->AsServo();
     ServoStyleRuleMap* map = styleSet->StyleRuleMap();
     map->EnsureTable();
 
     // Find matching rules in the table.
     for (const RawServoStyleRule* rawRule : Reversed(rawRuleList)) {
       if (ServoStyleRule* rule = map->Lookup(rawRule)) {
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -230,17 +230,17 @@ SERVO_BINDING_FUNC(Servo_GetComputedKeyf
                    ServoStyleContextBorrowed style,
                    RawServoStyleSetBorrowed set,
                    RawGeckoComputedKeyframeValuesListBorrowedMut result)
 SERVO_BINDING_FUNC(Servo_ComputedValues_ExtractAnimationValue,
                    RawServoAnimationValueStrong,
                    ServoStyleContextBorrowed computed_values,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_ComputedValues_SpecifiesAnimationsOrTransitions, bool,
-                   ServoComputedValuesBorrowed computed_values)
+                   ServoStyleContextBorrowed computed_values)
 SERVO_BINDING_FUNC(Servo_Property_IsAnimatable, bool,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_Property_IsTransitionable, bool,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_Property_IsDiscreteAnimatable, bool,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_GetProperties_Overriding_Animation, void,
                    RawGeckoElementBorrowed,
@@ -467,25 +467,25 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_
                    nsIAtom* pseudo_tag,
                    RawServoStyleSetBorrowed set)
 SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoStyleContextStrong,
                    RawServoStyleSetBorrowed set,
                    nsIAtom* pseudo_tag,
                    ServoStyleContextBorrowedOrNull parent_style,
                    mozilla::InheritTarget target)
 SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint64_t,
-                   ServoComputedValuesBorrowed values)
+                   ServoStyleContextBorrowed 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.
 SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleRuleList, void,
-                   ServoComputedValuesBorrowed values,
+                   ServoStyleContextBorrowed values,
                    RawGeckoServoStyleRuleListBorrowedMut rules)
 
 // Initialize Servo components. Should be called exactly once at startup.
 SERVO_BINDING_FUNC(Servo_Initialize, void,
                    RawGeckoURLExtraData* dummy_url_data)
 // Shut down Servo components. Should be called exactly once at shutdown.
 SERVO_BINDING_FUNC(Servo_Shutdown, void)
 
@@ -558,24 +558,24 @@ SERVO_BINDING_FUNC(Servo_StyleSet_GetBas
 
 // For canvas font.
 SERVO_BINDING_FUNC(Servo_SerializeFontValueForCanvas, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsAString* buffer)
 
 // Get custom property value.
 SERVO_BINDING_FUNC(Servo_GetCustomPropertyValue, bool,
-                   ServoComputedValuesBorrowed computed_values,
+                   ServoStyleContextBorrowed computed_values,
                    const nsAString* name, nsAString* value)
 
 SERVO_BINDING_FUNC(Servo_GetCustomPropertiesCount, uint32_t,
-                   ServoComputedValuesBorrowed computed_values)
+                   ServoStyleContextBorrowed computed_values)
 
 SERVO_BINDING_FUNC(Servo_GetCustomPropertyNameAt, bool,
-                   ServoComputedValuesBorrowed, uint32_t index,
+                   ServoStyleContextBorrowed, uint32_t index,
                    nsAString* name)
 
 SERVO_BINDING_FUNC(Servo_GetEmptyVariables, const nsStyleVariables*)
 
 
 // AddRef / Release functions
 #define SERVO_ARC_TYPE(name_, type_)                                \
   SERVO_BINDING_FUNC(Servo_##name_##_AddRef, void, type_##Borrowed) \
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -388,25 +388,25 @@ Gecko_GetStyleContext(RawGeckoElementBor
 CSSPseudoElementType
 Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement)
 {
   return aElement->GetPseudoElementType();
 }
 
 nsChangeHint
 Gecko_CalcStyleDifference(nsStyleContext* aOldStyleContext,
-                          ServoComputedValuesBorrowed aComputedValues,
+                          ServoStyleContextBorrowed aComputedValues,
                           bool* aAnyStyleChanged)
 {
   MOZ_ASSERT(aOldStyleContext);
   MOZ_ASSERT(aComputedValues);
 
   uint32_t equalStructs, samePointerStructs;
   nsChangeHint result =
-    aOldStyleContext->CalcStyleDifference(aComputedValues,
+    aOldStyleContext->CalcStyleDifference(aComputedValues->ComputedValues(),
                                           &equalStructs,
                                           &samePointerStructs);
   *aAnyStyleChanged = equalStructs != NS_STYLE_INHERIT_MASK;
   return result;
 }
 
 nsChangeHint
 Gecko_HintsHandledForDescendants(nsChangeHint aHint)
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -374,17 +374,17 @@ void Gecko_SetOwnerDocumentNeedsStyleFlu
 
 // Incremental restyle.
 // Also, we might want a ComputedValues to ComputedValues API for animations?
 // Not if we do them in Gecko...
 nsStyleContext* Gecko_GetStyleContext(RawGeckoElementBorrowed element,
                                       nsIAtom* aPseudoTagOrNull);
 mozilla::CSSPseudoElementType Gecko_GetImplementedPseudo(RawGeckoElementBorrowed element);
 nsChangeHint Gecko_CalcStyleDifference(nsStyleContext* oldstyle,
-                                       ServoComputedValuesBorrowed newstyle,
+                                       ServoStyleContextBorrowed newstyle,
                                        bool* any_style_changed);
 nsChangeHint Gecko_HintsHandledForDescendants(nsChangeHint aHint);
 
 // Get an element snapshot for a given element from the table.
 const ServoElementSnapshot*
 Gecko_GetElementSnapshot(const mozilla::ServoElementSnapshotTable* table,
                          RawGeckoElementBorrowed element);
 
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -320,17 +320,17 @@ mapped-generic-types = [
     { 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<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>" },
     { generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
     { generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>" },
     { generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
     { generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::servo_arc::RawOffsetArc" },
-    { generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>" },
+    { generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>" },
 ]
 fixups = [
     { pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
 ]
 
 [bindings]
 headers = ["mozilla/ServoBindings.h"]
 hide-types = [
@@ -340,17 +340,17 @@ hide-types = [
     "ServoStyleContextBorrowedOrNull",
 ]
 raw-lines = [
     "pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};",
     "use gecko_bindings::structs::nsStyleTransformMatrix;",
     "use gecko_bindings::structs::nsTArray;",
     "type nsACString_internal = nsACString;",
     "type nsAString_internal = nsAString;",
-    "pub type ServoStyleContextBorrowed<'a> = &'a ServoStyleContext;",
+    "pub type ServoStyleContextBorrowed<'a> = &'a ::properties::ComputedValues;",
     "pub type ServoStyleContextBorrowedOrNull<'a> = Option<&'a ::properties::ComputedValues>;",
     "pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;",
     "pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;",
 ]
 whitelist-functions = ["Servo_.*", "Gecko_.*"]
 structs-types = [
     "mozilla::css::GridTemplateAreasValue",
     "mozilla::css::ErrorReporter",
--- a/layout/style/ServoStyleContext.cpp
+++ b/layout/style/ServoStyleContext.cpp
@@ -19,17 +19,17 @@ ServoStyleContext::ServoStyleContext(nsS
                                nsPresContext* aPresContext,
                                nsIAtom* aPseudoTag,
                                CSSPseudoElementType aPseudoType,
                               ServoComputedValuesForgotten aComputedValues)
   : nsStyleContext(aParent, aPseudoTag, aPseudoType),
     mSource(aComputedValues)
 {
   mPresContext = aPresContext;
-  AddStyleBit(Servo_ComputedValues_GetStyleBits(&mSource));
+  AddStyleBit(Servo_ComputedValues_GetStyleBits(this));
 
   FinishConstruction();
 
   // No need to call ApplyStyleFixups here, since fixups are handled by Servo when
   // producing the ServoComputedValues.
 }
 
 void
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -456,17 +456,17 @@ ServoStyleSet::ResolvePseudoElementStyle
   MOZ_ASSERT(computedValues);
 
   bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
                          aType == CSSPseudoElementType::after;
   computedValues->UpdateWithElementState(isBeforeOrAfter ? aOriginatingElement : nullptr);
   return computedValues.forget();
 }
 
-already_AddRefed<nsStyleContext>
+already_AddRefed<ServoStyleContext>
 ServoStyleSet::ResolveTransientStyle(Element* aElement,
                                      CSSPseudoElementType aPseudoType,
                                      nsIAtom* aPseudoTag,
                                      StyleRuleInclusion aRuleInclusion)
 {
   RefPtr<ServoStyleContext> result =
     ResolveTransientServoStyle(aElement, aPseudoType, aPseudoTag, aRuleInclusion);
   result->UpdateWithElementState(nullptr);
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -181,24 +181,24 @@ public:
                             CSSPseudoElementType aType,
                             ServoStyleContext* aParentContext,
                             dom::Element* aPseudoElement);
 
   // Resolves style for a (possibly-pseudo) Element without assuming that the
   // style has been resolved, and without worrying about setting the style
   // context up to live in the style context tree (a null parent is used).
   // |aPeudoTag| and |aPseudoType| must match.
-  already_AddRefed<nsStyleContext>
+  already_AddRefed<ServoStyleContext>
   ResolveTransientStyle(dom::Element* aElement,
                         CSSPseudoElementType aPseudoType,
                         nsIAtom* aPseudoTag,
                         StyleRuleInclusion aRules =
                           StyleRuleInclusion::All);
 
-  // Similar to ResolveTransientStyle() but returns ServoComputedValues.
+  // Similar to ResolveTransientStyle() but doesn't update the context state
   // Unlike ResolveServoStyle() this function calls PreTraverseSync().
   already_AddRefed<ServoStyleContext>
   ResolveTransientServoStyle(dom::Element* aElement,
                              CSSPseudoElementType aPseudoType,
                              nsIAtom* aPseudoTag,
                              StyleRuleInclusion aRules =
                                StyleRuleInclusion::All);
 
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -349,17 +349,17 @@ nsComputedDOMStyle::GetLength(uint32_t* 
 
   uint32_t length = GetComputedStyleMap()->Length();
 
   // Make sure we have up to date style so that we can include custom
   // properties.
   UpdateCurrentStyleSources(false);
   if (mStyleContext) {
     length += mStyleContext->IsServo()
-      ? Servo_GetCustomPropertiesCount(mStyleContext->ComputedValues())
+      ? Servo_GetCustomPropertiesCount(mStyleContext->AsServo())
       : StyleVariables()->mVariables.Count();
   }
 
   *aLength = length;
 
   ClearCurrentStyleSources();
 
   return NS_OK;
@@ -1089,26 +1089,25 @@ nsComputedDOMStyle::IndexedGetter(uint32
 
   bool isServo = mStyleContext->IsServo();
 
   const nsStyleVariables* variables = isServo
     ? nullptr
     : StyleVariables();
 
   const uint32_t count = isServo
-    ? Servo_GetCustomPropertiesCount(mStyleContext->ComputedValues())
+    ? Servo_GetCustomPropertiesCount(mStyleContext->AsServo())
     : variables->mVariables.Count();
 
   const uint32_t index = aIndex - length;
   if (index < count) {
     aFound = true;
     nsString varName;
     if (isServo) {
-      Servo_GetCustomPropertyNameAt(mStyleContext->ComputedValues(),
-                                    index, &varName);
+      Servo_GetCustomPropertyNameAt(mStyleContext->AsServo(), index, &varName);
     } else {
       variables->mVariables.GetVariableAt(index, varName);
     }
     aPropName.AssignLiteral("--");
     aPropName.Append(varName);
   } else {
     aFound = false;
   }
@@ -6944,18 +6943,17 @@ already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName)
 {
   MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName));
 
   nsString variableValue;
   const nsAString& name = Substring(aPropertyName,
                                     CSS_CUSTOM_NAME_PREFIX_LENGTH);
   bool present = mStyleContext->IsServo()
-    ? Servo_GetCustomPropertyValue(mStyleContext->ComputedValues(),
-                                   &name, &variableValue)
+    ? Servo_GetCustomPropertyValue(mStyleContext->AsServo(), &name, &variableValue)
     : StyleVariables()->mVariables.Get(name, variableValue);
   if (!present) {
     return nullptr;
   }
 
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
   val->SetString(variableValue);
 
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -222,17 +222,17 @@ nsStyleContext::CalcStyleDifferenceInter
       if (thisVariables->mVariables == otherVariables->mVariables) {
         *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
       }
     } else {
       *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
     }
   } else {
     if (Servo_ComputedValues_EqualCustomProperties(
-          ComputedValues(),
+          this->ComputedValues(),
           aNewContext->ComputedValues())) {
       *aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
     }
   }
 
   DebugOnly<int> styleStructCount = 1;  // count Variables already
 
   // Servo's optimization to stop the cascade when there are no style changes
--- a/servo/components/servo_arc/lib.rs
+++ b/servo/components/servo_arc/lib.rs
@@ -884,16 +884,22 @@ impl<'a, T> Clone for ArcBorrow<'a, T> {
 impl<'a, T> ArcBorrow<'a, T> {
     pub fn clone_arc(&self) -> Arc<T> {
         let arc = unsafe { Arc::from_raw(self.0) };
         // addref it!
         mem::forget(arc.clone());
         arc
     }
 
+    /// For constructing from a reference known to be Arc-backed,
+    /// e.g. if we obtain such a reference over FFI
+    pub unsafe fn from_ref(r: &'a T) -> Self {
+        ArcBorrow(r)
+    }
+
     pub fn with_arc<F, U>(&self, f: F) -> U where F: FnOnce(&Arc<T>) -> 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.
--- a/servo/components/style/gecko/arc_types.rs
+++ b/servo/components/style/gecko/arc_types.rs
@@ -8,23 +8,24 @@
 
 #![allow(non_snake_case, missing_docs)]
 
 use gecko_bindings::bindings::{RawServoImportRule, RawServoSupportsRule};
 use gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframesRule};
 use gecko_bindings::bindings::{RawServoMediaRule, RawServoNamespaceRule, RawServoPageRule};
 use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule};
 use gecko_bindings::bindings::ServoCssRules;
-use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock, RawServoStyleRule, RawServoMediaList};
-use gecko_bindings::structs::{RawServoStyleSheetContents, ServoStyleContext};
-use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
+use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock, RawServoStyleRule};
+use gecko_bindings::structs::{RawServoMediaList, RawServoStyleSheetContents};
+use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
 use media_queries::MediaList;
 use properties::{ComputedValues, PropertyDeclarationBlock};
 use properties::animated_properties::AnimationValue;
 use rule_tree::StrongRuleNode;
+use servo_arc::{Arc, ArcBorrow};
 use shared_lock::Locked;
 use std::{mem, ptr};
 use stylesheets::{CssRules, StylesheetContents, StyleRule, ImportRule, KeyframesRule, MediaRule};
 use stylesheets::{NamespaceRule, PageRule, SupportsRule, DocumentRule};
 use stylesheets::keyframes_rule::Keyframe;
 
 macro_rules! impl_arc_ffi {
     ($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
@@ -46,19 +47,16 @@ macro_rules! impl_arc_ffi {
 }
 
 impl_arc_ffi!(Locked<CssRules> => ServoCssRules
               [Servo_CssRules_AddRef, Servo_CssRules_Release]);
 
 impl_arc_ffi!(StylesheetContents => RawServoStyleSheetContents
               [Servo_StyleSheetContents_AddRef, Servo_StyleSheetContents_Release]);
 
-impl_arc_ffi!(ComputedValues => ServoStyleContext
-              [Servo_StyleContext_AddRef, Servo_StyleContext_Release]);
-
 impl_arc_ffi!(Locked<PropertyDeclarationBlock> => RawServoDeclarationBlock
               [Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]);
 
 impl_arc_ffi!(Locked<StyleRule> => RawServoStyleRule
               [Servo_StyleRule_AddRef, Servo_StyleRule_Release]);
 
 impl_arc_ffi!(Locked<ImportRule> => RawServoImportRule
               [Servo_ImportRule_AddRef, Servo_ImportRule_Release]);
@@ -109,8 +107,33 @@ pub unsafe extern "C" fn Servo_RuleNode_
     mem::forget(StrongRuleNode::from_ffi(&obj).clone());
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn Servo_RuleNode_Release(obj: &RawServoRuleNode) {
     let ptr = StrongRuleNode::from_ffi(&obj);
     ptr::read(ptr as *const StrongRuleNode);
 }
+
+// ServoStyleContext is not an opaque type on any side of FFI.
+// This means that doing the HasArcFFI type trick is actually unsound,
+// since it gives us a way to construct an Arc<ServoStyleContext> from
+// an &ServoStyleContext, which in general is not allowed. So we
+// implement the restricted set of arc type functionality we need.
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_StyleContext_AddRef(obj: &ComputedValues) {
+    mem::forget(ArcBorrow::from_ref(obj).clone());
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_StyleContext_Release(obj: &ComputedValues) {
+    ArcBorrow::from_ref(obj).with_arc(|a: &Arc<ComputedValues>| {
+      ptr::read(a);
+    });
+}
+
+
+impl From<Arc<ComputedValues>> for Strong<ComputedValues> {
+    fn from(arc: Arc<ComputedValues>) -> Self {
+        unsafe { mem::transmute(Arc::into_raw_offset(arc)) }
+    }
+}
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -1,16 +1,16 @@
 /* automatically generated by rust-bindgen */
 
 pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};
 use gecko_bindings::structs::nsStyleTransformMatrix;
 use gecko_bindings::structs::nsTArray;
 type nsACString_internal = nsACString;
 type nsAString_internal = nsAString;
-pub type ServoStyleContextBorrowed<'a> = &'a ServoStyleContext;
+pub type ServoStyleContextBorrowed<'a> = &'a ::properties::ComputedValues;
 pub type ServoStyleContextBorrowedOrNull<'a> = Option<&'a ::properties::ComputedValues>;
 pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
 pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
 use gecko_bindings::structs::mozilla::css::GridTemplateAreasValue;
 use gecko_bindings::structs::mozilla::css::ErrorReporter;
 use gecko_bindings::structs::mozilla::css::ImageValue;
 use gecko_bindings::structs::mozilla::css::URLValue;
 use gecko_bindings::structs::mozilla::css::URLValueData;
@@ -1037,17 +1037,17 @@ extern "C" {
      -> *mut nsStyleContext;
 }
 extern "C" {
     pub fn Gecko_GetImplementedPseudo(element: RawGeckoElementBorrowed)
      -> CSSPseudoElementType;
 }
 extern "C" {
     pub fn Gecko_CalcStyleDifference(oldstyle: *mut nsStyleContext,
-                                     newstyle: ServoComputedValuesBorrowed,
+                                     newstyle: ServoStyleContextBorrowed,
                                      any_style_changed: *mut bool)
      -> nsChangeHint;
 }
 extern "C" {
     pub fn Gecko_HintsHandledForDescendants(aHint: nsChangeHint)
      -> nsChangeHint;
 }
 extern "C" {
@@ -2304,17 +2304,17 @@ extern "C" {
     pub fn Servo_ComputedValues_ExtractAnimationValue(computed_values:
                                                           ServoStyleContextBorrowed,
                                                       property:
                                                           nsCSSPropertyID)
      -> RawServoAnimationValueStrong;
 }
 extern "C" {
     pub fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(computed_values:
-                                                                     ServoComputedValuesBorrowed)
+                                                                     ServoStyleContextBorrowed)
      -> bool;
 }
 extern "C" {
     pub fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool;
 }
 extern "C" {
     pub fn Servo_Property_IsTransitionable(property: nsCSSPropertyID) -> bool;
 }
@@ -2687,29 +2687,29 @@ extern "C" {
                                         pseudo_tag: *mut nsIAtom,
                                         parent_style:
                                             ServoStyleContextBorrowedOrNull,
                                         target: InheritTarget)
      -> ServoStyleContextStrong;
 }
 extern "C" {
     pub fn Servo_ComputedValues_GetStyleBits(values:
-                                                 ServoComputedValuesBorrowed)
+                                                 ServoStyleContextBorrowed)
      -> u64;
 }
 extern "C" {
     pub fn Servo_ComputedValues_EqualCustomProperties(first:
                                                           ServoComputedValuesBorrowed,
                                                       second:
                                                           ServoComputedValuesBorrowed)
      -> bool;
 }
 extern "C" {
     pub fn Servo_ComputedValues_GetStyleRuleList(values:
-                                                     ServoComputedValuesBorrowed,
+                                                     ServoStyleContextBorrowed,
                                                  rules:
                                                      RawGeckoServoStyleRuleListBorrowedMut);
 }
 extern "C" {
     pub fn Servo_Initialize(dummy_url_data: *mut RawGeckoURLExtraData);
 }
 extern "C" {
     pub fn Servo_Shutdown();
@@ -2786,27 +2786,27 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_SerializeFontValueForCanvas(declarations:
                                                  RawServoDeclarationBlockBorrowed,
                                              buffer: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_GetCustomPropertyValue(computed_values:
-                                            ServoComputedValuesBorrowed,
+                                            ServoStyleContextBorrowed,
                                         name: *const nsAString,
                                         value: *mut nsAString) -> bool;
 }
 extern "C" {
     pub fn Servo_GetCustomPropertiesCount(computed_values:
-                                              ServoComputedValuesBorrowed)
+                                              ServoStyleContextBorrowed)
      -> u32;
 }
 extern "C" {
-    pub fn Servo_GetCustomPropertyNameAt(arg1: ServoComputedValuesBorrowed,
+    pub fn Servo_GetCustomPropertyNameAt(arg1: ServoStyleContextBorrowed,
                                          index: u32, name: *mut nsAString)
      -> bool;
 }
 extern "C" {
     pub fn Servo_GetEmptyVariables() -> *const nsStyleVariables;
 }
 extern "C" {
     pub fn Gecko_CreateCSSErrorReporter(sheet: *mut ServoStyleSheet,
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -11,17 +11,17 @@ pub type ServoCell<T> = ::std::cell::Cel
 pub type ServoNodeData = AtomicRefCell<ElementData>;
 pub type ServoWritingMode = ::logical_geometry::WritingMode;
 pub type ServoFontComputationData = ::properties::FontComputationData;
 pub type ServoCustomPropertiesMap = Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>;
 pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
 pub type ServoVisitedStyle = Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>;
 pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
 pub type ServoRawOffsetArc<T> = ::servo_arc::RawOffsetArc<T>;
-pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>;
+pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>;
 
 #[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>);
     impl <T> __BindgenUnionField<T> {
         #[inline]
         pub fn new() -> Self {
@@ -41611,28 +41611,17 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsStyleContext> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::nsStyleContext>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsStyleContext> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_217() {
-        assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::nsStyleContext>>()
-                   , 8usize , concat ! (
-                   "Size of template specialization: " , stringify ! (
-                   root::already_AddRefed<root::nsStyleContext> ) ));
-        assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::nsStyleContext>>()
-                   , 8usize , concat ! (
-                   "Alignment of template specialization: " , stringify ! (
-                   root::already_AddRefed<root::nsStyleContext> ) ));
-    }
-    #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_218() {
+    fn __bindgen_test_layout_nsTArray_instantiation_154() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::ServoStyleSheet>>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::RefPtr<root::mozilla::ServoStyleSheet>>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::ServoStyleSheet>>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
--- a/servo/components/style/gecko/generated/structs_release.rs
+++ b/servo/components/style/gecko/generated/structs_release.rs
@@ -11,17 +11,17 @@ pub type ServoCell<T> = ::std::cell::Cel
 pub type ServoNodeData = AtomicRefCell<ElementData>;
 pub type ServoWritingMode = ::logical_geometry::WritingMode;
 pub type ServoFontComputationData = ::properties::FontComputationData;
 pub type ServoCustomPropertiesMap = Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>;
 pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
 pub type ServoVisitedStyle = Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>;
 pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
 pub type ServoRawOffsetArc<T> = ::servo_arc::RawOffsetArc<T>;
-pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>;
+pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>;
 
 #[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>);
     impl <T> __BindgenUnionField<T> {
         #[inline]
         pub fn new() -> Self {
@@ -40909,28 +40909,17 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsStyleContext> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::nsStyleContext>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsStyleContext> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_210() {
-        assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::nsStyleContext>>()
-                   , 8usize , concat ! (
-                   "Size of template specialization: " , stringify ! (
-                   root::already_AddRefed<root::nsStyleContext> ) ));
-        assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::nsStyleContext>>()
-                   , 8usize , concat ! (
-                   "Alignment of template specialization: " , stringify ! (
-                   root::already_AddRefed<root::nsStyleContext> ) ));
-    }
-    #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_211() {
+    fn __bindgen_test_layout_nsTArray_instantiation_153() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::ServoStyleSheet>>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::RefPtr<root::mozilla::ServoStyleSheet>>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::ServoStyleSheet>>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
--- a/servo/components/style/gecko_bindings/sugar/ownership.rs
+++ b/servo/components/style/gecko_bindings/sugar/ownership.rs
@@ -204,16 +204,17 @@ impl<GeckoType> Strong<GeckoType> {
         }
     }
 
     #[inline]
     /// Produces a null strong FFI reference.
     pub fn null() -> Self {
         unsafe { transmute(ptr::null::<GeckoType>()) }
     }
+
 }
 
 /// A few helpers implemented on top of Arc<ServoType> to make it more
 /// comfortable to use and write safe code with.
 pub unsafe trait FFIArcHelpers {
     /// The Rust FFI type that we're implementing methods for.
     type Inner: HasArcFFI;
 
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -218,17 +218,18 @@ impl ComputedValuesInner {
         self,
         pres_context: bindings::RawGeckoPresContextBorrowed,
         parent: ParentStyleContextInfo,
         pseudo_ty: structs::CSSPseudoElementType,
         pseudo_tag: *mut structs::nsIAtom
     ) -> Arc<ComputedValues> {
         let arc = unsafe {
             let arc: Arc<ComputedValues> = Arc::new(uninitialized());
-            bindings::Gecko_ServoStyleContext_Init(&arc.0 as *const _ as *mut _, parent, pres_context,
+            bindings::Gecko_ServoStyleContext_Init(&arc.0 as *const _ as *mut _,
+                                                   parent, pres_context,
                                                    &self, pseudo_ty, pseudo_tag);
             // We're simulating a move by having C++ do a memcpy and then forgetting
             // it on this end.
             forget(self);
             arc
         };
         arc
     }
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -98,16 +98,17 @@ use style::properties::{SKIP_ROOT_AND_IT
 use style::properties::animated_properties::{Animatable, AnimatableLonghand, AnimationValue};
 use style::properties::parse_one_declaration_into;
 use style::rule_tree::StyleSource;
 use style::selector_parser::PseudoElementCascadeType;
 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, ArcBorrow, RawOffsetArc};
 use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule};
 use style::stylesheets::{ImportRule, KeyframesRule, MallocSizeOfWithGuard, MediaRule};
 use style::stylesheets::{NamespaceRule, Origin, PageRule, StyleRule, SupportsRule};
 use style::stylesheets::StylesheetContents;
 use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
 use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
 use style::stylesheets::supports_rule::parse_condition_or_declaration;
 use style::stylist::RuleInclusion;
@@ -660,46 +661,46 @@ pub extern "C" fn Servo_StyleSet_GetBase
                                                                  computed_values: ServoStyleContextBorrowed,
                                                                  snapshots: *const ServoElementSnapshotTable,
                                                                  pseudo_type: CSSPseudoElementType)
                                                                  -> ServoStyleContextStrong
 {
     use style::style_resolver::StyleResolverForElement;
 
     debug_assert!(!snapshots.is_null());
-    let computed_values = ComputedValues::as_arc(&computed_values);
+    let computed_values = unsafe { ArcBorrow::from_ref(computed_values) };
 
     let rules = match computed_values.rules {
-        None => return computed_values.clone().into_strong(),
+        None => return computed_values.clone_arc().into(),
         Some(ref rules) => rules,
     };
 
     let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
     let without_animations =
         doc_data.stylist.rule_tree().remove_animation_rules(rules);
 
     if without_animations == *rules {
-        return computed_values.clone().into_strong();
+        return computed_values.clone_arc().into();
     }
 
     let element = GeckoElement(element);
 
     let element_data = match element.borrow_data() {
         Some(data) => data,
-        None => return computed_values.clone().into_strong(),
+        None => return computed_values.clone_arc().into(),
     };
     let styles = &element_data.styles;
 
     if let Some(pseudo) = PseudoElement::from_pseudo_type(pseudo_type) {
         // This style already doesn't have animations.
         return styles
             .pseudos
             .get(&pseudo)
             .expect("GetBaseComputedValuesForElement for an unexisting pseudo?")
-            .clone().into_strong();
+            .clone().into();
     }
 
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     let shared = create_shared_context(&global_style_data,
                                        &guard,
                                        &doc_data,
                                        TraversalFlags::empty(),
@@ -715,31 +716,30 @@ pub extern "C" fn Servo_StyleSet_GetBase
     let inputs =
         CascadeInputs {
             rules: Some(without_animations),
             visited_rules: None,
         };
 
     StyleResolverForElement::new(element, &mut context, RuleInclusion::All)
         .cascade_style_and_visited_with_default_parents(inputs)
-        .into_strong()
+        .into()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ComputedValues_ExtractAnimationValue(computed_values: ServoStyleContextBorrowed,
                                                              property_id: nsCSSPropertyID)
                                                              -> RawServoAnimationValueStrong
 {
     let property = match AnimatableLonghand::from_nscsspropertyid(property_id) {
         Some(longhand) => longhand,
         None => return Strong::null(),
     };
 
-    let computed_values = ComputedValues::as_arc(&computed_values);
-    Arc::new(AnimationValue::from_computed_values(&property, computed_values)).into_strong()
+    Arc::new(AnimationValue::from_computed_values(&property, &computed_values)).into_strong()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_Property_IsAnimatable(property: nsCSSPropertyID) -> bool {
     use style::properties::animated_properties;
     animated_properties::nscsspropertyid_is_animatable(property)
 }
 
@@ -1520,17 +1520,17 @@ pub extern "C" fn Servo_ComputedValues_G
         cascade_flags.insert(IS_FIELDSET_CONTENT);
     }
     let metrics = get_metrics_provider_for_product();
     data.stylist.precomputed_values_for_pseudo(
         &guards,
         &pseudo,
         parent_style_or_null.map(|x| &*x),
         cascade_flags, &metrics
-    ).into_strong()
+    ).into()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
                                            pseudo_type: CSSPseudoElementType,
                                            is_probe: bool,
                                            inherited_style: ServoStyleContextBorrowedOrNull,
                                            raw_data: RawServoStyleSetBorrowed)
@@ -1544,17 +1544,17 @@ pub extern "C" fn Servo_ResolvePseudoSty
            element, PseudoElement::from_pseudo_type(pseudo_type), is_probe);
 
     // FIXME(bholley): Assert against this.
     if !data.has_styles() {
         warn!("Calling Servo_ResolvePseudoStyle on unstyled element");
         return if is_probe {
             Strong::null()
         } else {
-            doc_data.default_computed_values().clone().into_strong()
+            doc_data.default_computed_values().clone().into()
         };
     }
 
     let pseudo = PseudoElement::from_pseudo_type(pseudo_type)
                     .expect("ResolvePseudoStyle with a non-pseudo?");
 
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
@@ -1565,36 +1565,35 @@ pub extern "C" fn Servo_ResolvePseudoSty
         RuleInclusion::All,
         &data.styles,
         inherited_style,
         &*doc_data,
         is_probe,
     );
 
     match style {
-        Some(s) => s.into_strong(),
+        Some(s) => s.into(),
         None => {
             debug_assert!(is_probe);
             Strong::null()
         }
     }
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_SetExplicitStyle(element: RawGeckoElementBorrowed,
                                          style: ServoStyleContextBorrowed)
 {
     let element = GeckoElement(element);
-    let style = ComputedValues::as_arc(&style);
     debug!("Servo_SetExplicitStyle: {:?}", element);
     // We only support this API for initial styling. There's no reason it couldn't
     // 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_arc());
+    data.styles.primary = Some(unsafe { ArcBorrow::from_ref(style) }.clone_arc());
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_HasAuthorSpecifiedRules(element: RawGeckoElementBorrowed,
                                                 rule_type_mask: u32,
                                                 author_colors_allowed: bool)
     -> bool
 {
@@ -1725,50 +1724,50 @@ pub extern "C" fn Servo_ComputedValues_I
         debug_assert!(!for_text);
         StyleBuilder::for_derived_style(
             data.stylist.device(),
             data.default_computed_values(),
             Some(&pseudo),
         ).build()
     };
 
-    style.into_strong()
+    style.into()
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ServoComputedValuesBorrowed) -> u64 {
+pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ServoStyleContextBorrowed) -> u64 {
     use style::properties::computed_value_flags::*;
     let flags = values.flags;
     let mut result = 0;
     if flags.contains(HAS_TEXT_DECORATION_LINES) {
         result |= structs::NS_STYLE_HAS_TEXT_DECORATION_LINES as u64;
     }
     if flags.contains(SHOULD_SUPPRESS_LINEBREAK) {
         result |= structs::NS_STYLE_SUPPRESS_LINEBREAK as u64;
     }
     result
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(values: ServoComputedValuesBorrowed)
+pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(values: ServoStyleContextBorrowed)
                                                                         -> bool {
     let b = values.get_box();
     b.specifies_animations() || b.specifies_transitions()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ComputedValues_EqualCustomProperties(
     first: ServoComputedValuesBorrowed,
     second: ServoComputedValuesBorrowed
 ) -> bool {
     first.get_custom_properties() == second.get_custom_properties()
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(values: ServoComputedValuesBorrowed,
+pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(values: ServoStyleContextBorrowed,
                                                         rules: RawGeckoServoStyleRuleListBorrowedMut) {
     if let Some(ref rule_node) = values.rules {
         let mut result = vec![];
         for node in rule_node.self_and_ancestors() {
             if let &StyleSource::Style(ref rule) = node.style_source() {
                 result.push(rule);
             }
         }
@@ -2799,17 +2798,17 @@ pub extern "C" fn Servo_ResolveStyle(ele
     // restyle hints other than animation hints.
     let flags = if restyle_behavior == Restyle::ForThrottledAnimationFlush {
         ANIMATION_ONLY
     } else {
         TraversalFlags::empty()
     };
     debug_assert!(element.has_current_styles_for_traversal(&*data, flags),
                   "Resolving style on element without current styles");
-    data.styles.primary().clone().into_strong()
+    data.styles.primary().clone().into()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
                                            pseudo_type: CSSPseudoElementType,
                                            rule_inclusion: StyleRuleInclusion,
                                            snapshots: *const ServoElementSnapshotTable,
                                            raw_data: RawServoStyleSetBorrowed)
@@ -2848,34 +2847,34 @@ pub extern "C" fn Servo_ResolveStyleLazi
         let styles = element.mutate_data().and_then(|d| {
             if d.has_styles() {
                 Some(finish(&d.styles))
             } else {
                 None
             }
         });
         if let Some(result) = styles {
-            return result.into_strong();
+            return result.into();
         }
     }
 
     // We don't have the style ready. Go ahead and compute it as necessary.
     let shared = create_shared_context(&global_style_data,
                                        &guard,
                                        &data,
                                        TraversalFlags::empty(),
                                        unsafe { &*snapshots });
     let mut tlc = ThreadLocalStyleContext::new(&shared);
     let mut context = StyleContext {
         shared: &shared,
         thread_local: &mut tlc,
     };
 
     let styles = resolve_style(&mut context, element, rule_inclusion);
-    finish(&styles).into_strong()
+    finish(&styles).into()
 }
 
 #[cfg(feature = "gecko_debug")]
 fn simulate_compute_values_failure(property: &PropertyValuePair) -> bool {
     let p = property.mProperty;
     let id = get_property_id_from_nscsspropertyid!(p, false);
     id.as_shorthand().is_ok() && property.mSimulateComputeValuesFailure
 }
@@ -2913,25 +2912,24 @@ pub extern "C" fn Servo_GetComputedKeyfr
                                                   raw_data: RawServoStyleSetBorrowed,
                                                   computed_keyframes: RawGeckoComputedKeyframeValuesListBorrowedMut)
 {
     use std::mem;
     use style::properties::LonghandIdSet;
 
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
     let metrics = get_metrics_provider_for_product();
-    let style = ComputedValues::as_arc(&style);
 
     let element = GeckoElement(element);
     let parent_element = element.inheritance_parent();
     let parent_data = parent_element.as_ref().and_then(|e| e.borrow_data());
     let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &**x);
 
     let pseudo = style.pseudo();
-    let mut context = create_context(&data, &metrics, style, parent_style, pseudo.as_ref());
+    let mut context = create_context(&data, &metrics, &style, parent_style, pseudo.as_ref());
 
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     let default_values = data.default_computed_values();
 
     for (index, keyframe) in keyframes.iter().enumerate() {
         let ref mut animation_values = computed_keyframes[index];
 
@@ -2995,25 +2993,24 @@ pub extern "C" fn Servo_GetComputedKeyfr
 #[no_mangle]
 pub extern "C" fn Servo_GetAnimationValues(declarations: RawServoDeclarationBlockBorrowed,
                                            element: RawGeckoElementBorrowed,
                                            style: ServoStyleContextBorrowed,
                                            raw_data: RawServoStyleSetBorrowed,
                                            animation_values: RawGeckoServoAnimationValueListBorrowedMut) {
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
     let metrics = get_metrics_provider_for_product();
-    let style = ComputedValues::as_arc(&style);
 
     let element = GeckoElement(element);
     let parent_element = element.inheritance_parent();
     let parent_data = parent_element.as_ref().and_then(|e| e.borrow_data());
     let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &**x);
 
     let pseudo = style.pseudo();
-    let mut context = create_context(&data, &metrics, style, parent_style, pseudo.as_ref());
+    let mut context = create_context(&data, &metrics, &style, parent_style, pseudo.as_ref());
 
     let default_values = data.default_computed_values();
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
 
     let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
     let guard = declarations.read_with(&guard);
     for (index, anim) in guard.to_animation_value_iter(&mut context, &default_values).enumerate() {
@@ -3025,17 +3022,16 @@ pub extern "C" fn Servo_GetAnimationValu
 #[no_mangle]
 pub extern "C" fn Servo_AnimationValue_Compute(element: RawGeckoElementBorrowed,
                                                declarations: RawServoDeclarationBlockBorrowed,
                                                style: ServoStyleContextBorrowed,
                                                raw_data: RawServoStyleSetBorrowed)
                                                -> RawServoAnimationValueStrong {
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
     let metrics = get_metrics_provider_for_product();
-    let style = ComputedValues::as_arc(&style);
 
     let element = GeckoElement(element);
     let parent_element = element.inheritance_parent();
     let parent_data = parent_element.as_ref().and_then(|e| e.borrow_data());
     let parent_style = parent_data.as_ref().map(|d| d.styles.primary()).map(|x| &**x);
 
     let pseudo = style.pseudo();
     let mut context = create_context(&data, &metrics, style, parent_style, pseudo.as_ref());
@@ -3294,17 +3290,17 @@ pub extern "C" fn Servo_StyleSet_Resolve
     };
 
     let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
 
     doc_data.stylist.compute_for_declarations(
         &guards,
         parent_style,
         declarations.clone_arc(),
-    ).into_strong()
+    ).into()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleSet_MightHaveAttributeDependency(
     raw_data: RawServoStyleSetBorrowed,
     element: RawGeckoElementBorrowed,
     local_name: *mut nsIAtom,
 ) -> bool {
@@ -3351,17 +3347,17 @@ pub extern "C" fn Servo_StyleSet_HasStat
             has_dep = has_dep || stylist.might_have_state_dependency(state);
         });
     }
 
     has_dep
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_GetCustomPropertyValue(computed_values: ServoComputedValuesBorrowed,
+pub extern "C" fn Servo_GetCustomPropertyValue(computed_values: ServoStyleContextBorrowed,
                                                name: *const nsAString,
                                                value: *mut nsAString) -> bool {
     let custom_properties = match computed_values.custom_properties() {
         Some(p) => p,
         None => return false,
     };
 
     let name = unsafe { Atom::from((&*name)) };
@@ -3370,25 +3366,25 @@ pub extern "C" fn Servo_GetCustomPropert
         None => return false,
     };
 
     computed_value.to_css(unsafe { value.as_mut().unwrap() }).unwrap();
     true
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_GetCustomPropertiesCount(computed_values: ServoComputedValuesBorrowed) -> u32 {
+pub extern "C" fn Servo_GetCustomPropertiesCount(computed_values: ServoStyleContextBorrowed) -> u32 {
     match computed_values.custom_properties() {
         Some(p) => p.len() as u32,
         None => 0,
     }
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_GetCustomPropertyNameAt(computed_values: ServoComputedValuesBorrowed,
+pub extern "C" fn Servo_GetCustomPropertyNameAt(computed_values: ServoStyleContextBorrowed,
                                                 index: u32,
                                                 name: *mut nsAString) -> bool {
     let custom_properties = match computed_values.custom_properties() {
         Some(p) => p,
         None => return false,
     };
 
     let property_name = match custom_properties.get_name_at(index) {