Bug 1896607 - FOG: Memory reporter on the Rust side. r=chutten
This sets up the scaffolding on the Rust side and calls that from the C++ side. To start it only measures the size of pings. This requires a Glean update that implements all that malloc_size_of. Differential Revision: https://phabricator.services.mozilla.com/D210288
This commit is contained in:
committed by
jrediger@mozilla.com
parent
9888dfdbf9
commit
9c8e0c6df6
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1967,6 +1967,7 @@ dependencies = [
|
|||||||
"inherent",
|
"inherent",
|
||||||
"log",
|
"log",
|
||||||
"mozbuild",
|
"mozbuild",
|
||||||
|
"nserror",
|
||||||
"nsstring",
|
"nsstring",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1975,6 +1976,7 @@ dependencies = [
|
|||||||
"thin-vec",
|
"thin-vec",
|
||||||
"time 0.1.45",
|
"time 0.1.45",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
"wr_malloc_size_of",
|
||||||
"xpcom",
|
"xpcom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ xpcom = { path = "../../../../xpcom/rust/xpcom", optional = true }
|
|||||||
thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
|
thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
|
||||||
mozbuild = "0.1"
|
mozbuild = "0.1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
nserror = { path = "../../../../xpcom/rust/nserror" }
|
||||||
|
malloc_size_of = { path = "../../../../gfx/wr/wr_malloc_size_of", package = "wr_malloc_size_of", features = ["once_cell"] }
|
||||||
|
|
||||||
# Note, we will want to remove this when Bug 1925313 is fixed
|
# Note, we will want to remove this when Bug 1925313 is fixed
|
||||||
[dependencies.time]
|
[dependencies.time]
|
||||||
|
|||||||
@@ -25,3 +25,58 @@ pub mod ipc;
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod common_test;
|
mod common_test;
|
||||||
|
|
||||||
|
#[cfg(feature = "with_gecko")]
|
||||||
|
use nserror::{NS_ERROR_UNEXPECTED, NS_OK};
|
||||||
|
#[cfg(feature = "with_gecko")]
|
||||||
|
use nsstring::{nsACString, nsCStr};
|
||||||
|
#[cfg(feature = "with_gecko")]
|
||||||
|
use xpcom::interfaces::{nsIHandleReportCallback, nsIMemoryReporter, nsISupports};
|
||||||
|
#[cfg(feature = "with_gecko")]
|
||||||
|
use xpcom::RefPtr;
|
||||||
|
|
||||||
|
/// Collect a memory report for heap memory in bytes.
|
||||||
|
#[cfg(feature = "with_gecko")]
|
||||||
|
macro_rules! moz_collect_report {
|
||||||
|
($cb:ident, $path:expr, $amount:expr, $desc:expr, $data:expr) => {
|
||||||
|
$cb.Callback(
|
||||||
|
&nsCStr::new() as &nsACString,
|
||||||
|
&nsCStr::from($path) as &nsACString,
|
||||||
|
nsIMemoryReporter::KIND_HEAP,
|
||||||
|
nsIMemoryReporter::UNITS_BYTES,
|
||||||
|
$amount as i64,
|
||||||
|
&nsCStr::from($desc) as &nsACString,
|
||||||
|
$data,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "with_gecko")]
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn fog_collect_reports(
|
||||||
|
callback: *const nsIHandleReportCallback,
|
||||||
|
data: *const nsISupports,
|
||||||
|
_anonymize: bool,
|
||||||
|
) -> nserror::nsresult {
|
||||||
|
let callback = match RefPtr::from_raw(callback) {
|
||||||
|
Some(ptr) => ptr,
|
||||||
|
None => return NS_ERROR_UNEXPECTED,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn fog_malloc_size_of(ptr: *const xpcom::reexports::libc::c_void) -> usize;
|
||||||
|
}
|
||||||
|
let mut ops = malloc_size_of::MallocSizeOfOps::new(fog_malloc_size_of, None);
|
||||||
|
|
||||||
|
let ping_size = pings::fog_ping_alloc_size(&mut ops);
|
||||||
|
|
||||||
|
moz_collect_report!(
|
||||||
|
callback,
|
||||||
|
"explicit/fog/pings",
|
||||||
|
ping_size,
|
||||||
|
"Memory used by all FOG pings",
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
NS_OK
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ pub enum Ping {
|
|||||||
Child,
|
Child,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl malloc_size_of::MallocSizeOf for Ping {
|
||||||
|
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||||
|
match self {
|
||||||
|
Ping::Child => 0,
|
||||||
|
Ping::Parent { inner, .. } => inner.size_of(ops),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Ping {
|
impl Ping {
|
||||||
/// Create a new ping type for the given name, whether to include the client ID and whether to
|
/// Create a new ping type for the given name, whether to include the client ID and whether to
|
||||||
/// send this ping empty.
|
/// send this ping empty.
|
||||||
|
|||||||
@@ -125,3 +125,15 @@ pub(crate) fn set_ping_enabled_by_id(id: u32, enabled: bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Measure the allocation size of all known pings.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn fog_ping_alloc_size(ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||||
|
use malloc_size_of::MallocSizeOf;
|
||||||
|
|
||||||
|
let mut n = 0;
|
||||||
|
{% for obj in all_objs['pings'].values() %}
|
||||||
|
n += ::once_cell::sync::Lazy::get(&{{ obj.name|snake_case }}).map(|p| p.size_of(ops)).unwrap_or(0);
|
||||||
|
{% endfor %}
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ line_length = 100
|
|||||||
tab_width = 2
|
tab_width = 2
|
||||||
language = "C++"
|
language = "C++"
|
||||||
namespaces = ["mozilla::glean::impl"]
|
namespaces = ["mozilla::glean::impl"]
|
||||||
includes = ["nsTArray.h", "nsString.h"]
|
includes = ["nsTArray.h", "nsString.h", "nsIMemoryReporter.h"]
|
||||||
|
|
||||||
[export.rename]
|
[export.rename]
|
||||||
"ThinVec" = "nsTArray"
|
"ThinVec" = "nsTArray"
|
||||||
|
|||||||
@@ -655,6 +655,16 @@ void FOG::InitMemoryReporter() { RegisterWeakMemoryReporter(this); }
|
|||||||
|
|
||||||
MOZ_DEFINE_MALLOC_SIZE_OF(FOGMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(FOGMallocSizeOf)
|
||||||
|
|
||||||
|
// Rust doesn't support weak-linking, so MFBT_API functions like
|
||||||
|
// moz_malloc_size_of need a C++ wrapper that uses the regular ABI
|
||||||
|
//
|
||||||
|
// We're not using MOZ_DEFINE_MALLOC_SIZE_OF here because that makes the
|
||||||
|
// function `static`, which would make it not visible outside this file
|
||||||
|
extern "C" size_t fog_malloc_size_of(const void* aPtr) {
|
||||||
|
MOZ_REPORT(aPtr);
|
||||||
|
return moz_malloc_size_of(aPtr);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
FOG::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
|
FOG::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
|
||||||
bool aAnonymize) {
|
bool aAnonymize) {
|
||||||
@@ -663,6 +673,7 @@ FOG::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
|
|||||||
MOZ_COLLECT_REPORT("explicit/fog/impl", KIND_HEAP, UNITS_BYTES,
|
MOZ_COLLECT_REPORT("explicit/fog/impl", KIND_HEAP, UNITS_BYTES,
|
||||||
aMallocSizeOf(this),
|
aMallocSizeOf(this),
|
||||||
"Memory used by the FOG core implementation");
|
"Memory used by the FOG core implementation");
|
||||||
|
glean::impl::fog_collect_reports(aHandleReport, aData, aAnonymize);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user