Skip to content

Commit 2e67cfe

Browse files
Update to use the new allocator APIs.
1 parent 794c2d6 commit 2e67cfe

File tree

2 files changed

+27
-36
lines changed

2 files changed

+27
-36
lines changed

src/destructors.md

+14-21
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,23 @@ this is totally fine.
2626
For instance, a custom implementation of `Box` might write `Drop` like this:
2727

2828
```rust
29-
#![feature(alloc, heap_api, unique)]
29+
#![feature(alloc, heap_api, unique, allocator_api)]
3030

3131
extern crate alloc;
3232

3333
use std::ptr::{drop_in_place, Unique};
3434
use std::mem;
3535

36-
use alloc::heap;
36+
use alloc::allocator::{Layout, Alloc};
37+
use alloc::heap::Heap;
3738

3839
struct Box<T>{ ptr: Unique<T> }
3940

4041
impl<T> Drop for Box<T> {
4142
fn drop(&mut self) {
4243
unsafe {
4344
drop_in_place(self.ptr.as_ptr());
44-
heap::deallocate(self.ptr.as_ptr() as *mut u8,
45-
mem::size_of::<T>(),
46-
mem::align_of::<T>());
45+
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>())
4746
}
4847
}
4948
}
@@ -57,24 +56,23 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible.
5756
However this wouldn't work:
5857

5958
```rust
60-
#![feature(alloc, heap_api, unique)]
59+
#![feature(alloc, allocator_api, heap_api, unique)]
6160

6261
extern crate alloc;
6362

6463
use std::ptr::{drop_in_place, Unique};
6564
use std::mem;
6665

67-
use alloc::heap;
66+
use alloc::allocator::{Layout, Alloc};
67+
use alloc::heap::Heap;
6868

6969
struct Box<T>{ ptr: Unique<T> }
7070

7171
impl<T> Drop for Box<T> {
7272
fn drop(&mut self) {
7373
unsafe {
7474
drop_in_place(self.ptr.as_ptr());
75-
heap::deallocate(self.ptr.as_ptr() as *mut u8,
76-
mem::size_of::<T>(),
77-
mem::align_of::<T>());
75+
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>());
7876
}
7977
}
8078
}
@@ -86,9 +84,7 @@ impl<T> Drop for SuperBox<T> {
8684
unsafe {
8785
// Hyper-optimized: deallocate the box's contents for it
8886
// without `drop`ing the contents
89-
heap::deallocate(self.my_box.ptr.as_ptr() as *mut u8,
90-
mem::size_of::<T>(),
91-
mem::align_of::<T>());
87+
Heap.dealloc(self.my_box.ptr.as_ptr() as *mut u8, Layout::new::<T>());
9288
}
9389
}
9490
}
@@ -135,24 +131,23 @@ The classic safe solution to overriding recursive drop and allowing moving out
135131
of Self during `drop` is to use an Option:
136132

137133
```rust
138-
#![feature(alloc, heap_api, unique)]
134+
#![feature(alloc, allocator_api, heap_api, unique)]
139135

140136
extern crate alloc;
141137

142138
use std::ptr::{drop_in_place, Unique};
143139
use std::mem;
144140

145-
use alloc::heap;
141+
use alloc::allocator::{Layout, Alloc};
142+
use alloc::heap::Heap;
146143

147144
struct Box<T>{ ptr: Unique<T> }
148145

149146
impl<T> Drop for Box<T> {
150147
fn drop(&mut self) {
151148
unsafe {
152149
drop_in_place(self.ptr.as_ptr());
153-
heap::deallocate(self.ptr.as_ptr() as *mut u8,
154-
mem::size_of::<T>(),
155-
mem::align_of::<T>());
150+
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>());
156151
}
157152
}
158153
}
@@ -166,9 +161,7 @@ impl<T> Drop for SuperBox<T> {
166161
// without `drop`ing the contents. Need to set the `box`
167162
// field as `None` to prevent Rust from trying to Drop it.
168163
let my_box = self.my_box.take().unwrap();
169-
heap::deallocate(my_box.ptr.as_ptr() as *mut u8,
170-
mem::size_of::<T>(),
171-
mem::align_of::<T>());
164+
Heap.dealloc(my_box.ptr.as_ptr() as *mut u8, Layout::new::<T>());
172165
mem::forget(my_box);
173166
}
174167
}

src/vec-final.md

+13-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
```rust
44
#![feature(unique)]
5-
#![feature(alloc, heap_api)]
5+
#![feature(alloc, allocator_api, heap_api)]
66

77
extern crate alloc;
88

@@ -11,7 +11,8 @@ use std::mem;
1111
use std::ops::{Deref, DerefMut};
1212
use std::marker::PhantomData;
1313

14-
use alloc::heap;
14+
use alloc::allocator::{Layout, Alloc};
15+
use alloc::heap::Heap;
1516

1617
struct RawVec<T> {
1718
ptr: Unique<T>,
@@ -35,22 +36,22 @@ impl<T> RawVec<T> {
3536
// 0, getting to here necessarily means the Vec is overfull.
3637
assert!(elem_size != 0, "capacity overflow");
3738

38-
let align = mem::align_of::<T>();
39-
4039
let (new_cap, ptr) = if self.cap == 0 {
41-
let ptr = heap::allocate(elem_size, align);
40+
let ptr = Heap.alloc(Layout::array::<T>(1).unwrap());
4241
(1, ptr)
4342
} else {
4443
let new_cap = 2 * self.cap;
45-
let ptr = heap::reallocate(self.ptr.as_ptr() as *mut _,
46-
self.cap * elem_size,
47-
new_cap * elem_size,
48-
align);
44+
let ptr = Heap.realloc(self.ptr.as_ptr() as *mut _,
45+
Layout::array::<T>(self.cap).unwrap(),
46+
Layout::array::<T>(new_cap).unwrap());
4947
(new_cap, ptr)
5048
};
5149

52-
// If allocate or reallocate fail, we'll get `null` back
53-
if ptr.is_null() { oom() }
50+
// If allocate or reallocate fail, oom
51+
let ptr = match ptr {
52+
Ok(ptr) => ptr,
53+
Err(err) => Heap.oom(err),
54+
};
5455

5556
self.ptr = Unique::new(ptr as *mut _);
5657
self.cap = new_cap;
@@ -62,11 +63,8 @@ impl<T> Drop for RawVec<T> {
6263
fn drop(&mut self) {
6364
let elem_size = mem::size_of::<T>();
6465
if self.cap != 0 && elem_size != 0 {
65-
let align = mem::align_of::<T>();
66-
67-
let num_bytes = elem_size * self.cap;
6866
unsafe {
69-
heap::deallocate(self.ptr.as_ptr() as *mut _, num_bytes, align);
67+
Heap.dealloc(self.ptr.as_ptr() as *mut _, Layout::array::<T>(self.cap).unwrap());
7068
}
7169
}
7270
}

0 commit comments

Comments
 (0)