@@ -165,34 +165,33 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
165165unsafe impl AllocRef for Global {
166166 #[ inline]
167167 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 } )
178176 }
179177
178+ #[ inline]
180179 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 } )
191188 }
192189
193190 #[ inline]
194191 unsafe fn dealloc ( & mut self , ptr : NonNull < u8 > , layout : Layout ) {
195192 if layout. size ( ) != 0 {
193+ // SAFETY: `layout` is non-zero in size,
194+ // other conditions must be upheld by the caller
196195 unsafe { dealloc ( ptr. as_ptr ( ) , layout) }
197196 }
198197 }
@@ -204,59 +203,55 @@ unsafe impl AllocRef for Global {
204203 layout : Layout ,
205204 new_size : usize ,
206205 ) -> Result < MemoryBlock , AllocErr > {
207- let size = layout. size ( ) ;
208206 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()`"
211209 ) ;
212210
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+ }
227225 }
228226 }
229227
228+ #[ inline]
230229 unsafe fn grow_zeroed (
231230 & mut self ,
232231 ptr : NonNull < u8 > ,
233232 layout : Layout ,
234233 new_size : usize ,
235234 ) -> Result < MemoryBlock , AllocErr > {
236- let size = layout. size ( ) ;
237235 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()`"
240238 ) ;
241239
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+ }
258254 }
259- Ok ( memory)
260255 }
261256 }
262257
@@ -267,29 +262,33 @@ unsafe impl AllocRef for Global {
267262 layout : Layout ,
268263 new_size : usize ,
269264 ) -> Result < MemoryBlock , AllocErr > {
270- let size = layout. size ( ) ;
265+ let old_size = layout. size ( ) ;
271266 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()`"
274269 ) ;
275270
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
281276 unsafe {
282277 self . dealloc ( ptr, layout) ;
283278 }
284- Ok ( MemoryBlock { ptr : layout. dangling ( ) , size : 0 } )
279+ layout. dangling ( )
285280 } 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) ;
289286 realloc ( ptr. as_ptr ( ) , layout, new_size)
290287 } ;
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 } )
293292 }
294293}
295294
0 commit comments