4
4
5
5
use core:: intrinsics:: { self , min_align_of_val, size_of_val} ;
6
6
use core:: ptr:: { NonNull , Unique } ;
7
- use core:: usize;
7
+ use core:: { mem , usize} ;
8
8
9
9
#[ stable( feature = "alloc_module" , since = "1.28.0" ) ]
10
10
#[ doc( inline) ]
@@ -165,102 +165,96 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
165
165
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
166
166
unsafe impl AllocRef for Global {
167
167
#[ inline]
168
- fn alloc ( & mut self , layout : Layout , init : AllocInit ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
169
- let new_size = layout. size ( ) ;
170
- if new_size == 0 {
171
- Ok ( ( layout. dangling ( ) , 0 ) )
172
- } else {
173
- unsafe {
168
+ fn alloc ( & mut self , layout : Layout , init : AllocInit ) -> Result < MemoryBlock , AllocErr > {
169
+ unsafe {
170
+ if layout. size ( ) == 0 {
171
+ Ok ( MemoryBlock :: new ( layout. dangling ( ) , layout) )
172
+ } else {
174
173
let raw_ptr = match init {
175
174
AllocInit :: Uninitialized => alloc ( layout) ,
176
175
AllocInit :: Zeroed => alloc_zeroed ( layout) ,
177
176
} ;
178
177
let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocErr ) ?;
179
- Ok ( ( ptr, new_size ) )
178
+ Ok ( MemoryBlock :: new ( ptr, layout ) )
180
179
}
181
180
}
182
181
}
183
182
184
183
#[ inline]
185
- unsafe fn dealloc ( & mut self , ptr : NonNull < u8 > , layout : Layout ) {
186
- if layout . size ( ) != 0 {
187
- dealloc ( ptr. as_ptr ( ) , layout)
184
+ unsafe fn dealloc ( & mut self , memory : MemoryBlock ) {
185
+ if memory . size ( ) != 0 {
186
+ dealloc ( memory . ptr ( ) . as_ptr ( ) , memory . layout ( ) )
188
187
}
189
188
}
190
189
191
190
#[ inline]
192
191
unsafe fn grow (
193
192
& mut self ,
194
- ptr : NonNull < u8 > ,
195
- layout : Layout ,
193
+ memory : & mut MemoryBlock ,
196
194
new_size : usize ,
197
195
placement : ReallocPlacement ,
198
196
init : AllocInit ,
199
- ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
200
- let old_size = layout . size ( ) ;
197
+ ) -> Result < ( ) , AllocErr > {
198
+ let old_size = memory . size ( ) ;
201
199
debug_assert ! (
202
200
new_size >= old_size,
203
- "`new_size` must be greater than or equal to `layout .size()`"
201
+ "`new_size` must be greater than or equal to `memory .size()`"
204
202
) ;
205
203
206
204
if old_size == new_size {
207
- return Ok ( ( ptr , new_size ) ) ;
205
+ return Ok ( ( ) ) ;
208
206
}
209
207
208
+ let new_layout = Layout :: from_size_align_unchecked ( new_size, memory. align ( ) ) ;
210
209
match placement {
210
+ ReallocPlacement :: InPlace => return Err ( AllocErr ) ,
211
+ ReallocPlacement :: MayMove if memory. size ( ) == 0 => {
212
+ * memory = self . alloc ( new_layout, init) ?
213
+ }
211
214
ReallocPlacement :: MayMove => {
212
- if old_size == 0 {
213
- self . alloc ( Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) , init)
214
- } else {
215
- // `realloc` probably checks for `new_size > old_size` or something similar.
216
- // `new_size` must be greater than or equal to `old_size` due to the safety constraint,
217
- // and `new_size` == `old_size` was caught before
218
- intrinsics:: assume ( new_size > old_size) ;
219
- let ptr =
220
- NonNull :: new ( realloc ( ptr. as_ptr ( ) , layout, new_size) ) . ok_or ( AllocErr ) ?;
221
- let new_layout = Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ;
222
- init. initialize_offset ( ptr, new_layout, old_size) ;
223
- Ok ( ( ptr, new_size) )
224
- }
215
+ // `realloc` probably checks for `new_size > old_size` or something similar.
216
+ intrinsics:: assume ( new_size > old_size) ;
217
+ let ptr = realloc ( memory. ptr ( ) . as_ptr ( ) , memory. layout ( ) , new_size) ;
218
+ * memory = MemoryBlock :: new ( NonNull :: new ( ptr) . ok_or ( AllocErr ) ?, new_layout) ;
219
+ memory. init_offset ( init, old_size) ;
225
220
}
226
- ReallocPlacement :: InPlace => Err ( AllocErr ) ,
227
221
}
222
+ Ok ( ( ) )
228
223
}
229
224
230
225
#[ inline]
231
226
unsafe fn shrink (
232
227
& mut self ,
233
- ptr : NonNull < u8 > ,
234
- layout : Layout ,
228
+ memory : & mut MemoryBlock ,
235
229
new_size : usize ,
236
230
placement : ReallocPlacement ,
237
- ) -> Result < ( NonNull < u8 > , usize ) , AllocErr > {
238
- let old_size = layout . size ( ) ;
231
+ ) -> Result < ( ) , AllocErr > {
232
+ let old_size = memory . size ( ) ;
239
233
debug_assert ! (
240
234
new_size <= old_size,
241
- "`new_size` must be smaller than or equal to `layout .size()`"
235
+ "`new_size` must be smaller than or equal to `memory .size()`"
242
236
) ;
243
237
244
238
if old_size == new_size {
245
- return Ok ( ( ptr , new_size ) ) ;
239
+ return Ok ( ( ) ) ;
246
240
}
247
241
242
+ let new_layout = Layout :: from_size_align_unchecked ( new_size, memory. align ( ) ) ;
248
243
match placement {
244
+ ReallocPlacement :: InPlace => return Err ( AllocErr ) ,
245
+ ReallocPlacement :: MayMove if new_size == 0 => {
246
+ let new_memory = MemoryBlock :: new ( new_layout. dangling ( ) , new_layout) ;
247
+ let old_memory = mem:: replace ( memory, new_memory) ;
248
+ self . dealloc ( old_memory)
249
+ }
249
250
ReallocPlacement :: MayMove => {
250
- let ptr = if new_size == 0 {
251
- self . dealloc ( ptr, layout) ;
252
- layout. dangling ( )
253
- } else {
254
- // `realloc` probably checks for `new_size > old_size` or something similar.
255
- // `new_size` must be smaller than or equal to `old_size` due to the safety constraint,
256
- // and `new_size` == `old_size` was caught before
257
- intrinsics:: assume ( new_size < old_size) ;
258
- NonNull :: new ( realloc ( ptr. as_ptr ( ) , layout, new_size) ) . ok_or ( AllocErr ) ?
259
- } ;
260
- Ok ( ( ptr, new_size) )
251
+ // `realloc` probably checks for `new_size < old_size` or something similar.
252
+ intrinsics:: assume ( new_size < old_size) ;
253
+ let ptr = realloc ( memory. ptr ( ) . as_ptr ( ) , memory. layout ( ) , new_size) ;
254
+ * memory = MemoryBlock :: new ( NonNull :: new ( ptr) . ok_or ( AllocErr ) ?, new_layout) ;
261
255
}
262
- ReallocPlacement :: InPlace => Err ( AllocErr ) ,
263
256
}
257
+ Ok ( ( ) )
264
258
}
265
259
}
266
260
@@ -272,7 +266,7 @@ unsafe impl AllocRef for Global {
272
266
unsafe fn exchange_malloc ( size : usize , align : usize ) -> * mut u8 {
273
267
let layout = Layout :: from_size_align_unchecked ( size, align) ;
274
268
match Global . alloc ( layout, AllocInit :: Uninitialized ) {
275
- Ok ( ( ptr , _ ) ) => ptr. as_ptr ( ) ,
269
+ Ok ( memory ) => memory . ptr ( ) . as_ptr ( ) ,
276
270
Err ( _) => handle_alloc_error ( layout) ,
277
271
}
278
272
}
@@ -288,7 +282,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
288
282
let size = size_of_val ( ptr. as_ref ( ) ) ;
289
283
let align = min_align_of_val ( ptr. as_ref ( ) ) ;
290
284
let layout = Layout :: from_size_align_unchecked ( size, align) ;
291
- Global . dealloc ( ptr. cast ( ) . into ( ) , layout)
285
+ Global . dealloc ( MemoryBlock :: new ( ptr. cast ( ) . into ( ) , layout) )
292
286
}
293
287
294
288
/// Abort on memory allocation error or failure.
0 commit comments