Skip to content

Commit 8f924a3

Browse files
committed
Use NonNull in the allocator API
As discussed in #32838 (comment) and following, instead of *mut pointers, use NonNull for the allocator API. One issue is that older rustc versions, used to bootstrap the compiler, expands #[global_allocator], used in various places including libstd or librustc_[almt]san, to code that uses the Alloc trait, so changes to that trait make bootstrapping fail. Thankfully, it does so through the location of the Alloc trait before 94d1970 so we can use at our advantage by making stage0 expose the old API as alloc::heap::Alloc. At the same time, we change the expansion for #[global_allocator] to use the new trait location under core, which will allow newer versions of rustc to bootstrap stage0 as well, despite the workaround described above.
1 parent 199b7e2 commit 8f924a3

File tree

20 files changed

+281
-235
lines changed

20 files changed

+281
-235
lines changed

src/dlmalloc

src/doc/unstable-book/src/language-features/global-allocator.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,16 @@ looks like:
3030
#![feature(global_allocator, allocator_api, heap_api)]
3131

3232
use std::heap::{Alloc, System, Layout, AllocErr};
33+
use std::ptr::NonNull;
3334

3435
struct MyAllocator;
3536

3637
unsafe impl<'a> Alloc for &'a MyAllocator {
37-
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
38+
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
3839
System.alloc(layout)
3940
}
4041

41-
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
42+
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
4243
System.dealloc(ptr, layout)
4344
}
4445
}

src/liballoc/arc.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -513,15 +513,13 @@ impl<T: ?Sized> Arc<T> {
513513
// Non-inlined part of `drop`.
514514
#[inline(never)]
515515
unsafe fn drop_slow(&mut self) {
516-
let ptr = self.ptr.as_ptr();
517-
518516
// Destroy the data at this time, even though we may not free the box
519517
// allocation itself (there may still be weak pointers lying around).
520518
ptr::drop_in_place(&mut self.ptr.as_mut().data);
521519

522520
if self.inner().weak.fetch_sub(1, Release) == 1 {
523521
atomic::fence(Acquire);
524-
Heap.dealloc(ptr as *mut u8, Layout::for_value(&*ptr))
522+
Heap.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
525523
}
526524
}
527525

@@ -559,7 +557,7 @@ impl<T: ?Sized> Arc<T> {
559557
.unwrap_or_else(|e| Heap.oom(e));
560558

561559
// Initialize the real ArcInner
562-
let inner = set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>;
560+
let inner = set_data_ptr(ptr as *mut T, mem.as_ptr()) as *mut ArcInner<T>;
563561

564562
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
565563
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
@@ -626,7 +624,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
626624
// In the event of a panic, elements that have been written
627625
// into the new ArcInner will be dropped, then the memory freed.
628626
struct Guard<T> {
629-
mem: *mut u8,
627+
mem: NonNull<u8>,
630628
elems: *mut T,
631629
layout: Layout,
632630
n_elems: usize,
@@ -656,7 +654,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
656654
let elems = &mut (*ptr).data as *mut [T] as *mut T;
657655

658656
let mut guard = Guard{
659-
mem: mem,
657+
mem: NonNull::new_unchecked(mem),
660658
elems: elems,
661659
layout: layout,
662660
n_elems: 0,
@@ -1148,8 +1146,6 @@ impl<T: ?Sized> Drop for Weak<T> {
11481146
/// assert!(other_weak_foo.upgrade().is_none());
11491147
/// ```
11501148
fn drop(&mut self) {
1151-
let ptr = self.ptr.as_ptr();
1152-
11531149
// If we find out that we were the last weak pointer, then its time to
11541150
// deallocate the data entirely. See the discussion in Arc::drop() about
11551151
// the memory orderings
@@ -1161,7 +1157,7 @@ impl<T: ?Sized> Drop for Weak<T> {
11611157
if self.inner().weak.fetch_sub(1, Release) == 1 {
11621158
atomic::fence(Acquire);
11631159
unsafe {
1164-
Heap.dealloc(ptr as *mut u8, Layout::for_value(&*ptr))
1160+
Heap.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
11651161
}
11661162
}
11671163
}

src/liballoc/btree/node.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl<K, V> Root<K, V> {
237237
pub fn pop_level(&mut self) {
238238
debug_assert!(self.height > 0);
239239

240-
let top = self.node.ptr.as_ptr() as *mut u8;
240+
let top = self.node.ptr;
241241

242242
self.node = unsafe {
243243
BoxedNode::from_ptr(self.as_mut()
@@ -250,7 +250,7 @@ impl<K, V> Root<K, V> {
250250
self.as_mut().as_leaf_mut().parent = ptr::null();
251251

252252
unsafe {
253-
Heap.dealloc(top, Layout::new::<InternalNode<K, V>>());
253+
Heap.dealloc(NonNull::from(top).cast(), Layout::new::<InternalNode<K, V>>());
254254
}
255255
}
256256
}
@@ -434,9 +434,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
434434
marker::Edge
435435
>
436436
> {
437-
let ptr = self.as_leaf() as *const LeafNode<K, V> as *const u8 as *mut u8;
437+
let node = self.node;
438438
let ret = self.ascend().ok();
439-
Heap.dealloc(ptr, Layout::new::<LeafNode<K, V>>());
439+
Heap.dealloc(node.cast(), Layout::new::<LeafNode<K, V>>());
440440
ret
441441
}
442442
}
@@ -455,9 +455,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
455455
marker::Edge
456456
>
457457
> {
458-
let ptr = self.as_internal() as *const InternalNode<K, V> as *const u8 as *mut u8;
458+
let node = self.node;
459459
let ret = self.ascend().ok();
460-
Heap.dealloc(ptr, Layout::new::<InternalNode<K, V>>());
460+
Heap.dealloc(node.cast(), Layout::new::<InternalNode<K, V>>());
461461
ret
462462
}
463463
}
@@ -1240,12 +1240,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
12401240
}
12411241

12421242
Heap.dealloc(
1243-
right_node.node.as_ptr() as *mut u8,
1243+
right_node.node.cast(),
12441244
Layout::new::<InternalNode<K, V>>(),
12451245
);
12461246
} else {
12471247
Heap.dealloc(
1248-
right_node.node.as_ptr() as *mut u8,
1248+
right_node.node.cast(),
12491249
Layout::new::<LeafNode<K, V>>(),
12501250
);
12511251
}

0 commit comments

Comments
 (0)