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",
|
||||
"log",
|
||||
"mozbuild",
|
||||
"nserror",
|
||||
"nsstring",
|
||||
"once_cell",
|
||||
"serde",
|
||||
@@ -1975,6 +1976,7 @@ dependencies = [
|
||||
"thin-vec",
|
||||
"time 0.1.45",
|
||||
"uuid",
|
||||
"wr_malloc_size_of",
|
||||
"xpcom",
|
||||
]
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ xpcom = { path = "../../../../xpcom/rust/xpcom", optional = true }
|
||||
thin-vec = { version = "0.2.1", features = ["gecko-ffi"] }
|
||||
mozbuild = "0.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
|
||||
[dependencies.time]
|
||||
|
||||
@@ -25,3 +25,58 @@ pub mod ipc;
|
||||
|
||||
#[cfg(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,
|
||||
}
|
||||
|
||||
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 {
|
||||
/// Create a new ping type for the given name, whether to include the client ID and whether to
|
||||
/// 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
|
||||
language = "C++"
|
||||
namespaces = ["mozilla::glean::impl"]
|
||||
includes = ["nsTArray.h", "nsString.h"]
|
||||
includes = ["nsTArray.h", "nsString.h", "nsIMemoryReporter.h"]
|
||||
|
||||
[export.rename]
|
||||
"ThinVec" = "nsTArray"
|
||||
|
||||
@@ -655,6 +655,16 @@ void FOG::InitMemoryReporter() { RegisterWeakMemoryReporter(this); }
|
||||
|
||||
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
|
||||
FOG::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
|
||||
bool aAnonymize) {
|
||||
@@ -663,6 +673,7 @@ FOG::CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
|
||||
MOZ_COLLECT_REPORT("explicit/fog/impl", KIND_HEAP, UNITS_BYTES,
|
||||
aMallocSizeOf(this),
|
||||
"Memory used by the FOG core implementation");
|
||||
glean::impl::fog_collect_reports(aHandleReport, aData, aAnonymize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user