@@ -165,34 +165,33 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
165
165
unsafe impl AllocRef for Global {
166
166
#[ inline]
167
167
fn alloc ( & mut self , layout : Layout ) -> Result < MemoryBlock , AllocErr > {
168
- unsafe {
169
- let size = layout. size ( ) ;
170
- if size == 0 {
171
- Ok ( MemoryBlock { ptr : layout. dangling ( ) , size : 0 } )
172
- } else {
173
- let raw_ptr = alloc ( layout) ;
174
- let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocErr ) ?;
175
- Ok ( MemoryBlock { ptr, size } )
176
- }
177
- }
168
+ let size = layout. size ( ) ;
169
+ let ptr = if size == 0 {
170
+ layout. dangling ( )
171
+ } else {
172
+ // SAFETY: `layout` is non-zero in size,
173
+ unsafe { NonNull :: new ( alloc ( layout) ) . ok_or ( AllocErr ) ? }
174
+ } ;
175
+ Ok ( MemoryBlock { ptr, size } )
178
176
}
179
177
178
+ #[ inline]
180
179
fn alloc_zeroed ( & mut self , layout : Layout ) -> Result < MemoryBlock , AllocErr > {
181
- unsafe {
182
- let size = layout. size ( ) ;
183
- if size == 0 {
184
- Ok ( MemoryBlock { ptr : layout. dangling ( ) , size : 0 } )
185
- } else {
186
- let raw_ptr = alloc_zeroed ( layout) ;
187
- let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocErr ) ?;
188
- Ok ( MemoryBlock { ptr, size } )
189
- }
190
- }
180
+ let size = layout. size ( ) ;
181
+ let ptr = if size == 0 {
182
+ layout. dangling ( )
183
+ } else {
184
+ // SAFETY: `layout` is non-zero in size,
185
+ unsafe { NonNull :: new ( alloc_zeroed ( layout) ) . ok_or ( AllocErr ) ? }
186
+ } ;
187
+ Ok ( MemoryBlock { ptr, size } )
191
188
}
192
189
193
190
#[ inline]
194
191
unsafe fn dealloc ( & mut self , ptr : NonNull < u8 > , layout : Layout ) {
195
192
if layout. size ( ) != 0 {
193
+ // SAFETY: `layout` is non-zero in size,
194
+ // other conditions must be upheld by the caller
196
195
unsafe { dealloc ( ptr. as_ptr ( ) , layout) }
197
196
}
198
197
}
@@ -204,59 +203,55 @@ unsafe impl AllocRef for Global {
204
203
layout : Layout ,
205
204
new_size : usize ,
206
205
) -> Result < MemoryBlock , AllocErr > {
207
- let size = layout. size ( ) ;
208
206
debug_assert ! (
209
- new_size >= size,
210
- "`new_size` must be greater than or equal to `memory .size()`"
207
+ new_size >= layout . size( ) ,
208
+ "`new_size` must be greater than or equal to `layout .size()`"
211
209
) ;
212
210
213
- if size == new_size {
214
- return Ok ( MemoryBlock { ptr , size } ) ;
215
- }
216
-
217
- if layout . size ( ) == 0 {
218
- let new_layout = unsafe { Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) } ;
219
- self . alloc ( new_layout )
220
- } else {
221
- // `realloc` probably checks for `new_size > size` or something similar.
222
- let ptr = unsafe {
223
- intrinsics :: assume ( new_size > size ) ;
224
- realloc ( ptr. as_ptr ( ) , layout , new_size)
225
- } ;
226
- Ok ( MemoryBlock { ptr : NonNull :: new ( ptr ) . ok_or ( AllocErr ) ? , size : new_size } )
211
+ // SAFETY: ` new_size` must be non-zero, which is checked in the match expression.
212
+ // Other conditions must be upheld by the caller
213
+ unsafe {
214
+ match layout . size ( ) {
215
+ old_size if old_size == new_size => Ok ( MemoryBlock { ptr , size : new_size } ) ,
216
+ 0 => self . alloc ( Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ) ,
217
+ old_size => {
218
+ // `realloc` probably checks for `new_size > size` or something similar.
219
+ intrinsics :: assume ( new_size > old_size ) ;
220
+ let raw_ptr = realloc ( ptr . as_ptr ( ) , layout , new_size ) ;
221
+ let ptr = NonNull :: new ( raw_ptr ) . ok_or ( AllocErr ) ? ;
222
+ Ok ( MemoryBlock { ptr, size : new_size } )
223
+ }
224
+ }
227
225
}
228
226
}
229
227
228
+ #[ inline]
230
229
unsafe fn grow_zeroed (
231
230
& mut self ,
232
231
ptr : NonNull < u8 > ,
233
232
layout : Layout ,
234
233
new_size : usize ,
235
234
) -> Result < MemoryBlock , AllocErr > {
236
- let size = layout. size ( ) ;
237
235
debug_assert ! (
238
- new_size >= size,
239
- "`new_size` must be greater than or equal to `memory .size()`"
236
+ new_size >= layout . size( ) ,
237
+ "`new_size` must be greater than or equal to `layout .size()`"
240
238
) ;
241
239
242
- if size == new_size {
243
- return Ok ( MemoryBlock { ptr, size } ) ;
244
- }
245
-
246
- if layout. size ( ) == 0 {
247
- let new_layout = unsafe { Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) } ;
248
- self . alloc ( new_layout)
249
- } else {
250
- // `realloc` probably checks for `new_size > size` or something similar.
251
- let ptr = unsafe {
252
- intrinsics:: assume ( new_size > size) ;
253
- realloc ( ptr. as_ptr ( ) , layout, new_size)
254
- } ;
255
- let memory = MemoryBlock { ptr : NonNull :: new ( ptr) . ok_or ( AllocErr ) ?, size : new_size } ;
256
- unsafe {
257
- memory. ptr . as_ptr ( ) . add ( size) . write_bytes ( 0 , memory. size - size) ;
240
+ // SAFETY: `new_size` must be non-zero, which is checked in the match expression.
241
+ // Other conditions must be upheld by the caller
242
+ unsafe {
243
+ match layout. size ( ) {
244
+ old_size if old_size == new_size => Ok ( MemoryBlock { ptr, size : new_size } ) ,
245
+ 0 => self . alloc_zeroed ( Layout :: from_size_align_unchecked ( new_size, layout. align ( ) ) ) ,
246
+ old_size => {
247
+ // `realloc` probably checks for `new_size > size` or something similar.
248
+ intrinsics:: assume ( new_size > old_size) ;
249
+ let raw_ptr = realloc ( ptr. as_ptr ( ) , layout, new_size) ;
250
+ raw_ptr. add ( old_size) . write_bytes ( 0 , new_size - old_size) ;
251
+ let ptr = NonNull :: new ( raw_ptr) . ok_or ( AllocErr ) ?;
252
+ Ok ( MemoryBlock { ptr, size : new_size } )
253
+ }
258
254
}
259
- Ok ( memory)
260
255
}
261
256
}
262
257
@@ -267,29 +262,33 @@ unsafe impl AllocRef for Global {
267
262
layout : Layout ,
268
263
new_size : usize ,
269
264
) -> Result < MemoryBlock , AllocErr > {
270
- let size = layout. size ( ) ;
265
+ let old_size = layout. size ( ) ;
271
266
debug_assert ! (
272
- new_size <= size ,
273
- "`new_size` must be smaller than or equal to `memory .size()`"
267
+ new_size <= old_size ,
268
+ "`new_size` must be smaller than or equal to `layout .size()`"
274
269
) ;
275
270
276
- if size == new_size {
277
- return Ok ( MemoryBlock { ptr, size } ) ;
278
- }
279
-
280
- if new_size == 0 {
271
+ let ptr = if new_size == old_size {
272
+ ptr
273
+ } else if new_size == 0 {
274
+ // SAFETY: `layout` is non-zero in size as `old_size` != `new_size`
275
+ // Other conditions must be upheld by the caller
281
276
unsafe {
282
277
self . dealloc ( ptr, layout) ;
283
278
}
284
- Ok ( MemoryBlock { ptr : layout. dangling ( ) , size : 0 } )
279
+ layout. dangling ( )
285
280
} else {
286
- // `realloc` probably checks for `new_size < size` or something similar.
287
- let ptr = unsafe {
288
- intrinsics:: assume ( new_size < size) ;
281
+ // SAFETY: new_size is not zero,
282
+ // Other conditions must be upheld by the caller
283
+ let raw_ptr = unsafe {
284
+ // `realloc` probably checks for `new_size < old_size` or something similar.
285
+ intrinsics:: assume ( new_size < old_size) ;
289
286
realloc ( ptr. as_ptr ( ) , layout, new_size)
290
287
} ;
291
- Ok ( MemoryBlock { ptr : NonNull :: new ( ptr) . ok_or ( AllocErr ) ?, size : new_size } )
292
- }
288
+ NonNull :: new ( raw_ptr) . ok_or ( AllocErr ) ?
289
+ } ;
290
+
291
+ Ok ( MemoryBlock { ptr, size : new_size } )
293
292
}
294
293
}
295
294
0 commit comments