@@ -200,28 +200,36 @@ unsafe impl Alloc for Jemalloc {
200
200
layout : Layout ,
201
201
new_size : usize ,
202
202
) -> Result < ( ) , CannotReallocInPlace > {
203
- if new_size == layout. size ( ) { return Ok ( ( ) ) ; }
203
+ if new_size == layout. size ( ) {
204
+ return Ok ( ( ) ) ;
205
+ }
204
206
let flags = layout_to_flags ( layout. align ( ) , new_size) ;
205
207
let usable_size = ffi:: xallocx ( ptr. cast ( ) . as_ptr ( ) , new_size, 0 , flags) ;
208
+
206
209
if usable_size < layout. size ( ) {
207
- // `shrink_in_place` succeeds if the usable size of the shrunk
208
- // allocation is smaller than that of the current allocation (and
209
- // therefore, than the originally requested size). This means that:
210
- //
211
- // * the size-class of the allocation was changed to the size-class
212
- // of `new_size`, therefore the allocation can be deallocated with
213
- // `new_size`
214
- //
215
- // * if `new_size` lies in the same size class as `layout.size()`,
216
- // and `new_size != layout.size()` then `shrink_in_place` will error
217
- // even though technically the allocation can be deallocated
218
- // properly with `new_size` - the problem is that `xallocx` will
219
- // return `layout.size()` if shrinking failed, and we cannot detect
220
- // whether that means that shrinking failed or that `new_size` is
221
- // part of the same size-class efficiently.
222
- //
210
+ // If `usable_size` is smaller than the original size, the
211
+ // size-class of the allocation was shrunk to the size-class of
212
+ // `new_size`, and it is safe to deallocate the allocation with
213
+ // `new_size`:
214
+ Ok ( ( ) )
215
+ } else if usable_size == ffi:: nallocx ( new_size, flags) {
216
+ // If the allocation was not shrunk and the size class of `new_size`
217
+ // is the same as the size-class of `layout.size()`, then the
218
+ // allocation can be properly deallocated using `new_size` (and also
219
+ // using `layout.size()` because the allocation did not change)
220
+
221
+ // note: when the allocation is not shrunk, `xallocx` returns the
222
+ // usable size of the original allocation, which in this case matches
223
+ // that of the requested allocation:
224
+ debug_assert_eq ! (
225
+ ffi:: nallocx( new_size, flags) ,
226
+ ffi:: nallocx( layout. size( ) , flags)
227
+ ) ;
223
228
Ok ( ( ) )
224
229
} else {
230
+ // If the allocation was not shrunk, but the size-class of
231
+ // `new_size` is not the same as that of the original allocation,
232
+ // then shrinking the allocation failed:
225
233
Err ( CannotReallocInPlace )
226
234
}
227
235
}
0 commit comments