From 13a980ff229fe653f6db262a314e6dc7bb886c13 Mon Sep 17 00:00:00 2001 From: Narfinger Date: Fri, 30 May 2025 19:15:06 +0200 Subject: [PATCH] Constellation can now optionally report memory usage when the page is loaded. (#37151) The constellation can now tell the memory reporter to report the memory to a trace file when a page is loaded. Additionally, we amend the memory reporter to allow a simple message where it will report the memory to a tracing provider (at the moment only OHOS/hitrace is supported but easy extension is possible). I am not sure if this is the right approach or if the embedder should decide to have the memory reporting done. Testing: This does not change functionality of any of the rendering. --------- Signed-off-by: Narfinger --- components/constellation/constellation.rs | 4 ++++ components/constellation/tracing.rs | 1 + components/profile/mem.rs | 1 - components/servo/lib.rs | 6 ++++++ components/shared/constellation/lib.rs | 3 +++ ports/servoshell/egl/app_state.rs | 18 ++++++++++++++++++ 6 files changed, 32 insertions(+), 1 deletion(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 866791268f9..5b4d244e746 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -148,6 +148,7 @@ use net_traits::pub_domains::reg_host; use net_traits::request::Referrer; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; use net_traits::{self, IpcSend, ReferrerPolicy, ResourceThreads}; +use profile_traits::mem::ProfilerMsg; use profile_traits::{mem, time}; use script_layout_interface::{LayoutFactory, ScriptThreadFactory}; use script_traits::{ @@ -1488,6 +1489,9 @@ where ) => { self.handle_evaluate_javascript(webview_id, evaluation_id, script); }, + EmbedderToConstellationMessage::CreateMemoryReport(sender) => { + self.mem_profiler_chan.send(ProfilerMsg::Report(sender)); + }, } } diff --git a/components/constellation/tracing.rs b/components/constellation/tracing.rs index 6237665b87f..99551bd58fc 100644 --- a/components/constellation/tracing.rs +++ b/components/constellation/tracing.rs @@ -78,6 +78,7 @@ mod from_compositor { Self::SetScrollStates(..) => target!("SetScrollStates"), Self::PaintMetric(..) => target!("PaintMetric"), Self::EvaluateJavaScript(..) => target!("EvaluateJavaScript"), + Self::CreateMemoryReport(..) => target!("CreateMemoryReport"), } } } diff --git a/components/profile/mem.rs b/components/profile/mem.rs index b9920f252b4..0aff98b89d0 100644 --- a/components/profile/mem.rs +++ b/components/profile/mem.rs @@ -114,7 +114,6 @@ impl Profiler { let _ = sender.send(MemoryReportResult { results }); true }, - ProfilerMsg::Exit => false, } } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index defc4ad7e8d..a188678c024 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -92,6 +92,7 @@ use media::{GlApi, NativeDisplay, WindowGLContext}; use net::protocols::ProtocolRegistry; use net::resource_thread::new_resource_threads; use profile::{mem as profile_mem, time as profile_time}; +use profile_traits::mem::MemoryReportResult; use profile_traits::{mem, time}; use script::{JSEngineSetup, ServiceWorkerManager}; use servo_config::opts::Opts; @@ -633,6 +634,11 @@ impl Servo { log::set_max_level(filter); } + pub fn create_memory_report(&self, snd: IpcSender) { + self.constellation_proxy + .send(EmbedderToConstellationMessage::CreateMemoryReport(snd)); + } + pub fn start_shutting_down(&self) { if self.shutdown_state.get() != ShutdownState::NotShuttingDown { warn!("Requested shutdown while already shutting down"); diff --git a/components/shared/constellation/lib.rs b/components/shared/constellation/lib.rs index fb00d4afdbf..53e924c5ad5 100644 --- a/components/shared/constellation/lib.rs +++ b/components/shared/constellation/lib.rs @@ -26,6 +26,7 @@ use euclid::Vector2D; pub use from_script_message::*; use ipc_channel::ipc::IpcSender; use malloc_size_of_derive::MallocSizeOf; +use profile_traits::mem::MemoryReportResult; use serde::{Deserialize, Serialize}; use servo_url::{ImmutableOrigin, ServoUrl}; pub use structured_data::*; @@ -95,6 +96,8 @@ pub enum EmbedderToConstellationMessage { /// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an /// error is encountered, a correpsonding message will be sent to the embedding layer. EvaluateJavaScript(WebViewId, JavaScriptEvaluationId, String), + /// Create a memory report and return it via the ipc sender + CreateMemoryReport(IpcSender), } /// A description of a paint metric that is sent from the Servo renderer to the diff --git a/ports/servoshell/egl/app_state.rs b/ports/servoshell/egl/app_state.rs index c0890e2d36a..114c9c5f4d0 100644 --- a/ports/servoshell/egl/app_state.rs +++ b/ports/servoshell/egl/app_state.rs @@ -152,6 +152,24 @@ impl WebViewDelegate for RunningAppState { self.callbacks .host_callbacks .notify_load_status_changed(load_status); + + #[cfg(feature = "tracing")] + if load_status == LoadStatus::Complete { + #[cfg(feature = "tracing-hitrace")] + let (snd, recv) = ipc_channel::ipc::channel().expect("Could not create channel"); + self.servo.create_memory_report(snd); + std::thread::spawn(move || { + let result = recv.recv().expect("Could not get memory report"); + let reports = result + .results + .first() + .expect("We should have some memory report"); + for report in &reports.reports { + let path = String::from("servo_memory_profiling:") + &report.path.join("/"); + hitrace::trace_metric_str(&path, report.size as i64); + } + }); + } } fn notify_closed(&self, webview: WebView) {