mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1709935 - Support XPCOM refcount logging with rust-xpcom, r=xpcom-reviewers,mccr8
Differential Revision: https://phabricator.services.mozilla.com/D115086
This commit is contained in:
parent
59028b25c8
commit
40a0ecc65f
@ -85,7 +85,7 @@ cubeb-remoting = ["cubeb-sys", "audioipc-client", "audioipc-server"]
|
||||
cubeb_coreaudio_rust = ["cubeb-sys", "cubeb-coreaudio"]
|
||||
cubeb_pulse_rust = ["cubeb-sys", "cubeb-pulse"]
|
||||
gecko_debug = ["geckoservo/gecko_debug", "nsstring/gecko_debug"]
|
||||
gecko_refcount_logging = ["geckoservo/gecko_refcount_logging"]
|
||||
gecko_refcount_logging = ["geckoservo/gecko_refcount_logging", "xpcom/gecko_refcount_logging"]
|
||||
simd-accel = ["encoding_glue/simd-accel", "jsrust_shared/simd-accel"]
|
||||
moz_memory = []
|
||||
moz_places = ["bookmark_sync"]
|
||||
|
@ -15,3 +15,4 @@ thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
|
||||
|
||||
[features]
|
||||
thread_sanitizer = []
|
||||
gecko_refcount_logging = []
|
||||
|
@ -319,3 +319,57 @@ impl AtomicRefcnt {
|
||||
self.0.load(Ordering::Acquire) as nsrefcnt
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko_refcount_logging")]
|
||||
pub mod trace_refcnt {
|
||||
use crate::interfaces::nsrefcnt;
|
||||
|
||||
extern "C" {
|
||||
pub fn NS_LogCtor(aPtr: *mut libc::c_void, aTypeName: *const libc::c_char, aSize: u32);
|
||||
pub fn NS_LogDtor(aPtr: *mut libc::c_void, aTypeName: *const libc::c_char, aSize: u32);
|
||||
pub fn NS_LogAddRef(
|
||||
aPtr: *mut libc::c_void,
|
||||
aRefcnt: nsrefcnt,
|
||||
aClass: *const libc::c_char,
|
||||
aClassSize: u32,
|
||||
);
|
||||
pub fn NS_LogRelease(
|
||||
aPtr: *mut libc::c_void,
|
||||
aRefcnt: nsrefcnt,
|
||||
aClass: *const libc::c_char,
|
||||
aClassSize: u32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// stub inline methods for the refcount logging functions for when the feature
|
||||
// is disabled.
|
||||
#[cfg(not(feature = "gecko_refcount_logging"))]
|
||||
pub mod trace_refcnt {
|
||||
use crate::interfaces::nsrefcnt;
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe extern "C" fn NS_LogCtor(_: *mut libc::c_void, _: *const libc::c_char, _: u32) {}
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe extern "C" fn NS_LogDtor(_: *mut libc::c_void, _: *const libc::c_char, _: u32) {}
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe extern "C" fn NS_LogAddRef(
|
||||
_: *mut libc::c_void,
|
||||
_: nsrefcnt,
|
||||
_: *const libc::c_char,
|
||||
_: u32,
|
||||
) {
|
||||
}
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
pub unsafe extern "C" fn NS_LogRelease(
|
||||
_: *mut libc::c_void,
|
||||
_: nsrefcnt,
|
||||
_: *const libc::c_char,
|
||||
_: u32,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +658,23 @@ fn xpcom(init: DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
coerce_impl.push(coerce);
|
||||
}
|
||||
|
||||
let size_for_logs = if real.generics.params.is_empty() {
|
||||
quote!(::std::mem::size_of::<Self>() as u32)
|
||||
} else {
|
||||
// Refcount logging requires all types with the same name to have the
|
||||
// same size, and generics aren't taken into account when creating our
|
||||
// name string, so we need to make sure that all possible instantiations
|
||||
// report the same size. To do that, we fake a size based on the number
|
||||
// of vtable pointers and the known refcount field.
|
||||
let fake_size_npointers = bases.len() + 1;
|
||||
quote!((::std::mem::size_of::<usize>() * #fake_size_npointers) as u32)
|
||||
};
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = real.generics.split_for_impl();
|
||||
let name_for_logs = quote!(
|
||||
concat!(module_path!(), "::", stringify!(#name #ty_generics), "\0").as_ptr()
|
||||
as *const ::xpcom::reexports::libc::c_char
|
||||
);
|
||||
Ok(quote! {
|
||||
#real
|
||||
|
||||
@ -695,12 +711,25 @@ fn xpcom(init: DeriveInput) -> Result<TokenStream, syn::Error> {
|
||||
|
||||
/// Automatically generated implementation of AddRef for nsISupports.
|
||||
#vis unsafe fn AddRef(&self) -> ::xpcom::interfaces::nsrefcnt {
|
||||
self.__refcnt.inc()
|
||||
let new = self.__refcnt.inc();
|
||||
::xpcom::trace_refcnt::NS_LogAddRef(
|
||||
self as *const _ as *mut ::xpcom::reexports::libc::c_void,
|
||||
new,
|
||||
#name_for_logs,
|
||||
#size_for_logs,
|
||||
);
|
||||
new
|
||||
}
|
||||
|
||||
/// Automatically generated implementation of Release for nsISupports.
|
||||
#vis unsafe fn Release(&self) -> ::xpcom::interfaces::nsrefcnt {
|
||||
let new = self.__refcnt.dec();
|
||||
::xpcom::trace_refcnt::NS_LogRelease(
|
||||
self as *const _ as *mut ::xpcom::reexports::libc::c_void,
|
||||
new,
|
||||
#name_for_logs,
|
||||
#size_for_logs,
|
||||
);
|
||||
if new == 0 {
|
||||
// dealloc
|
||||
::std::boxed::Box::from_raw(self as *const Self as *mut Self);
|
||||
|
Loading…
Reference in New Issue
Block a user