mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
base: Implement MallocSizeOf for some more types (#43858)
This implements MallocSizeOf for a couple more types and removes some "ignore_malloc_size_of" throughout the codebase. - std::path::PathBuf - tokio::sync::oneshot::Sender - http::HeaderMap (with a reasonable approximation of iterating over all headers) - data_url::Mime by looking at the inner type - http::Method: Is an enum internally - urlpattern::Urlpattern: Iterating over all public fields that are strings as an approximation. Testing: We cannot test if MallocSizeOf is correct currently. Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -8024,6 +8024,7 @@ dependencies = [
|
||||
"atomic_refcell",
|
||||
"content-security-policy",
|
||||
"crossbeam-channel",
|
||||
"data-url",
|
||||
"encoding_rs",
|
||||
"euclid",
|
||||
"http 1.4.0",
|
||||
|
||||
@@ -18,6 +18,7 @@ app_units = { workspace = true }
|
||||
atomic_refcell = { workspace = true }
|
||||
content-security-policy = { workspace = true }
|
||||
crossbeam-channel = { workspace = true }
|
||||
data-url = { workspace = true }
|
||||
encoding_rs = '0.8'
|
||||
euclid = { workspace = true }
|
||||
http = { workspace = true }
|
||||
|
||||
@@ -59,7 +59,6 @@ use resvg::usvg::{self, tiny_skia_path};
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::generics::length::GenericLengthPercentageOrAuto;
|
||||
pub use stylo_malloc_size_of::MallocSizeOfOps;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Trait for measuring the "deep" heap usage of a data structure. This is the
|
||||
/// most commonly-used of the traits.
|
||||
@@ -392,6 +391,13 @@ impl<T: MallocSizeOf> MallocSizeOf for std::collections::VecDeque<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl MallocSizeOf for std::path::PathBuf {
|
||||
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
|
||||
// This should be an approximation of the actual size
|
||||
self.as_os_str().as_encoded_bytes().len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: smallvec::Array> MallocShallowSizeOf for smallvec::SmallVec<A> {
|
||||
fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
if self.spilled() {
|
||||
@@ -1073,6 +1079,12 @@ impl<T> MallocSizeOf for tokio::sync::mpsc::UnboundedSender<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MallocSizeOf for tokio::sync::oneshot::Sender<T> {
|
||||
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MallocSizeOf for ipc_channel::ipc::IpcSender<T> {
|
||||
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
|
||||
0
|
||||
@@ -1109,6 +1121,22 @@ impl MallocSizeOf for servo_arc::Arc<ComputedValues> {
|
||||
}
|
||||
}
|
||||
|
||||
impl MallocSizeOf for http::HeaderMap {
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
// The headermap in http is more complicated than a simple hashmap
|
||||
// However, this should give us a reasonable approximation.
|
||||
self.iter()
|
||||
.map(|entry| entry.0.size_of(ops) + entry.1.size_of(ops))
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
|
||||
impl MallocSizeOf for data_url::mime::Mime {
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
self.type_.size_of(ops) + self.parameters.size_of(ops) + self.subtype.size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
malloc_size_of_hash_map!(indexmap::IndexMap<K, V, S>);
|
||||
malloc_size_of_hash_set!(indexmap::IndexSet<T, S>);
|
||||
|
||||
@@ -1117,12 +1145,13 @@ malloc_size_of_is_0!(f32, f64);
|
||||
malloc_size_of_is_0!(i8, i16, i32, i64, i128, isize);
|
||||
malloc_size_of_is_0!(u8, u16, u32, u64, u128, usize);
|
||||
|
||||
malloc_size_of_is_0!(Uuid);
|
||||
malloc_size_of_is_0!(uuid::Uuid);
|
||||
malloc_size_of_is_0!(app_units::Au);
|
||||
malloc_size_of_is_0!(content_security_policy::Destination);
|
||||
malloc_size_of_is_0!(content_security_policy::sandboxing_directive::SandboxingFlagSet);
|
||||
malloc_size_of_is_0!(encoding_rs::Decoder);
|
||||
malloc_size_of_is_0!(http::StatusCode);
|
||||
malloc_size_of_is_0!(http::Method);
|
||||
malloc_size_of_is_0!(keyboard_types::Code);
|
||||
malloc_size_of_is_0!(keyboard_types::Modifiers);
|
||||
malloc_size_of_is_0!(mime::Mime);
|
||||
@@ -1154,9 +1183,22 @@ malloc_size_of_is_0!(taffy::Layout);
|
||||
malloc_size_of_is_0!(time::Duration);
|
||||
malloc_size_of_is_0!(unicode_bidi::Level);
|
||||
malloc_size_of_is_0!(unicode_script::Script);
|
||||
malloc_size_of_is_0!(urlpattern::UrlPattern);
|
||||
malloc_size_of_is_0!(std::net::TcpStream);
|
||||
|
||||
impl MallocSizeOf for urlpattern::UrlPattern {
|
||||
fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize {
|
||||
// This is an approximation
|
||||
self.protocol().len() +
|
||||
self.username().len() +
|
||||
self.password().len() +
|
||||
self.hostname().len() +
|
||||
self.port().len() +
|
||||
self.pathname().len() +
|
||||
self.search().len() +
|
||||
self.hash().len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: tendril::TendrilSink<tendril::fmt::UTF8, A>, A: tendril::Atomicity> MallocSizeOf
|
||||
for tendril::stream::LossyDecoder<S, A>
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ use headers::{
|
||||
use http::header::HeaderValue;
|
||||
use http::{HeaderMap, Method, StatusCode, header};
|
||||
use log::{debug, error};
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf};
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use net_traits::http_status::HttpStatus;
|
||||
use net_traits::request::Request;
|
||||
@@ -55,11 +55,15 @@ impl CacheKey {
|
||||
}
|
||||
|
||||
/// A complete cached resource.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
pub struct CachedResource {
|
||||
#[conditional_malloc_size_of]
|
||||
request_headers: Arc<ParkingLotMutex<HeaderMap>>,
|
||||
#[conditional_malloc_size_of]
|
||||
body: Arc<ParkingLotMutex<ResponseBody>>,
|
||||
#[conditional_malloc_size_of]
|
||||
aborted: Arc<AtomicBool>,
|
||||
#[conditional_malloc_size_of]
|
||||
awaiting_body: Arc<ParkingLotMutex<Vec<TokioSender<Data>>>>,
|
||||
metadata: CachedMetadata,
|
||||
location_url: Option<Result<ServoUrl, String>>,
|
||||
@@ -70,27 +74,11 @@ pub struct CachedResource {
|
||||
last_validated: Instant,
|
||||
}
|
||||
|
||||
impl MallocSizeOf for CachedResource {
|
||||
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
|
||||
// TODO: self.request_headers.unconditional_size_of(ops) +
|
||||
self.body.unconditional_size_of(ops) +
|
||||
self.aborted.unconditional_size_of(ops) +
|
||||
self.awaiting_body.unconditional_size_of(ops) +
|
||||
self.metadata.size_of(ops) +
|
||||
self.location_url.size_of(ops) +
|
||||
self.https_state.size_of(ops) +
|
||||
self.status.size_of(ops) +
|
||||
self.url_list.size_of(ops) +
|
||||
self.expires.size_of(ops) +
|
||||
self.last_validated.size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata about a loaded resource, such as is obtained from HTTP headers.
|
||||
#[derive(Clone, MallocSizeOf)]
|
||||
struct CachedMetadata {
|
||||
/// Headers
|
||||
#[ignore_malloc_size_of = "Defined in `http` and has private members"]
|
||||
#[conditional_malloc_size_of]
|
||||
pub headers: Arc<ParkingLotMutex<HeaderMap>>,
|
||||
/// Final URL after redirects.
|
||||
pub final_url: ServoUrl,
|
||||
|
||||
@@ -30,7 +30,6 @@ use crate::script_runtime::CanGc;
|
||||
pub(crate) struct Headers {
|
||||
reflector_: Reflector,
|
||||
guard: Cell<Guard>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[no_trace]
|
||||
header_list: DomRefCell<HyperHeaders>,
|
||||
}
|
||||
|
||||
@@ -376,7 +376,6 @@ pub(crate) struct Window {
|
||||
test_runner: MutNullableDom<TestRunner>,
|
||||
|
||||
/// A handle for communicating messages to the WebGL thread, if available.
|
||||
#[ignore_malloc_size_of = "channels are hard"]
|
||||
#[no_trace]
|
||||
webgl_chan: Option<WebGLChan>,
|
||||
|
||||
|
||||
@@ -168,11 +168,9 @@ pub(crate) struct ServiceWorkerGlobalScope {
|
||||
/// indicating the sw should stop running,
|
||||
/// while still draining the task-queue
|
||||
// and running all enqueued, and not cancelled, tasks.
|
||||
#[ignore_malloc_size_of = "Defined in std"]
|
||||
#[no_trace]
|
||||
time_out_port: Receiver<Instant>,
|
||||
|
||||
#[ignore_malloc_size_of = "Defined in std"]
|
||||
#[no_trace]
|
||||
swmanager_sender: GenericSender<ServiceWorkerMsg>,
|
||||
|
||||
|
||||
@@ -208,20 +208,16 @@ pub(crate) struct XMLHttpRequest {
|
||||
response_arraybuffer: HeapBufferSource<ArrayBufferU8>,
|
||||
#[ignore_malloc_size_of = "Defined in rust-mozjs"]
|
||||
response_json: Heap<JSVal>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[no_trace]
|
||||
response_headers: DomRefCell<HeaderMap>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[no_trace]
|
||||
override_mime_type: DomRefCell<Option<Mime>>,
|
||||
|
||||
// Associated concepts
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[no_trace]
|
||||
request_method: DomRefCell<Method>,
|
||||
#[no_trace]
|
||||
request_url: DomRefCell<Option<ServoUrl>>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[no_trace]
|
||||
request_headers: DomRefCell<HeaderMap>,
|
||||
request_body_len: Cell<usize>,
|
||||
|
||||
@@ -71,7 +71,7 @@ impl Kind {
|
||||
/// <https://html.spec.whatwg.org/multipage/#drag-data-store-bitmap>
|
||||
#[derive(MallocSizeOf)]
|
||||
struct Bitmap {
|
||||
#[ignore_malloc_size_of = "RasterImage"]
|
||||
#[conditional_malloc_size_of]
|
||||
image: Option<Arc<RasterImage>>,
|
||||
x: i32,
|
||||
y: i32,
|
||||
|
||||
@@ -7,7 +7,6 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use layout_api::AnimatingImages;
|
||||
use malloc_size_of::MallocSizeOf;
|
||||
use paint_api::ImageUpdate;
|
||||
use parking_lot::RwLock;
|
||||
use script_bindings::codegen::GenericBindings::WindowBinding::WindowMethods;
|
||||
@@ -18,12 +17,13 @@ use crate::dom::node::Node;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_thread::with_script_thread;
|
||||
|
||||
#[derive(Clone, Default, JSTraceable)]
|
||||
#[derive(Clone, Default, JSTraceable, MallocSizeOf)]
|
||||
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
||||
pub struct ImageAnimationManager {
|
||||
/// The set of [`AnimatingImages`] which is used to communicate the addition
|
||||
/// and removal of animating images from layout.
|
||||
#[no_trace]
|
||||
#[conditional_malloc_size_of]
|
||||
animating_images: Arc<RwLock<AnimatingImages>>,
|
||||
|
||||
/// The [`TimerId`] of the currently scheduled animated image update callback.
|
||||
@@ -31,12 +31,6 @@ pub struct ImageAnimationManager {
|
||||
callback_timer_id: Cell<Option<TimerId>>,
|
||||
}
|
||||
|
||||
impl MallocSizeOf for ImageAnimationManager {
|
||||
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||
(*self.animating_images.read()).size_of(ops)
|
||||
}
|
||||
}
|
||||
|
||||
impl ImageAnimationManager {
|
||||
pub(crate) fn animating_images(&self) -> Arc<RwLock<AnimatingImages>> {
|
||||
self.animating_images.clone()
|
||||
|
||||
@@ -192,9 +192,7 @@ impl BroadcastClone for SerializableFileList {
|
||||
/// File-based blob
|
||||
#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
pub struct FileBlob {
|
||||
#[ignore_malloc_size_of = "Uuid are hard(not really)"]
|
||||
id: Uuid,
|
||||
#[ignore_malloc_size_of = "PathBuf are hard"]
|
||||
name: Option<PathBuf>,
|
||||
cache: RefCell<Option<Vec<u8>>>,
|
||||
size: u64,
|
||||
|
||||
@@ -493,9 +493,7 @@ pub struct PageError {
|
||||
#[derive(Debug, PartialEq, MallocSizeOf)]
|
||||
pub struct HttpRequest {
|
||||
pub url: ServoUrl,
|
||||
#[ignore_malloc_size_of = "http type"]
|
||||
pub method: Method,
|
||||
#[ignore_malloc_size_of = "http type"]
|
||||
pub headers: HeaderMap,
|
||||
pub body: Option<DebugVec>,
|
||||
pub pipeline_id: PipelineId,
|
||||
|
||||
@@ -639,13 +639,11 @@ pub struct WebResourceRequest {
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub method: Method,
|
||||
#[serde(
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub headers: HeaderMap,
|
||||
pub url: Url,
|
||||
pub is_for_main_frame: bool,
|
||||
|
||||
@@ -688,7 +688,7 @@ pub fn node_id_from_scroll_id(id: usize) -> usize {
|
||||
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
pub struct ImageAnimationState {
|
||||
#[ignore_malloc_size_of = "RasterImage"]
|
||||
#[conditional_malloc_size_of]
|
||||
pub image: Arc<RasterImage>,
|
||||
pub active_frame: usize,
|
||||
frame_start_time: f64,
|
||||
|
||||
@@ -78,13 +78,11 @@ pub enum LoadContext {
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
pub struct CustomResponse {
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[serde(
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
pub headers: HeaderMap,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
#[serde(
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
|
||||
@@ -174,7 +174,6 @@ pub struct PreloadEntry {
|
||||
/// <https://html.spec.whatwg.org/multipage/#preload-response>
|
||||
pub response: Option<Response>,
|
||||
/// <https://html.spec.whatwg.org/multipage/#preload-on-response-available>
|
||||
#[ignore_malloc_size_of = "Channels are hard"]
|
||||
pub on_response_available: Option<TokioSender<Response>>,
|
||||
}
|
||||
|
||||
@@ -318,7 +317,7 @@ pub enum BodyChunkRequest {
|
||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||
pub struct RequestBody {
|
||||
/// Net's channel to communicate with script re this body.
|
||||
#[ignore_malloc_size_of = "Channels are hard"]
|
||||
#[conditional_malloc_size_of]
|
||||
body_chunk_request_channel: Arc<Mutex<Option<IpcSender<BodyChunkRequest>>>>,
|
||||
/// <https://fetch.spec.whatwg.org/#concept-body-source>
|
||||
source: BodySource,
|
||||
@@ -427,7 +426,6 @@ pub struct RequestBuilder {
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub method: Method,
|
||||
|
||||
/// <https://fetch.spec.whatwg.org/#concept-request-url>
|
||||
@@ -438,7 +436,6 @@ pub struct RequestBuilder {
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub headers: HeaderMap,
|
||||
|
||||
/// <https://fetch.spec.whatwg.org/#unsafe-request-flag>
|
||||
@@ -782,12 +779,10 @@ pub struct Request {
|
||||
pub id: RequestId,
|
||||
pub preload_id: Option<PreloadId>,
|
||||
/// <https://fetch.spec.whatwg.org/#concept-request-method>
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub method: Method,
|
||||
/// <https://fetch.spec.whatwg.org/#local-urls-only-flag>
|
||||
pub local_urls_only: bool,
|
||||
/// <https://fetch.spec.whatwg.org/#concept-request-header-list>
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub headers: HeaderMap,
|
||||
/// <https://fetch.spec.whatwg.org/#unsafe-request-flag>
|
||||
pub unsafe_request: bool,
|
||||
|
||||
@@ -91,7 +91,6 @@ pub struct ResponseInit {
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub headers: HeaderMap,
|
||||
pub status_code: u16,
|
||||
pub referrer: Option<ServoUrl>,
|
||||
@@ -110,7 +109,6 @@ pub struct Response {
|
||||
deserialize_with = "::hyper_serde::deserialize",
|
||||
serialize_with = "::hyper_serde::serialize"
|
||||
)]
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
pub headers: HeaderMap,
|
||||
#[conditional_malloc_size_of]
|
||||
pub body: Arc<Mutex<ResponseBody>>,
|
||||
|
||||
Reference in New Issue
Block a user