diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2017-10-18 13:38:07 +0200 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2017-10-19 09:52:50 +0200 |
commit | 959ce482dd9f2f8c469964b8c258bd3e45f7ca2b (patch) | |
tree | b20d798d3ee0f78ba2f95012e111aaf17bb56462 /components/allocator/lib.rs | |
parent | 4c538b642e4bdfbf42c522c5a59c258a6d14546e (diff) | |
download | servo-959ce482dd9f2f8c469964b8c258bd3e45f7ca2b.tar.gz servo-959ce482dd9f2f8c469964b8c258bd3e45f7ca2b.zip |
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.
Diffstat (limited to 'components/allocator/lib.rs')
-rw-r--r-- | components/allocator/lib.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/components/allocator/lib.rs b/components/allocator/lib.rs new file mode 100644 index 00000000000..e832e485575 --- /dev/null +++ b/components/allocator/lib.rs @@ -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 + } +} + + |