servo: Merge #15629 - stylo: Destroy static Variables struct on shutdown (from heycam:variables-leak); r=bholley,emilio
authorCameron McCormack <cam@mcc.id.au>
Sun, 19 Feb 2017 21:12:57 -0800
changeset 372786 7b8628e541b608ae2395791fc8dcfec6f2a931fe
parent 372785 94a6e5edb0753e088b04aeebef98e113d42d6770
child 372787 59356eed685503e5f2fb1445adbe0f520c41eed4
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley, emilio
bugs15629, 1340457
milestone54.0a1
servo: Merge #15629 - stylo: Destroy static Variables struct on shutdown (from heycam:variables-leak); r=bholley,emilio Fix for https://bugzilla.mozilla.org/show_bug.cgi?id=1340457. r? @emilio Source-Repo: https://github.com/servo/servo Source-Revision: 58aa6ce7aedfe93df7154e84676a52905f1709f5
servo/components/style/properties/gecko.mako.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -21,16 +21,17 @@ use gecko_bindings::bindings::Gecko_Copy
 use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
 % endfor
 use gecko_bindings::bindings::Gecko_Construct_nsStyleVariables;
 use gecko_bindings::bindings::Gecko_CopyCursorArrayFrom;
 use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom;
 use gecko_bindings::bindings::Gecko_CopyImageValueFrom;
 use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
 use gecko_bindings::bindings::Gecko_CopyListStyleTypeFrom;
+use gecko_bindings::bindings::Gecko_Destroy_nsStyleVariables;
 use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
 use gecko_bindings::bindings::Gecko_FontFamilyList_AppendGeneric;
 use gecko_bindings::bindings::Gecko_FontFamilyList_AppendNamed;
 use gecko_bindings::bindings::Gecko_FontFamilyList_Clear;
 use gecko_bindings::bindings::Gecko_SetCursorArrayLength;
 use gecko_bindings::bindings::Gecko_SetCursorImage;
 use gecko_bindings::bindings::Gecko_NewCSSShadowArray;
 use gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
@@ -3142,24 +3143,30 @@ pub unsafe extern "C" fn Servo_GetStyle$
 ${declare_style_struct(style_struct)}
 ${impl_style_struct(style_struct)}
 % if not style_struct.name in data.manual_style_structs:
 <%self:raw_impl_trait style_struct="${style_struct}"></%self:raw_impl_trait>
 % endif
 ${define_ffi_struct_accessor(style_struct)}
 % endfor
 
-lazy_static! {
-    static ref EMPTY_VARIABLES_STRUCT: nsStyleVariables = {
-        unsafe {
-            let mut variables: nsStyleVariables = unsafe { zeroed() };
-            Gecko_Construct_nsStyleVariables(&mut variables);
-            variables
-        }
-    };
-}
+// This is only accessed from the Gecko main thread.
+static mut EMPTY_VARIABLES_STRUCT: Option<nsStyleVariables> = None;
 
 #[no_mangle]
 #[allow(non_snake_case)]
 pub unsafe extern "C" fn Servo_GetStyleVariables(_cv: ServoComputedValuesBorrowedOrNull)
                                                  -> *const nsStyleVariables {
-    &*EMPTY_VARIABLES_STRUCT
+    EMPTY_VARIABLES_STRUCT.as_ref().unwrap()
 }
+
+pub fn initialize() {
+    unsafe {
+        EMPTY_VARIABLES_STRUCT = Some(zeroed());
+        Gecko_Construct_nsStyleVariables(EMPTY_VARIABLES_STRUCT.as_mut().unwrap());
+    }
+}
+
+pub fn shutdown() {
+    unsafe {
+        EMPTY_VARIABLES_STRUCT.take().as_mut().map(|v| Gecko_Destroy_nsStyleVariables(v));
+    }
+}
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -56,17 +56,17 @@ use style::gecko_bindings::structs::RawG
 use style::gecko_bindings::structs::RawServoAnimationValueBorrowedListBorrowed;
 use style::gecko_bindings::structs::ServoStyleSheet;
 use style::gecko_bindings::structs::nsCSSValueSharedList;
 use style::gecko_bindings::structs::nsTimingFunction;
 use style::gecko_bindings::structs::nsresult;
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI};
 use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
 use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
-use style::gecko_properties::style_structs;
+use style::gecko_properties::{self, style_structs};
 use style::keyframes::KeyframesStepValue;
 use style::parallel;
 use style::parser::{ParserContext, ParserContextExtraData};
 use style::properties::{ComputedValues, Importance, PropertyDeclaration};
 use style::properties::{PropertyDeclarationParseResult, PropertyDeclarationBlock, PropertyId};
 use style::properties::animated_properties::{AnimationValue, Interpolate, TransitionProperty};
 use style::properties::parse_one_declaration;
 use style::restyle_hints::{self, RestyleHint};
@@ -100,20 +100,25 @@ pub extern "C" fn Servo_Initialize() -> 
       _ => builder.parse(default_level).init().unwrap(),
     };
 
     // Pretend that we're a Servo Layout thread, to make some assertions happy.
     thread_state::initialize(thread_state::LAYOUT);
 
     // Perform some debug-only runtime assertions.
     restyle_hints::assert_restyle_hints_match();
+
+    // Initialize some static data.
+    gecko_properties::initialize();
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_Shutdown() -> () {
+    // Clear some static data to avoid shutdown leaks.
+    gecko_properties::shutdown();
 }
 
 fn create_shared_context(per_doc_data: &PerDocumentStyleDataImpl) -> SharedStyleContext {
     let local_context_data =
         ThreadLocalStyleContextCreationInfo::new(per_doc_data.new_animations_sender.clone());
 
     SharedStyleContext {
         // FIXME (bug 1303229): Use the actual viewport size here