Bug 1550377 - Use ManuallyDrop for style structs. r=jwatt
☠☠ backed out by 251671a74d95 ☠ ☠
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 14 May 2019 22:44:40 +0000
changeset 532698 2d0e8bded97ab21731f1577fcf093595aec62c22
parent 532697 db85e84612070c8cd9c75a7cc1b0a50bb5ed2d38
child 532699 9d6897b968f6cd1b1cf525f19a45843907a157e9
push id11270
push userrgurzau@mozilla.com
push dateWed, 15 May 2019 15:07:19 +0000
treeherdermozilla-beta@571bc76da583 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1550377
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1550377 - Use ManuallyDrop for style structs. r=jwatt We destroy them manually, so it's the right thing to do. This allows us to not run destructors of any members of nsStyle*, which in turn allows us to: * Remove the hack that replaced all nsStrings for nsStringReprs. * Remove ns{,C}StringRepr (followup) * Add members with destructors to the style structs (you see where I'm going :)). Differential Revision: https://phabricator.services.mozilla.com/D30450
layout/style/ServoBindings.toml
layout/style/ServoComputedData.h
layout/style/ServoComputedDataInlines.h
servo/components/style/properties/gecko.mako.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -486,19 +486,16 @@ mapped-generic-types = [
     { generic = true, gecko = "mozilla::RustCell", servo = "::std::cell::Cell" },
     { generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
     { generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
     { 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 = true, gecko = "mozilla::ServoManuallyDrop", servo = "::std::mem::ManuallyDrop" },
     { generic = false, gecko = "nsACString", servo = "nsstring::nsACString" },
     { generic = false, gecko = "nsAString", servo = "nsstring::nsAString" },
     { generic = false, gecko = "nsCString", servo = "nsstring::nsCString" },
-    { generic = false, gecko = "nsString", servo = "nsstring::nsStringRepr" },
+    { generic = false, gecko = "nsString", servo = "nsstring::nsString" },
 ]
 
 whitelist-functions = ["Servo_.*", "Gecko_.*"]
-
-fixups = [
-    { pat = "\\broot\\s*::\\s*nsTString\\s*<\\s*u16\\s*>", rep = "::nsstring::nsStringRepr" },
-]
--- a/layout/style/ServoComputedData.h
+++ b/layout/style/ServoComputedData.h
@@ -21,16 +21,25 @@ namespace mozilla {
 
 template <typename T>
 struct ServoRawOffsetArc {
   // This is a pointer to a T that lives inside a servo_arc::Arc<T>, and
   // which already has had its reference count incremented.
   T* mPtr;
 };
 
+// A wrapper that gets replaced by ManuallyDrop<T> by bindgen.
+//
+// NOTE(emilio): All this file is a bit gross, and most of this we make cleaner
+// using cbindgen and such.
+template <typename T>
+struct ServoManuallyDrop {
+  T mInner;
+};
+
 struct ServoWritingMode {
   uint8_t mBits;
 };
 
 struct ServoCustomPropertiesMap {
   uintptr_t mPtr;
 };
 
--- a/layout/style/ServoComputedDataInlines.h
+++ b/layout/style/ServoComputedDataInlines.h
@@ -8,22 +8,22 @@
 #define mozilla_ServoComputedDataInlines_h
 
 #include "mozilla/ServoComputedData.h"
 #include "nsStyleStruct.h"
 
 namespace mozilla {
 #define STYLE_STRUCT(name_) \
   struct Gecko##name_ {     \
-    nsStyle##name_ gecko;   \
+    ServoManuallyDrop<nsStyle##name_> gecko;   \
   };
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
 }  // namespace mozilla
 
 #define STYLE_STRUCT(name_)                                          \
   const nsStyle##name_* ServoComputedData::GetStyle##name_() const { \
-    return &name_.mPtr->gecko;                                       \
+    return &name_.mPtr->gecko.mInner;                                \
   }
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
 
 #endif  // mozilla_ServoComputedDataInlines_h
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -45,17 +45,17 @@ use crate::gecko::values::round_border_t
 use crate::logical_geometry::WritingMode;
 use crate::media_queries::Device;
 use crate::properties::computed_value_flags::*;
 use crate::properties::longhands;
 use crate::rule_tree::StrongRuleNode;
 use crate::selector_parser::PseudoElement;
 use servo_arc::{Arc, RawOffsetArc};
 use std::marker::PhantomData;
-use std::mem::{forget, uninitialized, zeroed};
+use std::mem::{forget, uninitialized, zeroed, ManuallyDrop};
 use std::{cmp, ops, ptr};
 use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
 use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty};
 use crate::values::computed::BorderStyle;
 use crate::values::computed::font::FontSize;
 use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow};
 use crate::values::generics::column::ColumnCount;
 use crate::values::generics::transform::TransformStyle;
@@ -1090,38 +1090,38 @@ pub fn clone_transform_from_list(
 <%def name="impl_logical(name, **kwargs)">
     ${helpers.logical_setter(name)}
 </%def>
 
 <%def name="impl_style_struct(style_struct)">
 impl ${style_struct.gecko_struct_name} {
     #[allow(dead_code, unused_variables)]
     pub fn default(document: &structs::Document) -> Arc<Self> {
-        let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: unsafe { zeroed() } });
+        let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: ManuallyDrop::new(unsafe { zeroed() }) });
         unsafe {
             Gecko_Construct_Default_${style_struct.gecko_ffi_name}(
-                &mut Arc::get_mut(&mut result).unwrap().gecko,
+                &mut *Arc::get_mut(&mut result).unwrap().gecko,
                 document,
             );
         }
         result
     }
 }
 impl Drop for ${style_struct.gecko_struct_name} {
     fn drop(&mut self) {
         unsafe {
-            Gecko_Destroy_${style_struct.gecko_ffi_name}(&mut self.gecko);
+            Gecko_Destroy_${style_struct.gecko_ffi_name}(&mut *self.gecko);
         }
     }
 }
 impl Clone for ${style_struct.gecko_struct_name} {
     fn clone(&self) -> Self {
         unsafe {
-            let mut result = ${style_struct.gecko_struct_name} { gecko: zeroed() };
-            Gecko_CopyConstruct_${style_struct.gecko_ffi_name}(&mut result.gecko, &self.gecko);
+            let mut result = ${style_struct.gecko_struct_name} { gecko: ManuallyDrop::new(zeroed()) };
+            Gecko_CopyConstruct_${style_struct.gecko_ffi_name}(&mut *result.gecko, &*self.gecko);
             result
         }
     }
 }
 
 </%def>
 
 <%def name="impl_simple_type_with_conversion(ident, gecko_ffi_name=None)">
@@ -1540,18 +1540,19 @@ fn static_assert() {
                     Some(self.gecko.${value.gecko}.mInteger)
                 },
         }
     }
     % endfor
 
     % for kind in ["rows", "columns"]:
     pub fn set_grid_auto_${kind}(&mut self, v: longhands::grid_auto_${kind}::computed_value::T) {
-        v.to_gecko_style_coords(&mut self.gecko.mGridAuto${kind.title()}Min,
-                                &mut self.gecko.mGridAuto${kind.title()}Max)
+        let gecko = &mut *self.gecko;
+        v.to_gecko_style_coords(&mut gecko.mGridAuto${kind.title()}Min,
+                                &mut gecko.mGridAuto${kind.title()}Max)
     }
 
     pub fn copy_grid_auto_${kind}_from(&mut self, other: &Self) {
         self.gecko.mGridAuto${kind.title()}Min.copy_from(&other.gecko.mGridAuto${kind.title()}Min);
         self.gecko.mGridAuto${kind.title()}Max.copy_from(&other.gecko.mGridAuto${kind.title()}Max);
     }
 
     pub fn reset_grid_auto_${kind}(&mut self, other: &Self) {
@@ -1561,24 +1562,24 @@ fn static_assert() {
     pub fn clone_grid_auto_${kind}(&self) -> longhands::grid_auto_${kind}::computed_value::T {
         crate::values::generics::grid::TrackSize::from_gecko_style_coords(&self.gecko.mGridAuto${kind.title()}Min,
                                                                      &self.gecko.mGridAuto${kind.title()}Max)
     }
 
     pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
         <% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
         use crate::gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine};
-        use nsstring::nsStringRepr;
+        use nsstring::nsString;
         use std::usize;
         use crate::values::CustomIdent;
         use crate::values::generics::grid::TrackListType::Auto;
         use crate::values::generics::grid::{GridTemplateComponent, RepeatCount};
 
         #[inline]
-        fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<nsStringRepr>) {
+        fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<nsString>) {
             unsafe {
                 bindings::Gecko_ResizeTArrayForStrings(gecko_names, servo_names.len() as u32);
             }
 
             for (servo_name, gecko_name) in servo_names.iter().zip(gecko_names.iter_mut()) {
                 gecko_name.assign(servo_name.0.as_slice());
             }
         }
@@ -1688,36 +1689,36 @@ fn static_assert() {
 
     pub fn reset_grid_template_${kind}(&mut self, other: &Self) {
         self.copy_grid_template_${kind}_from(other)
     }
 
     pub fn clone_grid_template_${kind}(&self) -> longhands::grid_template_${kind}::computed_value::T {
         <% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
         use crate::gecko_bindings::structs::nsTArray;
-        use nsstring::nsStringRepr;
+        use nsstring::nsString;
         use crate::values::CustomIdent;
         use crate::values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount};
         use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat, TrackSize};
 
         let value = match unsafe { ${self_grid}.mPtr.as_ref() } {
             None => return GridTemplateComponent::None,
             Some(value) => value,
         };
 
         #[inline]
-        fn to_boxed_customident_slice(gecko_names: &nsTArray<nsStringRepr>) -> Box<[CustomIdent]> {
+        fn to_boxed_customident_slice(gecko_names: &nsTArray<nsString>) -> Box<[CustomIdent]> {
             let idents: Vec<CustomIdent> = gecko_names.iter().map(|gecko_name| {
                 CustomIdent(Atom::from(gecko_name.to_string()))
             }).collect();
             idents.into_boxed_slice()
         }
 
         #[inline]
-        fn to_line_names_vec(gecko_line_names: &nsTArray<nsTArray<nsStringRepr>>)
+        fn to_line_names_vec(gecko_line_names: &nsTArray<nsTArray<nsString>>)
             -> Vec<Box<[CustomIdent]>> {
             gecko_line_names.iter().map(|gecko_names| {
                 to_boxed_customident_slice(gecko_names)
             }).collect()
         }
 
         let repeat_auto_index = value.mRepeatAutoIndex as usize;
         if value.mIsSubgrid() {
@@ -2124,24 +2125,24 @@ fn static_assert() {
         T::from_gecko_adjust(self.gecko.mFont.sizeAdjust)
     }
 
     #[allow(non_snake_case)]
     pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) {
         let ptr = v.0.as_ptr();
         forget(v);
         unsafe {
-            Gecko_nsStyleFont_SetLang(&mut self.gecko, ptr);
+            Gecko_nsStyleFont_SetLang(&mut *self.gecko, ptr);
         }
     }
 
     #[allow(non_snake_case)]
     pub fn copy__x_lang_from(&mut self, other: &Self) {
         unsafe {
-            Gecko_nsStyleFont_CopyLangFrom(&mut self.gecko, &other.gecko);
+            Gecko_nsStyleFont_CopyLangFrom(&mut *self.gecko, &*other.gecko);
         }
     }
 
     #[allow(non_snake_case)]
     pub fn reset__x_lang(&mut self, other: &Self) {
         self.copy__x_lang_from(other)
     }
 
@@ -2514,17 +2515,17 @@ fn static_assert() {
                           transform-style
                           rotate scroll-snap-points-x scroll-snap-points-y
                           scroll-snap-coordinate -moz-binding will-change
                           offset-path shape-outside
                           translate scale -webkit-line-clamp""" %>
 <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
     #[inline]
     pub fn generate_combined_transform(&mut self) {
-        unsafe { bindings::Gecko_StyleDisplay_GenerateCombinedTransform(&mut self.gecko) };
+        unsafe { bindings::Gecko_StyleDisplay_GenerateCombinedTransform(&mut *self.gecko) };
     }
 
     #[inline]
     pub fn set_display(&mut self, v: longhands::display::computed_value::T) {
         self.gecko.mDisplay = v;
         self.gecko.mOriginalDisplay = v;
     }
 
@@ -2831,42 +2832,42 @@ fn static_assert() {
 
     pub fn set_will_change(&mut self, v: longhands::will_change::computed_value::T) {
         use crate::gecko_bindings::bindings::{Gecko_AppendWillChange, Gecko_ClearWillChange};
         use crate::values::specified::box_::{WillChangeBits, WillChange};
 
         match v {
             WillChange::AnimateableFeatures { features, bits } => {
                 unsafe {
-                    Gecko_ClearWillChange(&mut self.gecko, features.len());
+                    Gecko_ClearWillChange(&mut *self.gecko, features.len());
                 }
 
                 for feature in features.iter() {
                     unsafe {
-                        Gecko_AppendWillChange(&mut self.gecko, feature.0.as_ptr())
+                        Gecko_AppendWillChange(&mut *self.gecko, feature.0.as_ptr())
                     }
                 }
 
                 self.gecko.mWillChangeBitField = bits;
             },
             WillChange::Auto => {
                 unsafe {
-                    Gecko_ClearWillChange(&mut self.gecko, 0);
+                    Gecko_ClearWillChange(&mut *self.gecko, 0);
                 }
                 self.gecko.mWillChangeBitField = WillChangeBits::empty();
             },
         };
     }
 
     pub fn copy_will_change_from(&mut self, other: &Self) {
         use crate::gecko_bindings::bindings::Gecko_CopyWillChangeFrom;
 
         self.gecko.mWillChangeBitField = other.gecko.mWillChangeBitField;
         unsafe {
-            Gecko_CopyWillChangeFrom(&mut self.gecko, &other.gecko);
+            Gecko_CopyWillChangeFrom(&mut *self.gecko, &*other.gecko);
         }
     }
 
     pub fn reset_will_change(&mut self, other: &Self) {
         self.copy_will_change_from(other)
     }
 
     pub fn clone_will_change(&self) -> longhands::will_change::computed_value::T {
@@ -3302,32 +3303,32 @@ fn static_assert() {
 
 <%self:impl_trait style_struct_name="List"
                   skip_longhands="list-style-image list-style-type quotes -moz-image-region">
 
     pub fn set_list_style_image(&mut self, image: longhands::list_style_image::computed_value::T) {
         match image {
             UrlOrNone::None => {
                 unsafe {
-                    Gecko_SetListStyleImageNone(&mut self.gecko);
+                    Gecko_SetListStyleImageNone(&mut *self.gecko);
                 }
             }
             UrlOrNone::Url(ref url) => {
                 unsafe {
                     Gecko_SetListStyleImageImageValue(
-                        &mut self.gecko,
+                        &mut *self.gecko,
                         url.url_value_ptr(),
                     );
                 }
             }
         }
     }
 
     pub fn copy_list_style_image_from(&mut self, other: &Self) {
-        unsafe { Gecko_CopyListStyleImageFrom(&mut self.gecko, &other.gecko); }
+        unsafe { Gecko_CopyListStyleImageFrom(&mut *self.gecko, &*other.gecko); }
     }
 
     pub fn reset_list_style_image(&mut self, other: &Self) {
         self.copy_list_style_image_from(other)
     }
 
     pub fn clone_list_style_image(&self) -> longhands::list_style_image::computed_value::T {
         use crate::values::computed::url::ComputedImageUrl;
@@ -3639,17 +3640,17 @@ fn static_assert() {
 
         fn fill_filter(m_type: u32, value: CoordDataValue, gecko_filter: &mut nsStyleFilter){
             gecko_filter.mType = m_type;
             gecko_filter.mFilterParameter.set_value(value);
         }
 
         let v = v.into_iter();
         unsafe {
-            Gecko_ResetFilters(&mut self.gecko, v.len());
+            Gecko_ResetFilters(&mut *self.gecko, v.len());
         }
         debug_assert_eq!(v.len(), self.gecko.mFilters.len());
 
         for (servo, gecko_filter) in v.zip(self.gecko.mFilters.iter_mut()) {
             match servo {
                 % for func in FILTER_FUNCTIONS:
                 ${func}(factor) => fill_filter(NS_STYLE_FILTER_${func.upper()},
                                                CoordDataValue::Factor(factor.0),
@@ -3685,17 +3686,17 @@ fn static_assert() {
                     }
                 },
             }
         }
     }
 
     pub fn copy_filter_from(&mut self, other: &Self) {
         unsafe {
-            Gecko_CopyFiltersFrom(&other.gecko as *const _ as *mut _, &mut self.gecko);
+            Gecko_CopyFiltersFrom(&other.gecko as *const _ as *mut _, &mut *self.gecko);
         }
     }
 
     pub fn reset_filter(&mut self, other: &Self) {
         self.copy_filter_from(other)
     }
 
     pub fn clone_filter(&self) -> longhands::filter::computed_value::T {
@@ -4134,35 +4135,35 @@ clip-path
         use crate::gecko_bindings::structs::nsStyleSVG_STROKE_DASHARRAY_CONTEXT as CONTEXT_VALUE;
         use crate::values::generics::svg::SVGStrokeDashArray;
 
         match v {
             SVGStrokeDashArray::Values(v) => {
                 let v = v.into_iter();
                 self.gecko.mContextFlags &= !CONTEXT_VALUE;
                 unsafe {
-                    bindings::Gecko_nsStyleSVG_SetDashArrayLength(&mut self.gecko, v.len() as u32);
+                    bindings::Gecko_nsStyleSVG_SetDashArrayLength(&mut *self.gecko, v.len() as u32);
                 }
                 for (gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v) {
                     *gecko = servo;
                 }
             }
             SVGStrokeDashArray::ContextValue => {
                 self.gecko.mContextFlags |= CONTEXT_VALUE;
                 unsafe {
-                    bindings::Gecko_nsStyleSVG_SetDashArrayLength(&mut self.gecko, 0);
+                    bindings::Gecko_nsStyleSVG_SetDashArrayLength(&mut *self.gecko, 0);
                 }
             }
         }
     }
 
     pub fn copy_stroke_dasharray_from(&mut self, other: &Self) {
         use crate::gecko_bindings::structs::nsStyleSVG_STROKE_DASHARRAY_CONTEXT as CONTEXT_VALUE;
         unsafe {
-            bindings::Gecko_nsStyleSVG_CopyDashArray(&mut self.gecko, &other.gecko);
+            bindings::Gecko_nsStyleSVG_CopyDashArray(&mut *self.gecko, &*other.gecko);
         }
         self.gecko.mContextFlags =
             (self.gecko.mContextFlags & !CONTEXT_VALUE) |
             (other.gecko.mContextFlags & CONTEXT_VALUE);
     }
 
     pub fn reset_stroke_dasharray(&mut self, other: &Self) {
         self.copy_stroke_dasharray_from(other)
@@ -4199,17 +4200,17 @@ clip-path
     #[allow(non_snake_case)]
     pub fn set__moz_context_properties<I>(&mut self, v: I)
     where
         I: IntoIterator<Item = longhands::_moz_context_properties::computed_value::single_value::T>,
         I::IntoIter: ExactSizeIterator
     {
         let v = v.into_iter();
         unsafe {
-            bindings::Gecko_nsStyleSVG_SetContextPropertiesLength(&mut self.gecko, v.len() as u32);
+            bindings::Gecko_nsStyleSVG_SetContextPropertiesLength(&mut *self.gecko, v.len() as u32);
         }
 
         self.gecko.mContextPropsBits = 0;
         for (gecko, servo) in self.gecko.mContextProps.iter_mut().zip(v) {
             if (servo.0).0 == atom!("fill") {
                 self.gecko.mContextPropsBits |= structs::NS_STYLE_CONTEXT_PROPERTY_FILL as u8;
             } else if (servo.0).0 == atom!("stroke") {
                 self.gecko.mContextPropsBits |= structs::NS_STYLE_CONTEXT_PROPERTY_STROKE as u8;
@@ -4220,34 +4221,34 @@ clip-path
             }
             gecko.mRawPtr = (servo.0).0.into_addrefed();
         }
     }
 
     #[allow(non_snake_case)]
     pub fn copy__moz_context_properties_from(&mut self, other: &Self) {
         unsafe {
-            bindings::Gecko_nsStyleSVG_CopyContextProperties(&mut self.gecko, &other.gecko);
+            bindings::Gecko_nsStyleSVG_CopyContextProperties(&mut *self.gecko, &*other.gecko);
         }
     }
 
     #[allow(non_snake_case)]
     pub fn reset__moz_context_properties(&mut self, other: &Self) {
         self.copy__moz_context_properties_from(other)
     }
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="Color">
 </%self:impl_trait>
 
 <%self:impl_trait style_struct_name="InheritedUI" skip_longhands="cursor">
     pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
         self.gecko.mCursor = v.keyword;
         unsafe {
-            Gecko_SetCursorArrayLength(&mut self.gecko, v.images.len());
+            Gecko_SetCursorArrayLength(&mut *self.gecko, v.images.len());
         }
         for i in 0..v.images.len() {
             unsafe {
                 Gecko_SetCursorImageValue(
                     &mut self.gecko.mCursorImages[i],
                     v.images[i].url.url_value_ptr(),
                 );
             }
@@ -4263,17 +4264,17 @@ clip-path
                 }
             }
         }
     }
 
     pub fn copy_cursor_from(&mut self, other: &Self) {
         self.gecko.mCursor = other.gecko.mCursor;
         unsafe {
-            Gecko_CopyCursorArrayFrom(&mut self.gecko, &other.gecko);
+            Gecko_CopyCursorArrayFrom(&mut *self.gecko, &*other.gecko);
         }
     }
 
     pub fn reset_cursor(&mut self, other: &Self) {
         self.copy_cursor_from(other)
     }
 
     pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T {
@@ -4382,30 +4383,30 @@ clip-path
         }
 
         match v {
             Content::None |
             Content::Normal => {
                 // Ensure destructors run, otherwise we could leak.
                 if !self.gecko.mContents.is_empty() {
                     unsafe {
-                        Gecko_ClearAndResizeStyleContents(&mut self.gecko, 0);
+                        Gecko_ClearAndResizeStyleContents(&mut *self.gecko, 0);
                     }
                 }
             },
             Content::MozAltContent => {
                 unsafe {
-                    Gecko_ClearAndResizeStyleContents(&mut self.gecko, 1);
+                    Gecko_ClearAndResizeStyleContents(&mut *self.gecko, 1);
                     *self.gecko.mContents[0].mContent.mString.as_mut() = ptr::null_mut();
                 }
                 self.gecko.mContents[0].mType = StyleContentType::AltContent;
             },
             Content::Items(items) => {
                 unsafe {
-                    Gecko_ClearAndResizeStyleContents(&mut self.gecko,
+                    Gecko_ClearAndResizeStyleContents(&mut *self.gecko,
                                                       items.len() as u32);
                 }
                 for (i, item) in items.into_vec().into_iter().enumerate() {
                     // NB: Gecko compares the mString value if type is not image
                     // or URI independently of whatever gets there. In the quote
                     // cases, they set it to null, so do the same here.
                     unsafe {
                         *self.gecko.mContents[i].mContent.mString.as_mut() = ptr::null_mut();
@@ -4476,17 +4477,17 @@ clip-path
                 }
             }
         }
     }
 
     pub fn copy_content_from(&mut self, other: &Self) {
         use crate::gecko_bindings::bindings::Gecko_CopyStyleContentsFrom;
         unsafe {
-            Gecko_CopyStyleContentsFrom(&mut self.gecko, &other.gecko)
+            Gecko_CopyStyleContentsFrom(&mut *self.gecko, &*other.gecko)
         }
     }
 
     pub fn reset_content(&mut self, other: &Self) {
         self.copy_content_from(other)
     }
 
     pub fn clone_content(&self) -> longhands::content::computed_value::T {
@@ -4570,29 +4571,29 @@ clip-path
     }
 
     % for counter_property in ["Increment", "Reset", "Set"]:
         pub fn set_counter_${counter_property.lower()}(
             &mut self,
             v: longhands::counter_${counter_property.lower()}::computed_value::T
         ) {
             unsafe {
-                bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut self.gecko, v.len() as u32);
+                bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut *self.gecko, v.len() as u32);
                 for (i, pair) in v.0.into_vec().into_iter().enumerate() {
                     self.gecko.m${counter_property}s[i].mCounter.set_move(
                         RefPtr::from_addrefed(pair.name.0.into_addrefed())
                     );
                     self.gecko.m${counter_property}s[i].mValue = pair.value;
                 }
             }
         }
 
         pub fn copy_counter_${counter_property.lower()}_from(&mut self, other: &Self) {
             unsafe {
-                bindings::Gecko_CopyCounter${counter_property}sFrom(&mut self.gecko, &other.gecko)
+                bindings::Gecko_CopyCounter${counter_property}sFrom(&mut *self.gecko, &*other.gecko)
             }
         }
 
         pub fn reset_counter_${counter_property.lower()}(&mut self, other: &Self) {
             self.copy_counter_${counter_property.lower()}_from(other)
         }
 
         pub fn clone_counter_${counter_property.lower()}(
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 use super::error_reporter::ErrorReporter;
 use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader};
 use cssparser::ToCss as ParserToCss;
 use cssparser::{ParseErrorKind, Parser, ParserInput, SourceLocation, UnicodeRange};
 use malloc_size_of::MallocSizeOfOps;
-use nsstring::{nsCString, nsString, nsStringRepr};
+use nsstring::{nsCString, nsString};
 use selectors::matching::{matches_selector, MatchingContext, MatchingMode};
 use selectors::{NthIndexCache, SelectorList};
 use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
 use smallvec::SmallVec;
 use std::cell::RefCell;
 use std::collections::BTreeSet;
 use std::fmt::Write;
 use std::iter;
@@ -1143,19 +1143,17 @@ pub unsafe extern "C" fn Servo_Property_
     if values.contains("transparent") {
         // This is a special value devtools use to avoid inserting the
         // long list of color keywords. We need to prepend it to values.
         extras.push("COLOR");
     }
 
     let result = result.as_mut().unwrap();
     let len = extras.len() + values.len();
-    // FIXME(emilio): This is one place where our nsString -> nsStringRepr
-    // conversion during bindgen goes bad.
-    bindings::Gecko_ResizeTArrayForStrings(result as *mut _ as *mut nsTArray<nsStringRepr>, len as u32);
+    bindings::Gecko_ResizeTArrayForStrings(result as *mut _ as *mut nsTArray<nsString>, len as u32);
 
     for (src, dest) in extras.iter().chain(values.iter()).zip(result.iter_mut()) {
         dest.write_str(src).unwrap();
     }
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_Property_IsAnimatable(prop: nsCSSPropertyID) -> bool {