@@ -14,10 +14,24 @@ struct Chonk<const N: usize> {
14
14
}
15
15
16
16
impl < const N : usize > Chonk < N > {
17
- pub fn new ( ) -> Self {
18
- Self {
19
- data : MaybeUninit :: uninit ( ) ,
20
- }
17
+ /// Returns (almost certainly aliasing) pointers to the Chonk
18
+ /// as well as the data payload.
19
+ ///
20
+ /// MUST be freed with a matching call to `Chonk::unleak`
21
+ pub fn new ( ) -> ( * mut Chonk < N > , * mut u8 ) {
22
+ let heap_space_ptr: * mut Chonk < N > = {
23
+ let owned_box = Box :: new ( Self {
24
+ data : MaybeUninit :: uninit ( ) ,
25
+ } ) ;
26
+ let mutref = Box :: leak ( owned_box) ;
27
+ mutref
28
+ } ;
29
+ let data_ptr: * mut u8 = unsafe { core:: ptr:: addr_of_mut!( ( * heap_space_ptr) . data) . cast ( ) } ;
30
+ ( heap_space_ptr, data_ptr)
31
+ }
32
+
33
+ pub unsafe fn unleak ( putter : * mut Chonk < N > ) {
34
+ drop ( Box :: from_raw ( putter) )
21
35
}
22
36
}
23
37
@@ -42,57 +56,36 @@ impl<F> DerefMut for OwnedHeap<F> {
42
56
43
57
pub fn new_heap ( ) -> OwnedHeap < impl Sized > {
44
58
const HEAP_SIZE : usize = 1000 ;
45
- let heap_space_ptr: * mut Chonk < HEAP_SIZE > = {
46
- let owned_box = Box :: new ( Chonk :: < HEAP_SIZE > :: new ( ) ) ;
47
- let mutref = Box :: leak ( owned_box) ;
48
- mutref
49
- } ;
50
- let data_ptr: * mut u8 = unsafe { core:: ptr:: addr_of_mut!( ( * heap_space_ptr) . data) . cast ( ) } ;
59
+ let ( heap_space_ptr, data_ptr) = Chonk :: < HEAP_SIZE > :: new ( ) ;
51
60
52
61
let heap = unsafe { Heap :: new ( data_ptr, HEAP_SIZE ) } ;
53
62
assert_eq ! ( heap. bottom( ) , data_ptr) ;
54
63
assert_eq ! ( heap. size( ) , align_down_size( HEAP_SIZE , size_of:: <usize >( ) ) ) ;
55
- let drop = move || {
56
- let _ = unsafe { Box :: from_raw ( heap_space_ptr) } ;
57
- } ;
64
+ let drop = move || unsafe { Chonk :: unleak ( heap_space_ptr) } ;
58
65
OwnedHeap { heap, _drop : drop }
59
66
}
60
67
61
68
fn new_max_heap ( ) -> OwnedHeap < impl Sized > {
62
69
const HEAP_SIZE : usize = 1024 ;
63
70
const HEAP_SIZE_MAX : usize = 2048 ;
64
- let heap_space_ptr: * mut Chonk < HEAP_SIZE_MAX > = {
65
- let owned_box = Box :: new ( Chonk :: < HEAP_SIZE_MAX > :: new ( ) ) ;
66
- let mutref = Box :: leak ( owned_box) ;
67
- mutref
68
- } ;
69
- let data_ptr: * mut u8 = unsafe { core:: ptr:: addr_of_mut!( ( * heap_space_ptr) . data) . cast ( ) } ;
71
+ let ( heap_space_ptr, data_ptr) = Chonk :: < HEAP_SIZE_MAX > :: new ( ) ;
70
72
71
73
// Unsafe so that we have provenance over the whole allocation.
72
74
let heap = unsafe { Heap :: new ( data_ptr, HEAP_SIZE ) } ;
73
75
assert_eq ! ( heap. bottom( ) , data_ptr) ;
74
76
assert_eq ! ( heap. size( ) , HEAP_SIZE ) ;
75
77
76
- let drop = move || {
77
- let _ = unsafe { Box :: from_raw ( heap_space_ptr) } ;
78
- } ;
78
+ let drop = move || unsafe { Chonk :: unleak ( heap_space_ptr) } ;
79
79
OwnedHeap { heap, _drop : drop }
80
80
}
81
81
82
82
fn new_heap_skip ( ct : usize ) -> OwnedHeap < impl Sized > {
83
83
const HEAP_SIZE : usize = 1000 ;
84
- let heap_space_ptr: * mut Chonk < HEAP_SIZE > = {
85
- let owned_box = Box :: new ( Chonk :: < HEAP_SIZE > :: new ( ) ) ;
86
- let mutref = Box :: leak ( owned_box) ;
87
- mutref
88
- } ;
89
- let data_ptr: * mut u8 = unsafe { core:: ptr:: addr_of_mut!( ( * heap_space_ptr) . data) . cast ( ) } ;
84
+ let ( heap_space_ptr, data_ptr) = Chonk :: < HEAP_SIZE > :: new ( ) ;
90
85
91
86
let heap = unsafe { Heap :: new ( data_ptr. add ( ct) , HEAP_SIZE - ct) } ;
92
87
93
- let drop = move || {
94
- let _ = unsafe { Box :: from_raw ( heap_space_ptr) } ;
95
- } ;
88
+ let drop = move || unsafe { Chonk :: unleak ( heap_space_ptr) } ;
96
89
OwnedHeap { heap, _drop : drop }
97
90
}
98
91
@@ -106,12 +99,7 @@ fn empty() {
106
99
#[ test]
107
100
fn oom ( ) {
108
101
const HEAP_SIZE : usize = 1000 ;
109
- let heap_space_ptr: * mut Chonk < HEAP_SIZE > = {
110
- let owned_box = Box :: new ( Chonk :: < HEAP_SIZE > :: new ( ) ) ;
111
- let mutref = Box :: leak ( owned_box) ;
112
- mutref
113
- } ;
114
- let data_ptr: * mut u8 = unsafe { core:: ptr:: addr_of_mut!( ( * heap_space_ptr) . data) . cast ( ) } ;
102
+ let ( heap_space_ptr, data_ptr) = Chonk :: < HEAP_SIZE > :: new ( ) ;
115
103
116
104
let mut heap = unsafe { Heap :: new ( data_ptr, HEAP_SIZE ) } ;
117
105
assert_eq ! ( heap. bottom( ) , data_ptr) ;
@@ -120,9 +108,9 @@ fn oom() {
120
108
let layout = Layout :: from_size_align ( heap. size ( ) + 1 , align_of :: < usize > ( ) ) ;
121
109
let addr = heap. allocate_first_fit ( layout. unwrap ( ) ) ;
122
110
assert ! ( addr. is_err( ) ) ;
123
-
111
+
124
112
// Explicitly unleak the heap allocation
125
- let _ = unsafe { Box :: from_raw ( heap_space_ptr) } ;
113
+ unsafe { Chonk :: unleak ( heap_space_ptr) } ;
126
114
}
127
115
128
116
#[ test]
0 commit comments