@@ -31,6 +31,7 @@ use std::cast::{transmute, transmute_mut, transmute_mut_region};
31
31
use std:: cast;
32
32
use std:: cell:: { Cell , RefCell } ;
33
33
use std:: mem;
34
+ use std:: ptr:: read;
34
35
use std:: cmp;
35
36
use std:: num;
36
37
use std:: kinds:: marker;
@@ -345,37 +346,32 @@ pub struct TypedArena<T> {
345
346
/// reached, a new chunk is allocated.
346
347
priv end: * T ,
347
348
348
- /// The type descriptor of the objects in the arena. This should not be
349
- /// necessary, but is until generic destructors are supported.
350
- priv tydesc : * TyDesc ,
351
-
352
349
/// A pointer to the first arena segment.
353
- priv first : Option < ~TypedArenaChunk > ,
350
+ priv first : Option < ~TypedArenaChunk < T > > ,
354
351
}
355
352
356
- struct TypedArenaChunk {
353
+ struct TypedArenaChunk < T > {
357
354
/// Pointer to the next arena segment.
358
- next : Option < ~TypedArenaChunk > ,
355
+ next : Option < ~TypedArenaChunk < T > > ,
359
356
360
357
/// The number of elements that this chunk can hold.
361
358
capacity : uint ,
362
359
363
360
// Objects follow here, suitably aligned.
364
361
}
365
362
366
- impl TypedArenaChunk {
363
+ impl < T > TypedArenaChunk < T > {
367
364
#[ inline]
368
- fn new < T > ( next : Option < ~TypedArenaChunk > , capacity : uint )
369
- -> ~TypedArenaChunk {
370
- let mut size = mem:: size_of :: < TypedArenaChunk > ( ) ;
365
+ fn new ( next : Option < ~TypedArenaChunk < T > > , capacity : uint ) -> ~TypedArenaChunk < T > {
366
+ let mut size = mem:: size_of :: < TypedArenaChunk < T > > ( ) ;
371
367
size = round_up ( size, mem:: min_align_of :: < T > ( ) ) ;
372
368
let elem_size = mem:: size_of :: < T > ( ) ;
373
369
let elems_size = elem_size. checked_mul ( & capacity) . unwrap ( ) ;
374
370
size = size. checked_add ( & elems_size) . unwrap ( ) ;
375
371
376
372
let mut chunk = unsafe {
377
373
let chunk = global_heap:: exchange_malloc ( size) ;
378
- let mut chunk: ~TypedArenaChunk = cast:: transmute ( chunk) ;
374
+ let mut chunk: ~TypedArenaChunk < T > = cast:: transmute ( chunk) ;
379
375
mem:: move_val_init ( & mut chunk. next , next) ;
380
376
chunk
381
377
} ;
@@ -387,16 +383,13 @@ impl TypedArenaChunk {
387
383
/// Destroys this arena chunk. If the type descriptor is supplied, the
388
384
/// drop glue is called; otherwise, drop glue is not called.
389
385
#[ inline]
390
- unsafe fn destroy ( & mut self , len : uint , opt_tydesc : Option < * TyDesc > ) {
386
+ unsafe fn destroy ( & mut self , len : uint ) {
391
387
// Destroy all the allocated objects.
392
- match opt_tydesc {
393
- None => { }
394
- Some ( tydesc) => {
395
- let mut start = self . start ( tydesc) ;
396
- for _ in range ( 0 , len) {
397
- ( ( * tydesc) . drop_glue ) ( start as * i8 ) ;
398
- start = start. offset ( ( * tydesc) . size as int )
399
- }
388
+ if intrinsics:: needs_drop :: < T > ( ) {
389
+ let mut start = self . start ( ) ;
390
+ for _ in range ( 0 , len) {
391
+ read ( start as * T ) ; // run the destructor on the pointer
392
+ start = start. offset ( mem:: size_of :: < T > ( ) as int )
400
393
}
401
394
}
402
395
@@ -406,26 +399,26 @@ impl TypedArenaChunk {
406
399
None => { }
407
400
Some ( mut next) => {
408
401
// We assume that the next chunk is completely filled.
409
- next. destroy ( next. capacity , opt_tydesc )
402
+ next. destroy ( next. capacity )
410
403
}
411
404
}
412
405
}
413
406
414
407
// Returns a pointer to the first allocated object.
415
408
#[ inline]
416
- fn start ( & self , tydesc : * TyDesc ) -> * u8 {
417
- let this: * TypedArenaChunk = self ;
409
+ fn start ( & self ) -> * u8 {
410
+ let this: * TypedArenaChunk < T > = self ;
418
411
unsafe {
419
- cast:: transmute ( round_up ( this. offset ( 1 ) as uint , ( * tydesc ) . align ) )
412
+ cast:: transmute ( round_up ( this. offset ( 1 ) as uint , mem :: min_align_of :: < T > ( ) ) )
420
413
}
421
414
}
422
415
423
416
// Returns a pointer to the end of the allocated space.
424
417
#[ inline]
425
- fn end ( & self , tydesc : * TyDesc ) -> * u8 {
418
+ fn end ( & self ) -> * u8 {
426
419
unsafe {
427
- let size = ( * tydesc ) . size . checked_mul ( & self . capacity ) . unwrap ( ) ;
428
- self . start ( tydesc ) . offset ( size as int )
420
+ let size = mem :: size_of :: < T > ( ) . checked_mul ( & self . capacity ) . unwrap ( ) ;
421
+ self . start ( ) . offset ( size as int )
429
422
}
430
423
}
431
424
}
@@ -441,14 +434,10 @@ impl<T> TypedArena<T> {
441
434
/// objects.
442
435
#[ inline]
443
436
pub fn with_capacity ( capacity : uint ) -> TypedArena < T > {
444
- let chunk = TypedArenaChunk :: new :: < T > ( None , capacity) ;
445
- let tydesc = unsafe {
446
- intrinsics:: get_tydesc :: < T > ( )
447
- } ;
437
+ let chunk = TypedArenaChunk :: < T > :: new ( None , capacity) ;
448
438
TypedArena {
449
- ptr : chunk. start ( tydesc) as * T ,
450
- end : chunk. end ( tydesc) as * T ,
451
- tydesc : tydesc,
439
+ ptr : chunk. start ( ) as * T ,
440
+ end : chunk. end ( ) as * T ,
452
441
first : Some ( chunk) ,
453
442
}
454
443
}
@@ -475,9 +464,9 @@ impl<T> TypedArena<T> {
475
464
fn grow ( & mut self ) {
476
465
let chunk = self . first . take_unwrap ( ) ;
477
466
let new_capacity = chunk. capacity . checked_mul ( & 2 ) . unwrap ( ) ;
478
- let chunk = TypedArenaChunk :: new :: < T > ( Some ( chunk) , new_capacity) ;
479
- self . ptr = chunk. start ( self . tydesc ) as * T ;
480
- self . end = chunk. end ( self . tydesc ) as * T ;
467
+ let chunk = TypedArenaChunk :: < T > :: new ( Some ( chunk) , new_capacity) ;
468
+ self . ptr = chunk. start ( ) as * T ;
469
+ self . end = chunk. end ( ) as * T ;
481
470
self . first = Some ( chunk)
482
471
}
483
472
}
@@ -486,18 +475,13 @@ impl<T> TypedArena<T> {
486
475
impl < T > Drop for TypedArena < T > {
487
476
fn drop ( & mut self ) {
488
477
// Determine how much was filled.
489
- let start = self . first . get_ref ( ) . start ( self . tydesc ) as uint ;
478
+ let start = self . first . get_ref ( ) . start ( ) as uint ;
490
479
let end = self . ptr as uint ;
491
480
let diff = ( end - start) / mem:: size_of :: < T > ( ) ;
492
481
493
482
// Pass that to the `destroy` method.
494
483
unsafe {
495
- let opt_tydesc = if intrinsics:: needs_drop :: < T > ( ) {
496
- Some ( self . tydesc )
497
- } else {
498
- None
499
- } ;
500
- self . first . get_mut_ref ( ) . destroy ( diff, opt_tydesc)
484
+ self . first . get_mut_ref ( ) . destroy ( diff)
501
485
}
502
486
}
503
487
}
0 commit comments