15
15
//! `Alloc` trait and is suitable both as a memory allocator and as a
16
16
//! global allocator.
17
17
18
- #![ feature( allocator_api) ]
18
+ #![ feature( allocator_api, nonnull_cast ) ]
19
19
#![ deny( missing_docs) ]
20
20
21
21
extern crate jemalloc_sys;
22
22
extern crate libc;
23
23
24
24
use std:: mem;
25
- use std:: ptr;
26
- use std:: heap:: { Alloc , Layout , Excess , CannotReallocInPlace , AllocErr , System } ;
25
+ use std:: ptr:: { self , NonNull } ;
26
+ use std:: heap:: { GlobalAlloc , Alloc , Layout , Opaque , Excess , CannotReallocInPlace , AllocErr , System } ;
27
27
28
28
use libc:: { c_int, c_void} ;
29
29
@@ -45,16 +45,16 @@ const MIN_ALIGN: usize = 8;
45
45
target_arch = "sparc64" ) ) ) ]
46
46
const MIN_ALIGN : usize = 16 ;
47
47
48
- fn layout_to_flags ( layout : & Layout ) -> c_int {
48
+ fn layout_to_flags ( align : usize , size : usize ) -> c_int {
49
49
// If our alignment is less than the minimum alignment they we may not
50
50
// have to pass special flags asking for a higher alignment. If the
51
51
// alignment is greater than the size, however, then this hits a sort of odd
52
52
// case where we still need to ask for a custom alignment. See #25 for more
53
53
// info.
54
- if layout . align ( ) <= MIN_ALIGN && layout . align ( ) <= layout . size ( ) {
54
+ if align <= MIN_ALIGN && align <= size {
55
55
0
56
56
} else {
57
- ffi:: MALLOCX_ALIGN ( layout . align ( ) )
57
+ ffi:: MALLOCX_ALIGN ( align)
58
58
}
59
59
}
60
60
@@ -66,160 +66,106 @@ fn layout_to_flags(layout: &Layout) -> c_int {
66
66
/// allocator.
67
67
pub struct Jemalloc ;
68
68
69
- unsafe impl Alloc for Jemalloc {
70
- #[ inline]
71
- unsafe fn alloc ( & mut self , layout : Layout ) -> Result < * mut u8 , AllocErr > {
72
- ( & * self ) . alloc ( layout)
73
- }
74
-
75
- #[ inline]
76
- unsafe fn alloc_zeroed ( & mut self , layout : Layout )
77
- -> Result < * mut u8 , AllocErr >
78
- {
79
- ( & * self ) . alloc_zeroed ( layout)
80
- }
81
-
69
+ unsafe impl GlobalAlloc for Jemalloc {
82
70
#[ inline]
83
- unsafe fn dealloc ( & mut self , ptr : * mut u8 , layout : Layout ) {
84
- ( & * self ) . dealloc ( ptr, layout)
71
+ unsafe fn alloc ( & self , layout : Layout ) -> * mut Opaque {
72
+ let flags = layout_to_flags ( layout. align ( ) , layout. size ( ) ) ;
73
+ let ptr = ffi:: mallocx ( layout. size ( ) , flags) ;
74
+ ptr as * mut Opaque
85
75
}
86
76
87
77
#[ inline]
88
- unsafe fn realloc ( & mut self ,
89
- ptr : * mut u8 ,
90
- old_layout : Layout ,
91
- new_layout : Layout ) -> Result < * mut u8 , AllocErr > {
92
- ( & * self ) . realloc ( ptr, old_layout, new_layout)
93
- }
94
-
95
- fn oom ( & mut self , err : AllocErr ) -> ! {
96
- ( & * self ) . oom ( err)
78
+ unsafe fn alloc_zeroed ( & self , layout : Layout ) -> * mut Opaque {
79
+ let ptr = if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
80
+ ffi:: calloc ( 1 , layout. size ( ) )
81
+ } else {
82
+ let flags = layout_to_flags ( layout. align ( ) , layout. size ( ) ) | ffi:: MALLOCX_ZERO ;
83
+ ffi:: mallocx ( layout. size ( ) , flags)
84
+ } ;
85
+ ptr as * mut Opaque
97
86
}
98
87
99
88
#[ inline]
100
- fn usable_size ( & self , layout : & Layout ) -> ( usize , usize ) {
101
- ( & self ) . usable_size ( layout)
89
+ unsafe fn dealloc ( & self , ptr : * mut Opaque , layout : Layout ) {
90
+ let flags = layout_to_flags ( layout. align ( ) , layout. size ( ) ) ;
91
+ ffi:: sdallocx ( ptr as * mut c_void , layout. size ( ) , flags)
102
92
}
103
93
104
94
#[ inline]
105
- unsafe fn alloc_excess ( & mut self , layout : Layout ) -> Result < Excess , AllocErr > {
106
- ( & * self ) . alloc_excess ( layout)
95
+ unsafe fn realloc ( & self ,
96
+ ptr : * mut Opaque ,
97
+ layout : Layout ,
98
+ new_size : usize ) -> * mut Opaque {
99
+ let flags = layout_to_flags ( layout. align ( ) , new_size) ;
100
+ let ptr = ffi:: rallocx ( ptr as * mut c_void , new_size, flags) ;
101
+ ptr as * mut Opaque
107
102
}
108
103
109
104
#[ inline]
110
- unsafe fn realloc_excess ( & mut self ,
111
- ptr : * mut u8 ,
112
- layout : Layout ,
113
- new_layout : Layout ) -> Result < Excess , AllocErr > {
114
- ( & * self ) . realloc_excess ( ptr, layout, new_layout)
105
+ fn oom ( & self ) -> ! {
106
+ System . oom ( )
115
107
}
108
+ }
116
109
110
+ unsafe impl Alloc for Jemalloc {
117
111
#[ inline]
118
- unsafe fn grow_in_place ( & mut self ,
119
- ptr : * mut u8 ,
120
- layout : Layout ,
121
- new_layout : Layout ) -> Result < ( ) , CannotReallocInPlace > {
122
- ( & * self ) . grow_in_place ( ptr, layout, new_layout)
112
+ unsafe fn alloc ( & mut self , layout : Layout ) -> Result < NonNull < Opaque > , AllocErr > {
113
+ NonNull :: new ( GlobalAlloc :: alloc ( self , layout) ) . ok_or ( AllocErr )
123
114
}
124
115
125
116
#[ inline]
126
- unsafe fn shrink_in_place ( & mut self ,
127
- ptr : * mut u8 ,
128
- layout : Layout ,
129
- new_layout : Layout ) -> Result < ( ) , CannotReallocInPlace > {
130
- ( & * self ) . shrink_in_place ( ptr, layout, new_layout)
117
+ unsafe fn alloc_zeroed ( & mut self , layout : Layout ) -> Result < NonNull < Opaque > , AllocErr > {
118
+ NonNull :: new ( GlobalAlloc :: alloc_zeroed ( self , layout) ) . ok_or ( AllocErr )
131
119
}
132
- }
133
120
134
- unsafe impl < ' a > Alloc for & ' a Jemalloc {
135
121
#[ inline]
136
- unsafe fn alloc ( & mut self , layout : Layout ) -> Result < * mut u8 , AllocErr > {
137
- let flags = layout_to_flags ( & layout) ;
138
- let ptr = ffi:: mallocx ( layout. size ( ) , flags) ;
139
- if ptr. is_null ( ) {
140
- Err ( AllocErr :: Exhausted { request : layout } )
141
- } else {
142
- Ok ( ptr as * mut u8 )
143
- }
122
+ unsafe fn dealloc ( & mut self , ptr : NonNull < Opaque > , layout : Layout ) {
123
+ GlobalAlloc :: dealloc ( self , ptr. as_ptr ( ) , layout)
144
124
}
145
125
146
126
#[ inline]
147
- unsafe fn alloc_zeroed ( & mut self , layout : Layout )
148
- -> Result < * mut u8 , AllocErr >
149
- {
150
- let ptr = if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
151
- ffi:: calloc ( 1 , layout. size ( ) )
152
- } else {
153
- let flags = layout_to_flags ( & layout) | ffi:: MALLOCX_ZERO ;
154
- ffi:: mallocx ( layout. size ( ) , flags)
155
- } ;
156
- if ptr. is_null ( ) {
157
- Err ( AllocErr :: Exhausted { request : layout } )
158
- } else {
159
- Ok ( ptr as * mut u8 )
160
- }
127
+ unsafe fn realloc ( & mut self ,
128
+ ptr : NonNull < Opaque > ,
129
+ layout : Layout ,
130
+ new_size : usize ) -> Result < NonNull < Opaque > , AllocErr > {
131
+ NonNull :: new ( GlobalAlloc :: realloc ( self , ptr. as_ptr ( ) , layout, new_size) ) . ok_or ( AllocErr )
161
132
}
162
133
163
134
#[ inline]
164
135
unsafe fn alloc_excess ( & mut self , layout : Layout ) -> Result < Excess , AllocErr > {
165
- let flags = layout_to_flags ( & layout) ;
136
+ let flags = layout_to_flags ( layout. align ( ) , layout . size ( ) ) ;
166
137
let ptr = ffi:: mallocx ( layout. size ( ) , flags) ;
167
- if ptr. is_null ( ) {
168
- Err ( AllocErr :: Exhausted { request : layout } )
169
- } else {
138
+ if let Some ( nonnull) = NonNull :: new ( ptr as * mut Opaque ) {
170
139
let excess = ffi:: nallocx ( layout. size ( ) , flags) ;
171
- Ok ( Excess ( ptr as * mut u8 , excess) )
172
- }
173
- }
174
-
175
- #[ inline]
176
- unsafe fn dealloc ( & mut self , ptr : * mut u8 , layout : Layout ) {
177
- let flags = layout_to_flags ( & layout) ;
178
- ffi:: sdallocx ( ptr as * mut c_void , layout. size ( ) , flags)
179
- }
180
-
181
- #[ inline]
182
- unsafe fn realloc ( & mut self ,
183
- ptr : * mut u8 ,
184
- old_layout : Layout ,
185
- new_layout : Layout ) -> Result < * mut u8 , AllocErr > {
186
- if old_layout. align ( ) != new_layout. align ( ) {
187
- return Err ( AllocErr :: Unsupported { details : "cannot change align" } )
188
- }
189
- let flags = layout_to_flags ( & new_layout) ;
190
- let ptr = ffi:: rallocx ( ptr as * mut c_void , new_layout. size ( ) , flags) ;
191
- if ptr. is_null ( ) {
192
- Err ( AllocErr :: Exhausted { request : new_layout } )
140
+ Ok ( Excess ( nonnull, excess) )
193
141
} else {
194
- Ok ( ptr as * mut u8 )
142
+ Err ( AllocErr )
195
143
}
196
144
}
197
145
198
146
#[ inline]
199
147
unsafe fn realloc_excess ( & mut self ,
200
- ptr : * mut u8 ,
201
- old_layout : Layout ,
202
- new_layout : Layout ) -> Result < Excess , AllocErr > {
203
- if old_layout. align ( ) != new_layout. align ( ) {
204
- return Err ( AllocErr :: Unsupported { details : "cannot change align" } )
205
- }
206
- let flags = layout_to_flags ( & new_layout) ;
207
- let ptr = ffi:: rallocx ( ptr as * mut c_void , new_layout. size ( ) , flags) ;
208
- if ptr. is_null ( ) {
209
- Err ( AllocErr :: Exhausted { request : new_layout } )
148
+ ptr : NonNull < Opaque > ,
149
+ layout : Layout ,
150
+ new_size : usize ) -> Result < Excess , AllocErr > {
151
+ let flags = layout_to_flags ( layout. align ( ) , new_size) ;
152
+ let ptr = ffi:: rallocx ( ptr. cast ( ) . as_ptr ( ) , new_size, flags) ;
153
+ if let Some ( nonnull) = NonNull :: new ( ptr as * mut Opaque ) {
154
+ let excess = ffi:: nallocx ( new_size, flags) ;
155
+ Ok ( Excess ( nonnull, excess) )
210
156
} else {
211
- let excess = ffi:: nallocx ( new_layout. size ( ) , flags) ;
212
- Ok ( Excess ( ptr as * mut u8 , excess) )
157
+ Err ( AllocErr )
213
158
}
214
159
}
215
160
216
- fn oom ( & mut self , err : AllocErr ) -> ! {
217
- System . oom ( err)
161
+ #[ inline]
162
+ fn oom ( & mut self ) -> ! {
163
+ System . oom ( )
218
164
}
219
165
220
166
#[ inline]
221
167
fn usable_size ( & self , layout : & Layout ) -> ( usize , usize ) {
222
- let flags = layout_to_flags ( & layout) ;
168
+ let flags = layout_to_flags ( layout. align ( ) , layout . size ( ) ) ;
223
169
unsafe {
224
170
let max = ffi:: nallocx ( layout. size ( ) , flags) ;
225
171
( layout. size ( ) , max)
@@ -228,23 +174,20 @@ unsafe impl<'a> Alloc for &'a Jemalloc {
228
174
229
175
#[ inline]
230
176
unsafe fn grow_in_place ( & mut self ,
231
- ptr : * mut u8 ,
232
- old_layout : Layout ,
233
- new_layout : Layout ) -> Result < ( ) , CannotReallocInPlace > {
234
- self . shrink_in_place ( ptr, old_layout , new_layout )
177
+ ptr : NonNull < Opaque > ,
178
+ layout : Layout ,
179
+ new_size : usize ) -> Result < ( ) , CannotReallocInPlace > {
180
+ self . shrink_in_place ( ptr, layout , new_size )
235
181
}
236
182
237
183
#[ inline]
238
184
unsafe fn shrink_in_place ( & mut self ,
239
- ptr : * mut u8 ,
240
- old_layout : Layout ,
241
- new_layout : Layout ) -> Result < ( ) , CannotReallocInPlace > {
242
- if old_layout. align ( ) != new_layout. align ( ) {
243
- return Err ( CannotReallocInPlace )
244
- }
245
- let flags = layout_to_flags ( & new_layout) ;
246
- let size = ffi:: xallocx ( ptr as * mut c_void , new_layout. size ( ) , 0 , flags) ;
247
- if size >= new_layout. size ( ) {
185
+ ptr : NonNull < Opaque > ,
186
+ layout : Layout ,
187
+ new_size : usize ) -> Result < ( ) , CannotReallocInPlace > {
188
+ let flags = layout_to_flags ( layout. align ( ) , new_size) ;
189
+ let size = ffi:: xallocx ( ptr. cast ( ) . as_ptr ( ) , new_size, 0 , flags) ;
190
+ if size >= new_size {
248
191
Err ( CannotReallocInPlace )
249
192
} else {
250
193
Ok ( ( ) )
0 commit comments