Replace all uses of the heapsize crate with malloc_size_of.

Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`.
`malloc_size_of` is better -- it handles various cases that `heapsize` does not
-- so this patch changes Servo to use `malloc_size_of`.

This patch makes the following changes to the `malloc_size_of` crate.

- Adds `MallocSizeOf` trait implementations for numerous types, some built-in
  (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`).

- Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't
  support that operation.

- For `HashSet`/`HashMap`, falls back to a computed estimate when
  `enclosing_size_of_op` isn't available.

- Adds an extern "C" `malloc_size_of` function that does the actual heap
  measurement; this is based on the same functions from the `heapsize` crate.

This patch makes the following changes elsewhere.

- Converts all the uses of `heapsize` to instead use `malloc_size_of`.

- Disables the "heapsize"/"heap_size" feature for the external crates that
  provide it.

- Removes the `HeapSizeOf` implementation from `hashglobe`.

- Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of`
  doesn't derive those types, unlike `heapsize`.
This commit is contained in:
Nicholas Nethercote 2017-10-18 10:42:01 +11:00
parent 421baa854e
commit 4506f0d30c
269 changed files with 1418 additions and 1521 deletions

View file

@ -11,19 +11,19 @@ path = "lib.rs"
[dependencies]
cookie = "0.6"
heapsize = "0.4"
heapsize_derive = "0.1"
hyper = "0.10"
hyper_serde = "0.7"
image = "0.16"
ipc-channel = "0.9"
lazy_static = "0.2"
log = "0.3.5"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
msg = {path = "../msg"}
num-traits = "0.1.32"
serde = "1.0"
servo_config = {path = "../config"}
servo_url = {path = "../url"}
url = {version = "1.2", features = ["heap_size"]}
url = "1.2"
uuid = {version = "0.5", features = ["v4", "serde"]}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}

View file

@ -7,7 +7,7 @@ use piston_image::{self, DynamicImage, ImageFormat};
use std::fmt;
use webrender_api;
#[derive(Clone, Copy, Debug, Deserialize, Eq, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub enum PixelFormat {
/// Luminance channel only
K8,
@ -19,14 +19,14 @@ pub enum PixelFormat {
BGRA8,
}
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct Image {
pub width: u32,
pub height: u32,
pub format: PixelFormat,
#[ignore_heap_size_of = "Defined in ipc-channel"]
#[ignore_malloc_size_of = "Defined in ipc-channel"]
pub bytes: IpcSharedMemory,
#[ignore_heap_size_of = "Defined in webrender_api"]
#[ignore_malloc_size_of = "Defined in webrender_api"]
pub id: Option<webrender_api::ImageKey>,
}
@ -37,7 +37,7 @@ impl fmt::Debug for Image {
}
}
#[derive(Clone, Debug, Deserialize, Eq, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub struct ImageMetadata {
pub width: u32,
pub height: u32,

View file

@ -23,9 +23,9 @@ pub enum CanRequestImages {
}
/// Indicating either entire image or just metadata availability
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub enum ImageOrMetadataAvailable {
ImageAvailable(Arc<Image>, ServoUrl),
ImageAvailable(#[ignore_malloc_size_of = "Arc"] Arc<Image>, ServoUrl),
MetadataAvailable(ImageMetadata),
}
@ -60,14 +60,14 @@ impl ImageResponder {
}
/// The returned image.
#[derive(Clone, Debug, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum ImageResponse {
/// The requested image was loaded.
Loaded(Arc<Image>, ServoUrl),
Loaded(#[ignore_malloc_size_of = "Arc"] Arc<Image>, ServoUrl),
/// The request image metadata was loaded.
MetadataLoaded(ImageMetadata),
/// The requested image failed to load, so a placeholder was loaded instead.
PlaceholderLoaded(Arc<Image>, ServoUrl),
PlaceholderLoaded(#[ignore_malloc_size_of = "Arc"] Arc<Image>, ServoUrl),
/// Neither the requested image nor the placeholder could be loaded.
None,
}
@ -81,7 +81,7 @@ pub enum ImageState {
}
/// The unique id for an image that has previously been requested.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct PendingImageId(pub u64);
#[derive(Debug, Deserialize, Serialize)]

View file

@ -6,14 +6,14 @@
#![deny(unsafe_code)]
extern crate cookie as cookie_rs;
extern crate heapsize;
#[macro_use] extern crate heapsize_derive;
extern crate hyper;
extern crate hyper_serde;
extern crate image as piston_image;
extern crate ipc_channel;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use] extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive;
extern crate msg;
extern crate num_traits;
#[macro_use] extern crate serde;
@ -25,7 +25,6 @@ extern crate webrender_api;
use cookie_rs::Cookie;
use filemanager_thread::FileManagerThreadMsg;
use heapsize::HeapSizeOf;
use hyper::Error as HyperError;
use hyper::header::{ContentType, Headers, ReferrerPolicy as ReferrerPolicyHeader};
use hyper::http::RawStatus;
@ -60,7 +59,7 @@ pub mod image {
/// A loading context, for context-specific sniffing, as defined in
/// <https://mimesniff.spec.whatwg.org/#context-specific-sniffing>
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub enum LoadContext {
Browsing,
Image,
@ -73,13 +72,13 @@ pub enum LoadContext {
CacheManifest,
}
#[derive(Clone, Debug, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct CustomResponse {
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
pub headers: Headers,
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
pub raw_status: RawStatus,
@ -104,7 +103,7 @@ pub struct CustomResponseMediator {
/// [Policies](https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states)
/// for providing a referrer header for a request
#[derive(Clone, Copy, Debug, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum ReferrerPolicy {
/// "no-referrer"
NoReferrer,
@ -310,11 +309,7 @@ impl IpcSend<StorageThreadMsg> for ResourceThreads {
}
// Ignore the sub-fields
impl HeapSizeOf for ResourceThreads {
fn heap_size_of_children(&self) -> usize {
0
}
}
malloc_size_of_is_0!(ResourceThreads);
#[derive(Clone, Copy, Deserialize, PartialEq, Serialize)]
pub enum IncludeSubdomains {
@ -322,7 +317,7 @@ pub enum IncludeSubdomains {
NotIncluded,
}
#[derive(Deserialize, HeapSizeOf, Serialize)]
#[derive(Deserialize, MallocSizeOf, Serialize)]
pub enum MessageData {
Text(String),
Binary(Vec<u8>),
@ -395,7 +390,7 @@ pub fn fetch_async<F>(request: RequestInit, core_resource_thread: &CoreResourceT
core_resource_thread.send(CoreResourceMsg::Fetch(request, action_sender)).unwrap();
}
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct ResourceCorsData {
/// CORS Preflight flag
pub preflight: bool,
@ -404,7 +399,7 @@ pub struct ResourceCorsData {
}
/// Metadata about a loaded resource, such as is obtained from HTTP headers.
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct Metadata {
/// Final URL after redirects.
pub final_url: ServoUrl,
@ -412,14 +407,14 @@ pub struct Metadata {
/// Location URL from the response headers.
pub location_url: Option<Result<ServoUrl, String>>,
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
/// MIME type / subtype.
pub content_type: Option<Serde<ContentType>>,
/// Character set.
pub charset: Option<String>,
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
/// Headers
pub headers: Option<Serde<Headers>>,
@ -509,11 +504,11 @@ pub fn load_whole_resource(request: RequestInit,
}
/// An unique identifier to keep track of each load message in the resource handler
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
pub struct ResourceId(pub u32);
/// Network errors that have to be exported out of the loaders
#[derive(Clone, Debug, Deserialize, Eq, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub enum NetworkError {
/// Could be any of the internal errors, like unsupported scheme, connection errors, etc.
Internal(String),

View file

@ -10,7 +10,7 @@ use servo_url::{ImmutableOrigin, ServoUrl};
use std::default::Default;
/// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator)
#[derive(Clone, Copy, HeapSizeOf, PartialEq)]
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum Initiator {
None,
Download,
@ -20,7 +20,7 @@ pub enum Initiator {
}
/// A request [type](https://fetch.spec.whatwg.org/#concept-request-type)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Type {
None,
Audio,
@ -33,7 +33,7 @@ pub enum Type {
}
/// A request [destination](https://fetch.spec.whatwg.org/#concept-request-destination)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Destination {
None,
Document,
@ -53,14 +53,14 @@ pub enum Destination {
}
/// A request [origin](https://fetch.spec.whatwg.org/#concept-request-origin)
#[derive(Clone, Debug, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Origin {
Client,
Origin(ImmutableOrigin),
}
/// A [referer](https://fetch.spec.whatwg.org/#concept-request-referrer)
#[derive(Clone, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Referrer {
NoReferrer,
/// Default referrer if nothing is specified
@ -69,7 +69,7 @@ pub enum Referrer {
}
/// A [request mode](https://fetch.spec.whatwg.org/#concept-request-mode)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum RequestMode {
Navigate,
SameOrigin,
@ -79,7 +79,7 @@ pub enum RequestMode {
}
/// Request [credentials mode](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CredentialsMode {
Omit,
CredentialsSameOrigin,
@ -87,7 +87,7 @@ pub enum CredentialsMode {
}
/// [Cache mode](https://fetch.spec.whatwg.org/#concept-request-cache-mode)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CacheMode {
Default,
NoStore,
@ -98,7 +98,7 @@ pub enum CacheMode {
}
/// [Service-workers mode](https://fetch.spec.whatwg.org/#request-service-workers-mode)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum ServiceWorkersMode {
All,
Foreign,
@ -106,7 +106,7 @@ pub enum ServiceWorkersMode {
}
/// [Redirect mode](https://fetch.spec.whatwg.org/#concept-request-redirect-mode)
#[derive(Clone, Copy, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum RedirectMode {
Follow,
Error,
@ -114,7 +114,7 @@ pub enum RedirectMode {
}
/// [Response tainting](https://fetch.spec.whatwg.org/#concept-request-response-tainting)
#[derive(Clone, Copy, HeapSizeOf, PartialEq)]
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum ResponseTainting {
Basic,
CorsTainting,
@ -122,7 +122,7 @@ pub enum ResponseTainting {
}
/// [Window](https://fetch.spec.whatwg.org/#concept-request-window)
#[derive(Clone, Copy, HeapSizeOf, PartialEq)]
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum Window {
NoWindow,
Client, // TODO: Environmental settings object
@ -135,16 +135,16 @@ pub enum CorsSettings {
UseCredentials,
}
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct RequestInit {
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
pub method: Method,
pub url: ServoUrl,
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
pub headers: Headers,
pub unsafe_request: bool,
pub body: Option<Vec<u8>>,
@ -199,17 +199,17 @@ impl Default for RequestInit {
/// A [Request](https://fetch.spec.whatwg.org/#concept-request) as defined by
/// the Fetch spec.
#[derive(Clone, HeapSizeOf)]
#[derive(Clone, MallocSizeOf)]
pub struct Request {
/// <https://fetch.spec.whatwg.org/#concept-request-method>
#[ignore_heap_size_of = "Defined in hyper"]
#[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/#sandboxed-storage-area-urls-flag>
pub sandboxed_storage_area_urls: bool,
/// <https://fetch.spec.whatwg.org/#concept-request-header-list>
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
pub headers: Headers,
/// <https://fetch.spec.whatwg.org/#unsafe-request-flag>
pub unsafe_request: bool,

View file

@ -13,7 +13,7 @@ use std::ascii::AsciiExt;
use std::sync::{Arc, Mutex};
/// [Response type](https://fetch.spec.whatwg.org/#concept-response-type)
#[derive(Clone, Debug, Deserialize, HeapSizeOf, PartialEq, Serialize)]
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum ResponseType {
Basic,
Cors,
@ -24,7 +24,7 @@ pub enum ResponseType {
}
/// [Response termination reason](https://fetch.spec.whatwg.org/#concept-response-termination-reason)
#[derive(Clone, Copy, Debug, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum TerminationReason {
EndUserAbort,
Fatal,
@ -33,7 +33,7 @@ pub enum TerminationReason {
/// The response body can still be pushed to after fetch
/// This provides a way to store unfinished response bodies
#[derive(Clone, Debug, HeapSizeOf, PartialEq)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
pub enum ResponseBody {
Empty, // XXXManishearth is this necessary, or is Done(vec![]) enough?
Receiving(Vec<u8>),
@ -52,7 +52,7 @@ impl ResponseBody {
/// [Cache state](https://fetch.spec.whatwg.org/#concept-response-cache-state)
#[derive(Clone, Debug, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum CacheState {
None,
Local,
@ -61,7 +61,7 @@ pub enum CacheState {
}
/// [Https state](https://fetch.spec.whatwg.org/#concept-response-https-state)
#[derive(Clone, Copy, Debug, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum HttpsState {
None,
Deprecated,
@ -74,31 +74,31 @@ pub enum ResponseMsg {
Errored,
}
#[derive(Clone, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct ResponseInit {
pub url: ServoUrl,
#[serde(deserialize_with = "::hyper_serde::deserialize",
serialize_with = "::hyper_serde::serialize")]
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
pub headers: Headers,
pub referrer: Option<ServoUrl>,
pub location_url: Option<Result<ServoUrl, String>>,
}
/// A [Response](https://fetch.spec.whatwg.org/#concept-response) as defined by the Fetch spec
#[derive(Clone, Debug, HeapSizeOf)]
#[derive(Clone, Debug, MallocSizeOf)]
pub struct Response {
pub response_type: ResponseType,
pub termination_reason: Option<TerminationReason>,
url: Option<ServoUrl>,
pub url_list: Vec<ServoUrl>,
/// `None` can be considered a StatusCode of `0`.
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
pub status: Option<StatusCode>,
pub raw_status: Option<(u16, Vec<u8>)>,
#[ignore_heap_size_of = "Defined in hyper"]
#[ignore_malloc_size_of = "Defined in hyper"]
pub headers: Headers,
#[ignore_heap_size_of = "Mutex heap size undefined"]
#[ignore_malloc_size_of = "Mutex heap size undefined"]
pub body: Arc<Mutex<ResponseBody>>,
pub cache_state: CacheState,
pub https_state: HttpsState,

View file

@ -5,7 +5,7 @@
use ipc_channel::ipc::IpcSender;
use servo_url::ServoUrl;
#[derive(Clone, Copy, Deserialize, HeapSizeOf, Serialize)]
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
pub enum StorageType {
Session,
Local,