2018-04-03 20:58:50 +02:00
|
|
|
// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2018-04-03 08:51:02 +09:00
|
|
|
#![allow(deprecated)]
|
|
|
|
|
2018-04-11 17:19:48 +02:00
|
|
|
pub use alloc::{Layout, AllocErr, CannotReallocInPlace, Opaque};
|
2018-04-03 20:58:50 +02:00
|
|
|
use core::alloc::Alloc as CoreAlloc;
|
2018-04-03 08:51:02 +09:00
|
|
|
use core::ptr::NonNull;
|
2018-04-03 20:58:50 +02:00
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
pub mod __core {
|
|
|
|
pub use core::*;
|
|
|
|
}
|
|
|
|
|
2018-04-03 08:51:02 +09:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Excess(pub *mut u8, pub usize);
|
|
|
|
|
2018-04-03 20:58:50 +02:00
|
|
|
/// Compatibility with older versions of #[global_allocator] during bootstrap
|
|
|
|
pub unsafe trait Alloc {
|
|
|
|
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
|
|
|
|
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);
|
|
|
|
fn oom(&mut self, err: AllocErr) -> !;
|
|
|
|
fn usable_size(&self, layout: &Layout) -> (usize, usize);
|
|
|
|
unsafe fn realloc(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<*mut u8, AllocErr>;
|
|
|
|
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
|
|
|
|
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr>;
|
|
|
|
unsafe fn realloc_excess(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<Excess, AllocErr>;
|
|
|
|
unsafe fn grow_in_place(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<(), CannotReallocInPlace>;
|
|
|
|
unsafe fn shrink_in_place(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<(), CannotReallocInPlace>;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl<T> Alloc for T where T: CoreAlloc {
|
|
|
|
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
2018-04-03 08:51:02 +09:00
|
|
|
CoreAlloc::alloc(self, layout).map(|ptr| ptr.cast().as_ptr())
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
|
2018-04-11 17:19:48 +02:00
|
|
|
let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
|
2018-04-03 20:58:50 +02:00
|
|
|
CoreAlloc::dealloc(self, ptr, layout)
|
|
|
|
}
|
|
|
|
|
2018-04-03 16:00:04 +02:00
|
|
|
fn oom(&mut self, _: AllocErr) -> ! {
|
2018-04-21 09:47:41 -07:00
|
|
|
unsafe { ::core::intrinsics::abort() }
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn usable_size(&self, layout: &Layout) -> (usize, usize) {
|
|
|
|
CoreAlloc::usable_size(self, layout)
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn realloc(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<*mut u8, AllocErr> {
|
2018-04-11 17:19:48 +02:00
|
|
|
let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
|
2018-04-03 08:51:02 +09:00
|
|
|
CoreAlloc::realloc(self, ptr, layout, new_layout.size()).map(|ptr| ptr.cast().as_ptr())
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
|
2018-04-03 08:51:02 +09:00
|
|
|
CoreAlloc::alloc_zeroed(self, layout).map(|ptr| ptr.cast().as_ptr())
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
|
|
|
|
CoreAlloc::alloc_excess(self, layout)
|
2018-04-03 08:51:02 +09:00
|
|
|
.map(|e| Excess(e.0 .cast().as_ptr(), e.1))
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn realloc_excess(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<Excess, AllocErr> {
|
2018-04-11 17:19:48 +02:00
|
|
|
let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
|
2018-04-04 17:19:16 +02:00
|
|
|
CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size())
|
2018-04-03 08:51:02 +09:00
|
|
|
.map(|e| Excess(e.0 .cast().as_ptr(), e.1))
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn grow_in_place(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
|
2018-04-11 17:19:48 +02:00
|
|
|
let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
|
2018-04-04 17:19:16 +02:00
|
|
|
CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size())
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn shrink_in_place(&mut self,
|
|
|
|
ptr: *mut u8,
|
|
|
|
layout: Layout,
|
|
|
|
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
|
2018-04-11 17:19:48 +02:00
|
|
|
let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
|
2018-04-04 17:19:16 +02:00
|
|
|
CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size())
|
2018-04-03 20:58:50 +02:00
|
|
|
}
|
|
|
|
}
|