Stop relying on linking details of std’s default allocator

We’ve been bitten before by symbol names changing:
https://github.com/servo/heapsize/pull/46
and upstream is planning to stop using jemalloc by default:
https://github.com/rust-lang/rust/issues/33082#issuecomment-309781465

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.
This commit is contained in:
Simon Sapin 2017-10-18 13:38:07 +02:00
parent 4c538b642e
commit 959ce482dd
20 changed files with 158 additions and 62 deletions

View file

@ -0,0 +1,18 @@
[package]
name = "servo_allocator"
version = "0.0.1"
authors = ["The Servo Project Developers"]
license = "MPL-2.0"
publish = false
[lib]
path = "lib.rs"
[features]
unstable = ["kernel32-sys", "jemallocator"]
[target.'cfg(not(windows))'.dependencies]
jemallocator = { version = "0.1.3", optional = true }
[target.'cfg(windows)'.dependencies]
kernel32-sys = { version = "0.2.1", optional = true }

View file

@ -0,0 +1,62 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Selecting the default global allocator for Servo
#![cfg_attr(all(feature = "unstable", windows), feature(alloc_system, allocator_api))]
#![cfg_attr(feature = "unstable", feature(global_allocator))]
#[cfg(feature = "unstable")]
#[global_allocator]
static ALLOC: platform::Allocator = platform::Allocator;
pub use platform::usable_size;
#[cfg(all(feature = "unstable", not(windows)))]
mod platform {
extern crate jemallocator;
pub use self::jemallocator::Jemalloc as Allocator;
use std::os::raw::c_void;
/// Get the size of a heap block.
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
jemallocator::usable_size(ptr)
}
}
#[cfg(all(feature = "unstable", windows))]
mod platform {
extern crate alloc_system;
extern crate kernel32;
pub use self::alloc_system::System as Allocator;
use self::kernel32::{GetProcessHeap, HeapSize, HeapValidate};
use std::os::raw::c_void;
/// Get the size of a heap block.
pub unsafe extern "C" fn usable_size(mut ptr: *const c_void) -> usize {
let heap = GetProcessHeap();
if HeapValidate(heap, 0, ptr) == 0 {
ptr = *(ptr as *const *const c_void).offset(-1);
}
HeapSize(heap, 0, ptr) as usize
}
}
#[cfg(not(feature = "unstable"))]
mod platform {
use std::os::raw::c_void;
/// Without `#[global_allocator]` we cannot be certain of what allocator is used
/// or how it is linked. We therefore disable memory reporting. (Return zero.)
pub unsafe extern "C" fn usable_size(_ptr: *const c_void) -> usize {
0
}
}