Skip to content

Commit

Permalink
Use the GlobalAlloc trait for #[global_allocator]
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonSapin committed Apr 12, 2018
1 parent eb69593 commit 86753ce
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 707 deletions.
1 change: 0 additions & 1 deletion src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -29,16 +29,16 @@ looks like:
```rust
#![feature(global_allocator, allocator_api, heap_api)]

use std::heap::{Alloc, System, Layout, AllocErr};
use std::alloc::{GlobalAlloc, System, Layout, Void};

struct MyAllocator;

unsafe impl<'a> Alloc for &'a MyAllocator {
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
unsafe impl GlobalAlloc for MyAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut Void {
System.alloc(layout)
}

unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) {
System.dealloc(ptr, layout)
}
}
Expand Down
188 changes: 40 additions & 148 deletions src/liballoc/alloc.rs
Expand Up @@ -16,26 +16,19 @@
issue = "32838")]

use core::intrinsics::{min_align_of_val, size_of_val};
use core::mem;
use core::usize;

#[doc(inline)]
pub use core::alloc::*;

#[cfg(stage0)]
extern "Rust" {
#[allocator]
#[rustc_allocator_nounwind]
fn __rust_alloc(size: usize, align: usize, err: *mut u8) -> *mut u8;
#[cold]
#[rustc_allocator_nounwind]
fn __rust_oom(err: *const u8) -> !;
#[rustc_allocator_nounwind]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
#[rustc_allocator_nounwind]
fn __rust_usable_size(layout: *const u8,
min: *mut usize,
max: *mut usize);
#[rustc_allocator_nounwind]
fn __rust_realloc(ptr: *mut u8,
old_size: usize,
old_align: usize,
Expand All @@ -44,31 +37,22 @@ extern "Rust" {
err: *mut u8) -> *mut u8;
#[rustc_allocator_nounwind]
fn __rust_alloc_zeroed(size: usize, align: usize, err: *mut u8) -> *mut u8;
}

#[cfg(not(stage0))]
extern "Rust" {
#[allocator]
#[rustc_allocator_nounwind]
fn __rust_alloc_excess(size: usize,
align: usize,
excess: *mut usize,
err: *mut u8) -> *mut u8;
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
#[rustc_allocator_nounwind]
fn __rust_realloc_excess(ptr: *mut u8,
old_size: usize,
old_align: usize,
new_size: usize,
new_align: usize,
excess: *mut usize,
err: *mut u8) -> *mut u8;
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
#[rustc_allocator_nounwind]
fn __rust_grow_in_place(ptr: *mut u8,
old_size: usize,
old_align: usize,
new_size: usize,
new_align: usize) -> u8;
fn __rust_realloc(ptr: *mut u8,
old_size: usize,
align: usize,
new_size: usize) -> *mut u8;
#[rustc_allocator_nounwind]
fn __rust_shrink_in_place(ptr: *mut u8,
old_size: usize,
old_align: usize,
new_size: usize,
new_align: usize) -> u8;
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
}

#[derive(Copy, Clone, Default, Debug)]
Expand All @@ -86,22 +70,15 @@ pub const Heap: Global = Global;
unsafe impl Alloc for Global {
#[inline]
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
let mut err = AllocErr;
let ptr = __rust_alloc(layout.size(),
layout.align(),
&mut err as *mut AllocErr as *mut u8);
if ptr.is_null() {
Err(AllocErr)
} else {
Ok(ptr)
}
}
#[cfg(not(stage0))]
let ptr = __rust_alloc(layout.size(), layout.align());
#[cfg(stage0)]
let ptr = __rust_alloc(layout.size(), layout.align(), &mut 0);

#[inline]
#[cold]
fn oom(&mut self, err: AllocErr) -> ! {
unsafe {
__rust_oom(&err as *const AllocErr as *const u8)
if !ptr.is_null() {
Ok(ptr)
} else {
Err(AllocErr)
}
}

Expand All @@ -110,126 +87,41 @@ unsafe impl Alloc for Global {
__rust_dealloc(ptr, layout.size(), layout.align())
}

#[inline]
fn usable_size(&self, layout: &Layout) -> (usize, usize) {
let mut min = 0;
let mut max = 0;
unsafe {
__rust_usable_size(layout as *const Layout as *const u8,
&mut min,
&mut max);
}
(min, max)
}

#[inline]
unsafe fn realloc(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout)
-> Result<*mut u8, AllocErr>
{
let mut err = AllocErr;
let ptr = __rust_realloc(ptr,
layout.size(),
layout.align(),
new_layout.size(),
new_layout.align(),
&mut err as *mut AllocErr as *mut u8);
if ptr.is_null() {
Err(AllocErr)
if layout.align() == new_layout.align() {
#[cfg(not(stage0))]
let ptr = __rust_realloc(ptr, layout.size(), layout.align(), new_layout.size());
#[cfg(stage0)]
let ptr = __rust_realloc(ptr, layout.size(), layout.align(),
new_layout.size(), new_layout.align(), &mut 0);

if !ptr.is_null() {
Ok(ptr)
} else {
Err(AllocErr)
}
} else {
mem::forget(err);
Ok(ptr)
Err(AllocErr)
}
}

#[inline]
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
let mut err = AllocErr;
let ptr = __rust_alloc_zeroed(layout.size(),
layout.align(),
&mut err as *mut AllocErr as *mut u8);
if ptr.is_null() {
Err(AllocErr)
} else {
Ok(ptr)
}
}
#[cfg(not(stage0))]
let ptr = __rust_alloc_zeroed(layout.size(), layout.align());
#[cfg(stage0)]
let ptr = __rust_alloc_zeroed(layout.size(), layout.align(), &mut 0);

#[inline]
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
let mut err = AllocErr;
let mut size = 0;
let ptr = __rust_alloc_excess(layout.size(),
layout.align(),
&mut size,
&mut err as *mut AllocErr as *mut u8);
if ptr.is_null() {
Err(AllocErr)
if !ptr.is_null() {
Ok(ptr)
} else {
Ok(Excess(ptr, size))
}
}

#[inline]
unsafe fn realloc_excess(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<Excess, AllocErr> {
let mut err = AllocErr;
let mut size = 0;
let ptr = __rust_realloc_excess(ptr,
layout.size(),
layout.align(),
new_layout.size(),
new_layout.align(),
&mut size,
&mut err as *mut AllocErr as *mut u8);
if ptr.is_null() {
Err(AllocErr)
} else {
Ok(Excess(ptr, size))
}
}

#[inline]
unsafe fn grow_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout)
-> Result<(), CannotReallocInPlace>
{
debug_assert!(new_layout.size() >= layout.size());
debug_assert!(new_layout.align() == layout.align());
let ret = __rust_grow_in_place(ptr,
layout.size(),
layout.align(),
new_layout.size(),
new_layout.align());
if ret != 0 {
Ok(())
} else {
Err(CannotReallocInPlace)
}
}

#[inline]
unsafe fn shrink_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
debug_assert!(new_layout.size() <= layout.size());
debug_assert!(new_layout.align() == layout.align());
let ret = __rust_shrink_in_place(ptr,
layout.size(),
layout.align(),
new_layout.size(),
new_layout.align());
if ret != 0 {
Ok(())
} else {
Err(CannotReallocInPlace)
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/liballoc_jemalloc/Cargo.toml
Expand Up @@ -12,7 +12,6 @@ test = false
doc = false

[dependencies]
alloc_system = { path = "../liballoc_system" }
core = { path = "../libcore" }
libc = { path = "../rustc/libc_shim" }
compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
Expand Down

0 comments on commit 86753ce

Please sign in to comment.