Skip to content

Commit 4fabdec

Browse files
committed
Add AbortAdapter allocator adapter
See its documentation for why its useful
1 parent a98fe63 commit 4fabdec

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

src/liballoc/abort_adapter.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//! An allocator adapter that blows up by calling `handle_alloc_error` on all errors.
2+
//!
3+
//! On one hand, concrete allocator implementations should always be written
4+
//! without panicking on user error and OOM to give users maximum
5+
//! flexibility. On the other hand, code that depends on allocation succeeding
6+
//! should depend on `Alloc<Err=!>` to avoid repetitively handling errors from
7+
//! which it cannot recover.
8+
//!
9+
//! This adapter bridges the gap, effectively allowing `Alloc<Err=!>` to be
10+
//! implemented by any allocator.
11+
12+
#![unstable(feature = "allocator_api",
13+
reason = "the precise API and guarantees it provides may be tweaked \
14+
slightly, especially to possibly take into account the \
15+
types being stored to make room for a future \
16+
tracing garbage collector",
17+
issue = "32838")]
18+
19+
use core::usize;
20+
use core::ptr::NonNull;
21+
22+
use crate::alloc::*;
23+
24+
/// An allocator adapter that blows up by calling `handle_alloc_error` on all errors.
25+
///
26+
/// See the [module-level documentation](../../std/abort_adapter/index.html) for more.
27+
#[derive(Copy, Clone, Debug, Default)]
28+
pub struct AbortAdapter<Alloc>(pub Alloc);
29+
30+
impl<A: AllocHelper> AllocHelper for AbortAdapter<A> {
31+
type Err = !;
32+
}
33+
34+
unsafe impl<A: Alloc> Alloc for AbortAdapter<A> {
35+
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, Self::Err> {
36+
self.0.alloc(layout).or_else(|_| handle_alloc_error(layout))
37+
}
38+
39+
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
40+
self.0.dealloc(ptr, layout)
41+
}
42+
43+
fn usable_size(&self, layout: &Layout) -> (usize, usize) {
44+
self.0.usable_size(layout)
45+
}
46+
47+
unsafe fn realloc(&mut self,
48+
ptr: NonNull<u8>,
49+
layout: Layout,
50+
new_size: usize) -> Result<NonNull<u8>, Self::Err> {
51+
self.0.realloc(ptr, layout, new_size).or_else(|_| handle_alloc_error(layout))
52+
}
53+
54+
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, Self::Err> {
55+
self.0.alloc_zeroed(layout).or_else(|_| handle_alloc_error(layout))
56+
}
57+
58+
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, Self::Err> {
59+
self.0.alloc_excess(layout).or_else(|_| handle_alloc_error(layout))
60+
}
61+
62+
unsafe fn grow_in_place(&mut self,
63+
ptr: NonNull<u8>,
64+
layout: Layout,
65+
new_size: usize) -> Result<(), CannotReallocInPlace> {
66+
self.0.grow_in_place(ptr, layout, new_size)
67+
}
68+
69+
unsafe fn shrink_in_place(&mut self,
70+
ptr: NonNull<u8>,
71+
layout: Layout,
72+
new_size: usize) -> Result<(), CannotReallocInPlace> {
73+
self.0.shrink_in_place(ptr, layout, new_size)
74+
}
75+
76+
fn alloc_one<T>(&mut self) -> Result<NonNull<T>, Self::Err>
77+
where Self: Sized
78+
{
79+
self.0.alloc_one().or_else(|_| handle_alloc_error(Layout::new::<T>()))
80+
}
81+
82+
unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>)
83+
where Self: Sized
84+
{
85+
self.0.dealloc_one(ptr)
86+
}
87+
88+
fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, Self::Err>
89+
where Self: Sized
90+
{
91+
self.0.alloc_array(n).or_else(|_| handle_alloc_error(Layout::new::<T>()))
92+
}
93+
94+
unsafe fn realloc_array<T>(&mut self,
95+
ptr: NonNull<T>,
96+
n_old: usize,
97+
n_new: usize) -> Result<NonNull<T>, Self::Err>
98+
where Self: Sized
99+
{
100+
self.0.realloc_array(ptr, n_old, n_new)
101+
.or_else(|_| handle_alloc_error(Layout::new::<T>()))
102+
}
103+
104+
unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), Self::Err>
105+
where Self: Sized
106+
{
107+
self.0.dealloc_array(ptr, n).or_else(|_| handle_alloc_error(Layout::new::<T>()))
108+
}
109+
}

src/liballoc/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
#![feature(alloc_layout_extra)]
116116
#![feature(try_trait)]
117117
#![feature(iter_nth_back)]
118+
#![feature(never_type)]
118119

119120
// Allow testing this library
120121

@@ -131,6 +132,7 @@ mod macros;
131132
// Heaps provided for low-level allocation strategies
132133

133134
pub mod alloc;
135+
pub mod abort_adapter;
134136

135137
// Primitive types using the heaps above
136138

0 commit comments

Comments
 (0)