Update to use the new allocator APIs.

pull/31/head
Mark Simulacrum 7 years ago
parent 794c2d6302
commit 2e67cfed79

@ -26,14 +26,15 @@ this is totally fine.
For instance, a custom implementation of `Box` might write `Drop` like this:
```rust
#![feature(alloc, heap_api, unique)]
#![feature(alloc, heap_api, unique, allocator_api)]
extern crate alloc;
use std::ptr::{drop_in_place, Unique};
use std::mem;
use alloc::heap;
use alloc::allocator::{Layout, Alloc};
use alloc::heap::Heap;
struct Box<T>{ ptr: Unique<T> }
@ -41,9 +42,7 @@ impl<T> Drop for Box<T> {
fn drop(&mut self) {
unsafe {
drop_in_place(self.ptr.as_ptr());
heap::deallocate(self.ptr.as_ptr() as *mut u8,
mem::size_of::<T>(),
mem::align_of::<T>());
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>())
}
}
}
@ -57,14 +56,15 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible.
However this wouldn't work:
```rust
#![feature(alloc, heap_api, unique)]
#![feature(alloc, allocator_api, heap_api, unique)]
extern crate alloc;
use std::ptr::{drop_in_place, Unique};
use std::mem;
use alloc::heap;
use alloc::allocator::{Layout, Alloc};
use alloc::heap::Heap;
struct Box<T>{ ptr: Unique<T> }
@ -72,9 +72,7 @@ impl<T> Drop for Box<T> {
fn drop(&mut self) {
unsafe {
drop_in_place(self.ptr.as_ptr());
heap::deallocate(self.ptr.as_ptr() as *mut u8,
mem::size_of::<T>(),
mem::align_of::<T>());
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>());
}
}
}
@ -86,9 +84,7 @@ impl<T> Drop for SuperBox<T> {
unsafe {
// Hyper-optimized: deallocate the box's contents for it
// without `drop`ing the contents
heap::deallocate(self.my_box.ptr.as_ptr() as *mut u8,
mem::size_of::<T>(),
mem::align_of::<T>());
Heap.dealloc(self.my_box.ptr.as_ptr() as *mut u8, Layout::new::<T>());
}
}
}
@ -135,14 +131,15 @@ The classic safe solution to overriding recursive drop and allowing moving out
of Self during `drop` is to use an Option:
```rust
#![feature(alloc, heap_api, unique)]
#![feature(alloc, allocator_api, heap_api, unique)]
extern crate alloc;
use std::ptr::{drop_in_place, Unique};
use std::mem;
use alloc::heap;
use alloc::allocator::{Layout, Alloc};
use alloc::heap::Heap;
struct Box<T>{ ptr: Unique<T> }
@ -150,9 +147,7 @@ impl<T> Drop for Box<T> {
fn drop(&mut self) {
unsafe {
drop_in_place(self.ptr.as_ptr());
heap::deallocate(self.ptr.as_ptr() as *mut u8,
mem::size_of::<T>(),
mem::align_of::<T>());
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>());
}
}
}
@ -166,9 +161,7 @@ impl<T> Drop for SuperBox<T> {
// without `drop`ing the contents. Need to set the `box`
// field as `None` to prevent Rust from trying to Drop it.
let my_box = self.my_box.take().unwrap();
heap::deallocate(my_box.ptr.as_ptr() as *mut u8,
mem::size_of::<T>(),
mem::align_of::<T>());
Heap.dealloc(my_box.ptr.as_ptr() as *mut u8, Layout::new::<T>());
mem::forget(my_box);
}
}

@ -2,7 +2,7 @@
```rust
#![feature(unique)]
#![feature(alloc, heap_api)]
#![feature(alloc, allocator_api, heap_api)]
extern crate alloc;
@ -11,7 +11,8 @@ use std::mem;
use std::ops::{Deref, DerefMut};
use std::marker::PhantomData;
use alloc::heap;
use alloc::allocator::{Layout, Alloc};
use alloc::heap::Heap;
struct RawVec<T> {
ptr: Unique<T>,
@ -35,22 +36,22 @@ impl<T> RawVec<T> {
// 0, getting to here necessarily means the Vec is overfull.
assert!(elem_size != 0, "capacity overflow");
let align = mem::align_of::<T>();
let (new_cap, ptr) = if self.cap == 0 {
let ptr = heap::allocate(elem_size, align);
let ptr = Heap.alloc(Layout::array::<T>(1).unwrap());
(1, ptr)
} else {
let new_cap = 2 * self.cap;
let ptr = heap::reallocate(self.ptr.as_ptr() as *mut _,
self.cap * elem_size,
new_cap * elem_size,
align);
let ptr = Heap.realloc(self.ptr.as_ptr() as *mut _,
Layout::array::<T>(self.cap).unwrap(),
Layout::array::<T>(new_cap).unwrap());
(new_cap, ptr)
};
// If allocate or reallocate fail, we'll get `null` back
if ptr.is_null() { oom() }
// If allocate or reallocate fail, oom
let ptr = match ptr {
Ok(ptr) => ptr,
Err(err) => Heap.oom(err),
};
self.ptr = Unique::new(ptr as *mut _);
self.cap = new_cap;
@ -62,11 +63,8 @@ impl<T> Drop for RawVec<T> {
fn drop(&mut self) {
let elem_size = mem::size_of::<T>();
if self.cap != 0 && elem_size != 0 {
let align = mem::align_of::<T>();
let num_bytes = elem_size * self.cap;
unsafe {
heap::deallocate(self.ptr.as_ptr() as *mut _, num_bytes, align);
Heap.dealloc(self.ptr.as_ptr() as *mut _, Layout::array::<T>(self.cap).unwrap());
}
}
}

Loading…
Cancel
Save