Skip to content

Commit c97a708

Browse files
committed
servo: Merge #18944 - Stop relying on linking details of std’s default allocator (from servo:jemallocator2); r=nox
We’ve been bitten before by symbol names changing: servo/heapsize#46, and upstream is planning to stop using jemalloc by default: rust-lang/rust#33082 (comment) So use the (relatively) new `#[global_allocator]` attribute to explicitly select the system allocator on Windows and jemalloc (now in an external crate) on other platforms. This choice matches current defaults. Source-Repo: https://github.com/servo/servo Source-Revision: 07e9794306d597afe5d90d192fd32a99572c3cc3 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : c773f809c4f783e63c42218220e7c8c190727e6e
1 parent 459bc71 commit c97a708

File tree

20 files changed

+152
-62
lines changed

20 files changed

+152
-62
lines changed

servo/Cargo.lock

+33-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

servo/components/allocator/Cargo.toml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "servo_allocator"
3+
version = "0.0.1"
4+
authors = ["The Servo Project Developers"]
5+
license = "MPL-2.0"
6+
publish = false
7+
8+
[lib]
9+
path = "lib.rs"
10+
11+
[features]
12+
unstable = ["kernel32-sys", "jemallocator"]
13+
14+
[target.'cfg(not(windows))'.dependencies]
15+
jemallocator = { version = "0.1.3", optional = true }
16+
17+
[target.'cfg(windows)'.dependencies]
18+
kernel32-sys = { version = "0.2.1", optional = true }

servo/components/allocator/lib.rs

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
//! Selecting the default global allocator for Servo
6+
7+
#![cfg_attr(all(feature = "unstable", windows), feature(alloc_system, allocator_api))]
8+
#![cfg_attr(feature = "unstable", feature(global_allocator))]
9+
10+
#[cfg(feature = "unstable")]
11+
#[global_allocator]
12+
static ALLOC: platform::Allocator = platform::Allocator;
13+
14+
pub use platform::usable_size;
15+
16+
17+
#[cfg(all(feature = "unstable", not(windows)))]
18+
mod platform {
19+
extern crate jemallocator;
20+
21+
pub use self::jemallocator::Jemalloc as Allocator;
22+
use std::os::raw::c_void;
23+
24+
/// Get the size of a heap block.
25+
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
26+
jemallocator::usable_size(ptr)
27+
}
28+
}
29+
30+
#[cfg(all(feature = "unstable", windows))]
31+
mod platform {
32+
extern crate alloc_system;
33+
extern crate kernel32;
34+
35+
pub use self::alloc_system::System as Allocator;
36+
use self::kernel32::{GetProcessHeap, HeapSize, HeapValidate};
37+
use std::os::raw::c_void;
38+
39+
/// Get the size of a heap block.
40+
pub unsafe extern "C" fn usable_size(mut ptr: *const c_void) -> usize {
41+
let heap = GetProcessHeap();
42+
43+
if HeapValidate(heap, 0, ptr) == 0 {
44+
ptr = *(ptr as *const *const c_void).offset(-1);
45+
}
46+
47+
HeapSize(heap, 0, ptr) as usize
48+
}
49+
}
50+
51+
#[cfg(not(feature = "unstable"))]
52+
mod platform {
53+
use std::os::raw::c_void;
54+
55+
/// Without `#[global_allocator]` we cannot be certain of what allocator is used
56+
/// or how it is linked. We therefore disable memory reporting. (Return zero.)
57+
pub unsafe extern "C" fn usable_size(_ptr: *const c_void) -> usize {
58+
0
59+
}
60+
}
61+
62+

servo/components/gfx/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ core-text = "7.0"
5353

5454
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
5555
freetype = "0.3"
56+
servo_allocator = {path = "../allocator"}
5657

5758
[target.'cfg(target_os = "linux")'.dependencies]
5859
servo-fontconfig = "0.2.1"

servo/components/gfx/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ extern crate fnv;
2727
#[cfg(target_os = "linux")]
2828
extern crate fontconfig;
2929
extern crate fontsan;
30-
#[cfg(any(target_os = "linux", target_os = "android"))]
31-
extern crate freetype;
30+
#[cfg(any(target_os = "linux", target_os = "android"))] extern crate freetype;
31+
#[cfg(any(target_os = "linux", target_os = "android"))] extern crate servo_allocator;
3232
extern crate gfx_traits;
3333

3434
// Eventually we would like the shaper to be pluggable, as many operating systems have their own

servo/components/gfx/platform/freetype/font_context.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use freetype::freetype::FT_Library;
88
use freetype::freetype::FT_Memory;
99
use freetype::freetype::FT_MemoryRec_;
1010
use freetype::freetype::FT_New_Library;
11-
use malloc_size_of::{malloc_size_of, MallocSizeOf, MallocSizeOfOps};
11+
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
12+
use servo_allocator::usable_size;
1213
use std::mem;
1314
use std::os::raw::{c_long, c_void};
1415
use std::ptr;
@@ -31,7 +32,7 @@ extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void {
3132
mem::forget(vec);
3233

3334
unsafe {
34-
let actual_size = malloc_size_of(ptr as *const _);
35+
let actual_size = usable_size(ptr as *const _);
3536
let user = (*mem).user as *mut User;
3637
(*user).size += actual_size;
3738
}
@@ -41,7 +42,7 @@ extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void {
4142

4243
extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) {
4344
unsafe {
44-
let actual_size = malloc_size_of(ptr as *const _);
45+
let actual_size = usable_size(ptr as *const _);
4546
let user = (*mem).user as *mut User;
4647
(*user).size -= actual_size;
4748

@@ -50,13 +51,14 @@ extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) {
5051
}
5152
}
5253

53-
extern fn ft_realloc(mem: FT_Memory, _cur_size: c_long, new_req_size: c_long,
54+
extern fn ft_realloc(mem: FT_Memory, old_size: c_long, new_req_size: c_long,
5455
old_ptr: *mut c_void) -> *mut c_void {
5556
let old_actual_size;
5657
let mut vec;
5758
unsafe {
58-
old_actual_size = malloc_size_of(old_ptr as *const _);
59-
vec = Vec::<u8>::from_raw_parts(old_ptr as *mut u8, old_actual_size, old_actual_size);
59+
old_actual_size = usable_size(old_ptr as *const _);
60+
let old_size = old_size as usize;
61+
vec = Vec::<u8>::from_raw_parts(old_ptr as *mut u8, old_size, old_size);
6062
};
6163

6264
let new_req_size = new_req_size as usize;
@@ -71,7 +73,7 @@ extern fn ft_realloc(mem: FT_Memory, _cur_size: c_long, new_req_size: c_long,
7173
mem::forget(vec);
7274

7375
unsafe {
74-
let new_actual_size = malloc_size_of(new_ptr as *const _);
76+
let new_actual_size = usable_size(new_ptr as *const _);
7577
let user = (*mem).user as *mut User;
7678
(*user).size += new_actual_size;
7779
(*user).size -= old_actual_size;

servo/components/layout_thread/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ script_layout_interface = {path = "../script_layout_interface"}
4040
script_traits = {path = "../script_traits"}
4141
selectors = { path = "../selectors" }
4242
serde_json = "1.0"
43+
servo_allocator = {path = "../allocator"}
4344
servo_arc = {path = "../servo_arc"}
4445
servo_atoms = {path = "../atoms"}
4546
servo_config = {path = "../config"}

servo/components/layout_thread/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern crate script_layout_interface;
3939
extern crate script_traits;
4040
extern crate selectors;
4141
extern crate serde_json;
42+
extern crate servo_allocator;
4243
extern crate servo_arc;
4344
extern crate servo_atoms;
4445
extern crate servo_config;
@@ -84,7 +85,7 @@ use layout::webrender_helpers::WebRenderDisplayListConverter;
8485
use layout::wrapper::LayoutNodeLayoutData;
8586
use layout_traits::LayoutThreadFactory;
8687
use libc::c_void;
87-
use malloc_size_of::{malloc_size_of, MallocSizeOf, MallocSizeOfOps};
88+
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
8889
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory};
8990
use msg::constellation_msg::PipelineId;
9091
use msg::constellation_msg::TopLevelBrowsingContextId;
@@ -775,7 +776,7 @@ impl LayoutThread {
775776
let mut reports = vec![];
776777
// Servo uses vanilla jemalloc, which doesn't have a
777778
// malloc_enclosing_size_of function.
778-
let mut ops = MallocSizeOfOps::new(malloc_size_of, None, None);
779+
let mut ops = MallocSizeOfOps::new(::servo_allocator::usable_size, None, None);
779780

780781
// FIXME(njn): Just measuring the display tree for now.
781782
let rw_data = possibly_locked_rw_data.lock();

servo/components/malloc_size_of/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ publish = false
88
[lib]
99
path = "lib.rs"
1010

11-
[target.'cfg(windows)'.dependencies]
12-
kernel32-sys = "0.2.1"
13-
1411
[features]
1512
servo = ["js", "string_cache", "url", "webrender_api", "xml5ever"]
1613

servo/components/malloc_size_of/lib.rs

-31
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ extern crate euclid;
4949
extern crate hashglobe;
5050
#[cfg(feature = "servo")]
5151
extern crate js;
52-
#[cfg(target_os = "windows")]
53-
extern crate kernel32;
5452
extern crate servo_arc;
5553
extern crate smallbitvec;
5654
extern crate smallvec;
@@ -63,8 +61,6 @@ extern crate webrender_api;
6361
#[cfg(feature = "servo")]
6462
extern crate xml5ever;
6563

66-
#[cfg(target_os = "windows")]
67-
use kernel32::{GetProcessHeap, HeapSize, HeapValidate};
6864
use std::hash::{BuildHasher, Hash};
6965
use std::mem::size_of;
7066
use std::ops::Range;
@@ -146,33 +142,6 @@ impl MallocSizeOfOps {
146142
}
147143
}
148144

149-
/// Get the size of a heap block.
150-
#[cfg(not(target_os = "windows"))]
151-
pub unsafe extern "C" fn malloc_size_of(ptr: *const c_void) -> usize {
152-
// The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some
153-
// platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice
154-
// this function doesn't modify the contents of the block that `ptr` points to, so we use
155-
// `*const c_void` here.
156-
extern "C" {
157-
#[cfg_attr(any(prefixed_jemalloc, target_os = "macos", target_os = "ios", target_os = "android"),
158-
link_name = "je_malloc_usable_size")]
159-
fn malloc_usable_size(ptr: *const c_void) -> usize;
160-
}
161-
malloc_usable_size(ptr)
162-
}
163-
164-
/// Get the size of a heap block.
165-
#[cfg(target_os = "windows")]
166-
pub unsafe extern "C" fn malloc_size_of(mut ptr: *const c_void) -> usize {
167-
let heap = GetProcessHeap();
168-
169-
if HeapValidate(heap, 0, ptr) == 0 {
170-
ptr = *(ptr as *const *const c_void).offset(-1);
171-
}
172-
173-
HeapSize(heap, 0, ptr) as usize
174-
}
175-
176145
/// Trait for measuring the "deep" heap usage of a data structure. This is the
177146
/// most commonly-used of the traits.
178147
pub trait MallocSizeOf {

servo/components/profile/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ name = "profile"
1010
path = "lib.rs"
1111

1212
[features]
13-
unstable = []
13+
unstable = ["jemalloc-sys"]
1414

1515
[dependencies]
1616
profile_traits = {path = "../profile_traits"}
@@ -31,3 +31,4 @@ regex = "0.2"
3131

3232
[target.'cfg(not(target_os = "windows"))'.dependencies]
3333
libc = "0.2"
34+
jemalloc-sys = {version = "0.1.3", optional = true}

servo/components/profile/lib.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
#![cfg_attr(all(feature = "unstable", not(target_os = "windows")), feature(alloc_jemalloc))]
6-
75
#![deny(unsafe_code)]
86

97
#[allow(unused_extern_crates)]
10-
#[cfg(all(feature = "unstable", not(target_os = "windows")))]
11-
extern crate alloc_jemalloc;
128
extern crate heartbeats_simple;
139
extern crate influent;
1410
extern crate ipc_channel;
15-
#[allow(unused_extern_crates)]
11+
#[cfg(all(feature = "unstable", not(target_os = "windows")))]
12+
extern crate jemalloc_sys;
1613
#[cfg(not(target_os = "windows"))]
1714
extern crate libc;
1815
#[macro_use]

0 commit comments

Comments
 (0)