Bug 1334579: Integrate nsstring bindings with leak logging. r?mystor draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 27 Jan 2017 21:12:22 +0100
changeset 467524 2bcd687729246fb17a78f8351f32eec6e32ef819
parent 466877 d1ea331c6ec7d2a11520ccdf3aca1539a14b5c9b
child 543706 675933ea7ace1219496aba4a234033016030d830
push id43199
push userbmo:emilio+bugs@crisal.io
push dateFri, 27 Jan 2017 22:37:58 +0000
reviewersmystor
bugs1334579
milestone54.0a1
Bug 1334579: Integrate nsstring bindings with leak logging. r?mystor MozReview-Commit-ID: 368DwwuaMqr
xpcom/rust/nsstring/src/lib.rs
xpcom/string/nsSubstring.cpp
--- a/xpcom/rust/nsstring/src/lib.rs
+++ b/xpcom/rust/nsstring/src/lib.rs
@@ -137,16 +137,17 @@ use std::ops::{Deref, DerefMut};
 use std::marker::PhantomData;
 use std::slice;
 use std::ptr;
 use std::mem;
 use std::fmt;
 use std::cmp;
 use std::str;
 use std::u32;
+use std::os::raw::c_void;
 
 //////////////////////////////////
 // Internal Implemenation Flags //
 //////////////////////////////////
 
 const F_NONE: u32 = 0; // no flags
 
 // data flags are in the lower 16-bits
@@ -357,16 +358,19 @@ macro_rules! define_string_types {
                 // SAFETY NOTE: This method produces an F_OWNED ns[C]String from
                 // a Box<[$char_t]>. this is only safe because in the Gecko
                 // tree, we use the same allocator for Rust code as for C++
                 // code, meaning that our box can be legally freed with
                 // libc::free().
                 let length = s.len() as u32;
                 let ptr = s.as_ptr();
                 mem::forget(s);
+                unsafe {
+                    Gecko_IncrementStringAdoptCount(ptr as *mut _);
+                }
                 $String {
                     hdr: $StringRepr {
                         data: ptr,
                         length: length,
                         flags: F_OWNED,
                     },
                     _marker: PhantomData,
                 }
@@ -757,19 +761,26 @@ impl cmp::PartialEq<str> for nsAString {
 #[macro_export]
 macro_rules! ns_auto_string {
     ($name:ident) => {
         let mut buf: [u16; 64] = [0; 64];
         let mut $name = $crate::nsFixedString::new(&mut buf);
     }
 }
 
+#[cfg(not(debug_assertions))]
+#[allow(non_snake_case)]
+unsafe fn Gecko_IncrementStringAdoptCount(_: *mut c_void) {}
+
 // NOTE: These bindings currently only expose infallible operations. Perhaps
 // consider allowing for fallible methods?
 extern "C" {
+    #[cfg(debug_assertions)]
+    fn Gecko_IncrementStringAdoptCount(data: *mut c_void);
+
     // Gecko implementation in nsSubstring.cpp
     fn Gecko_FinalizeCString(this: *mut nsACString);
     fn Gecko_AssignCString(this: *mut nsACString, other: *const nsACString);
     fn Gecko_AppendCString(this: *mut nsACString, other: *const nsACString);
     fn Gecko_TruncateCString(this: *mut nsACString);
 
     fn Gecko_FinalizeString(this: *mut nsAString);
     fn Gecko_AssignString(this: *mut nsAString, other: *const nsAString);
--- a/xpcom/string/nsSubstring.cpp
+++ b/xpcom/string/nsSubstring.cpp
@@ -350,16 +350,24 @@ nsStringBuffer::SizeOfIncludingThisEvenI
 #include "nsXPCOMStrings.h"
 
 static_assert(sizeof(nsStringContainer_base) == sizeof(nsSubstring),
               "internal and external strings must have the same size");
 
 // Provide rust bindings to the nsA[C]String types
 extern "C" {
 
+#ifdef DEBUG
+// This is a no-op on release, let's ensure it gives a linker error.
+void Gecko_IncrementStringAdoptCount(void* aData)
+{
+  MOZ_LOG_CTOR(aData, "StringAdopt", 1);
+}
+#endif
+
 void Gecko_FinalizeCString(nsACString* aThis)
 {
   aThis->~nsACString();
 }
 
 void Gecko_AssignCString(nsACString* aThis, const nsACString* aOther)
 {
   aThis->Assign(*aOther);