@@ -299,11 +299,13 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
299
299
unsafe impl < T : Send > Send for TypedArena < T > { }
300
300
301
301
pub struct DroplessArena {
302
- /// A pointer to the next object to be allocated .
303
- ptr : Cell < * mut u8 > ,
302
+ /// A pointer to the start of the free space .
303
+ start : Cell < * mut u8 > ,
304
304
305
- /// A pointer to the end of the allocated area. When this pointer is
306
- /// reached, a new chunk is allocated.
305
+ /// A pointer to the end of free space.
306
+ ///
307
+ /// The allocation proceeds from the end of the chunk towards the start.
308
+ /// When this pointer crosses the start pointer, a new chunk is allocated.
307
309
end : Cell < * mut u8 > ,
308
310
309
311
/// A vector of arena chunks.
@@ -316,7 +318,7 @@ impl Default for DroplessArena {
316
318
#[ inline]
317
319
fn default ( ) -> DroplessArena {
318
320
DroplessArena {
319
- ptr : Cell :: new ( ptr:: null_mut ( ) ) ,
321
+ start : Cell :: new ( ptr:: null_mut ( ) ) ,
320
322
end : Cell :: new ( ptr:: null_mut ( ) ) ,
321
323
chunks : Default :: default ( ) ,
322
324
}
@@ -348,7 +350,7 @@ impl DroplessArena {
348
350
new_cap = cmp:: max ( additional, new_cap) ;
349
351
350
352
let mut chunk = TypedArenaChunk :: < u8 > :: new ( new_cap) ;
351
- self . ptr . set ( chunk. start ( ) ) ;
353
+ self . start . set ( chunk. start ( ) ) ;
352
354
self . end . set ( chunk. end ( ) ) ;
353
355
chunks. push ( chunk) ;
354
356
}
@@ -359,24 +361,17 @@ impl DroplessArena {
359
361
/// request.
360
362
#[ inline]
361
363
fn alloc_raw_without_grow ( & self , layout : Layout ) -> Option < * mut u8 > {
362
- let ptr = self . ptr . get ( ) as usize ;
364
+ let start = self . start . get ( ) as usize ;
363
365
let end = self . end . get ( ) as usize ;
366
+
364
367
let align = layout. align ( ) ;
365
368
let bytes = layout. size ( ) ;
366
- // The allocation request fits into the current chunk iff:
367
- //
368
- // let aligned = align_to(ptr, align);
369
- // ptr <= aligned && aligned + bytes <= end
370
- //
371
- // Except that we work with fixed width integers and need to be careful
372
- // about potential overflow in the calcuation. If the overflow does
373
- // happen, then we definitely don't have enough free and need to grow
374
- // the arena.
375
- let aligned = ptr. checked_add ( align - 1 ) ? & !( align - 1 ) ;
376
- let new_ptr = aligned. checked_add ( bytes) ?;
377
- if new_ptr <= end {
378
- self . ptr . set ( new_ptr as * mut u8 ) ;
379
- Some ( aligned as * mut u8 )
369
+
370
+ let new_end = end. checked_sub ( bytes) ? & !( align - 1 ) ;
371
+ if start <= new_end {
372
+ let new_end = new_end as * mut u8 ;
373
+ self . end . set ( new_end) ;
374
+ Some ( new_end)
380
375
} else {
381
376
None
382
377
}
0 commit comments