Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the jemallocator crate from crates.io instead of alloc_jemalloc #18836

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Use the jemallocator crate from crates.io instead of alloc_jemalloc

This compiles a new copy of jemalloc in addition to the one brought
by the Rust standard library, but:

* Only one of those ends up being linked
* The increase in compile times is small (20 seconds on my laptop)

This commit also adds an use of `#[global_allocator]` to select
`jemallocator` as the default.
`extern crate alloc_jemalloc;` used to decide the default,
but it hasn’t since the `#[global_allocator]` attribute was introduced.

`mallctl_set(b"epoch\0", 0_u64)` ends up calling `mallctl`
with null pointers for the "old" value and its length,
which isn’t the same as what we were doing before
(passing the same pointer to both "old" and "new" parameters).
My understanding is that this works too,
since the important part is passing a new value:

http://jemalloc.net/jemalloc.3.html#epoch
>  epoch (uint64_t) rw
>
> If a value is passed in, refresh the data from which
> the mallctl*() functions report values, and increment the epoch.
> Return the current epoch. This is useful for detecting whether
> another thread caused a refresh.
  • Loading branch information
SimonSapin committed Oct 12, 2017
commit 15687b45f77fa55477898603f2b9ef2e9a701f72

Some generated files are not rendered by default. Learn more.

@@ -27,4 +27,5 @@ task_info = {path = "../../support/rust-task_info"}
regex = "0.2"

[target.'cfg(not(target_os = "windows"))'.dependencies]
jemallocator = "0.1"
libc = "0.2"
@@ -2,14 +2,10 @@
* 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/. */

#![cfg_attr(not(target_os = "windows"), feature(alloc_jemalloc))]
#![cfg_attr(not(target_os = "windows"), feature(global_allocator))]
#![feature(box_syntax)]

#![deny(unsafe_code)]

#[allow(unused_extern_crates)]
#[cfg(not(target_os = "windows"))]
extern crate alloc_jemalloc;
#[cfg(not(target_os = "windows"))] extern crate jemallocator;
extern crate heartbeats_simple;
extern crate influent;
extern crate ipc_channel;
@@ -29,9 +25,11 @@ extern crate servo_config;
extern crate task_info;
extern crate time as std_time;

#[allow(unsafe_code)]
mod heartbeats;
#[allow(unsafe_code)]
pub mod mem;
pub mod time;
pub mod trace_dump;
#[deny(unsafe_code)] pub mod time;
#[deny(unsafe_code)] pub mod trace_dump;

#[cfg(not(target_os = "windows"))]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
@@ -354,14 +354,8 @@ impl ReportsForest {

mod system_reporter {
#[cfg(not(target_os = "windows"))]
use libc::{c_char, c_int, c_void, size_t};
use libc::{c_int, size_t};
use profile_traits::mem::{Report, ReportKind, ReporterRequest};
#[cfg(not(target_os = "windows"))]
use std::ffi::CString;
#[cfg(not(target_os = "windows"))]
use std::mem::size_of;
#[cfg(not(target_os = "windows"))]
use std::ptr::null_mut;
use super::{JEMALLOC_HEAP_ALLOCATED_STR, SYSTEM_HEAP_ALLOCATED_STR};
#[cfg(target_os = "macos")]
use task_info::task_basic_info::{virtual_size, resident_size};
@@ -397,17 +391,17 @@ mod system_reporter {
// directly from the jemalloc documentation.

// "Total number of bytes allocated by the application."
report(path![JEMALLOC_HEAP_ALLOCATED_STR], jemalloc_stat("stats.allocated"));
report(path![JEMALLOC_HEAP_ALLOCATED_STR], jemalloc_stat("stats.allocated\0"));

// "Total number of bytes in active pages allocated by the application.
// This is a multiple of the page size, and greater than or equal to
// |stats.allocated|."
report(path!["jemalloc-heap-active"], jemalloc_stat("stats.active"));
report(path!["jemalloc-heap-active"], jemalloc_stat("stats.active\0"));

// "Total number of bytes in chunks mapped on behalf of the application.
// This is a multiple of the chunk size, and is at least as large as
// |stats.active|. This does not include inactive chunks."
report(path!["jemalloc-heap-mapped"], jemalloc_stat("stats.mapped"));
report(path!["jemalloc-heap-mapped"], jemalloc_stat("stats.mapped\0"));
}

request.reports_channel.send(reports);
@@ -457,47 +451,22 @@ mod system_reporter {
None
}

#[cfg(not(target_os = "windows"))]
extern {
#[cfg_attr(any(target_os = "macos", target_os = "android"), link_name = "je_mallctl")]
fn mallctl(name: *const c_char, oldp: *mut c_void, oldlenp: *mut size_t,
newp: *mut c_void, newlen: size_t) -> c_int;
}

#[cfg(not(target_os = "windows"))]
fn jemalloc_stat(value_name: &str) -> Option<usize> {
// Before we request the measurement of interest, we first send an "epoch"
// request. Without that jemalloc gives cached statistics(!) which can be
// highly inaccurate.
let epoch_name = "epoch";
let epoch_c_name = CString::new(epoch_name).unwrap();
let mut epoch: u64 = 0;
let epoch_ptr = &mut epoch as *mut _ as *mut c_void;
let mut epoch_len = size_of::<u64>() as size_t;

let value_c_name = CString::new(value_name).unwrap();
let mut value: size_t = 0;
let value_ptr = &mut value as *mut _ as *mut c_void;
let mut value_len = size_of::<size_t>() as size_t;

// Using the same values for the `old` and `new` parameters is enough
// to get the statistics updated.
let rv = unsafe {
mallctl(epoch_c_name.as_ptr(), epoch_ptr, &mut epoch_len, epoch_ptr,
epoch_len)
};
if rv != 0 {
return None;
}
unsafe {
// Before we request the measurement of interest, we first send an "epoch"
// request. Without that jemalloc gives cached statistics(!) which can be
// highly inaccurate.
if ::jemallocator::mallctl_set(b"epoch\0", 0_u64).is_err() {
return None
}

let rv = unsafe {
mallctl(value_c_name.as_ptr(), value_ptr, &mut value_len, null_mut(), 0)
};
if rv != 0 {
return None;
let mut value: size_t = 0;
if ::jemallocator::mallctl_fetch(value_name.as_bytes(), &mut value).is_err() {
return None
}
Some(value as usize)
}

Some(value as usize)
}

#[cfg(target_os = "windows")]
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.