19
19
#![ feature( rustc_attrs) ]
20
20
#![ cfg_attr( test, feature( test) ) ]
21
21
22
- use rustc_data_structures:: sync;
23
22
use smallvec:: SmallVec ;
24
23
25
24
use std:: alloc:: Layout ;
@@ -517,130 +516,12 @@ impl DroplessArena {
517
516
}
518
517
}
519
518
520
- /// Calls the destructor for an object when dropped.
521
- struct DropType {
522
- drop_fn : unsafe fn ( * mut u8 ) ,
523
- obj : * mut u8 ,
524
- }
525
-
526
- // SAFETY: we require `T: Send` before type-erasing into `DropType`.
527
- #[ cfg( parallel_compiler) ]
528
- unsafe impl sync:: Send for DropType { }
529
-
530
- impl DropType {
531
- #[ inline]
532
- unsafe fn new < T : sync:: Send > ( obj : * mut T ) -> Self {
533
- unsafe fn drop_for_type < T > ( to_drop : * mut u8 ) {
534
- std:: ptr:: drop_in_place ( to_drop as * mut T )
535
- }
536
-
537
- DropType { drop_fn : drop_for_type :: < T > , obj : obj as * mut u8 }
538
- }
539
- }
540
-
541
- impl Drop for DropType {
542
- fn drop ( & mut self ) {
543
- unsafe { ( self . drop_fn ) ( self . obj ) }
544
- }
545
- }
546
-
547
- /// An arena which can be used to allocate any type.
548
- ///
549
- /// # Safety
550
- ///
551
- /// Allocating in this arena is unsafe since the type system
552
- /// doesn't know which types it contains. In order to
553
- /// allocate safely, you must store a `PhantomData<T>`
554
- /// alongside this arena for each type `T` you allocate.
555
- #[ derive( Default ) ]
556
- pub struct DropArena {
557
- /// A list of destructors to run when the arena drops.
558
- /// Ordered so `destructors` gets dropped before the arena
559
- /// since its destructor can reference memory in the arena.
560
- destructors : RefCell < Vec < DropType > > ,
561
- arena : DroplessArena ,
562
- }
563
-
564
- impl DropArena {
565
- #[ inline]
566
- pub unsafe fn alloc < T > ( & self , object : T ) -> & mut T
567
- where
568
- T : sync:: Send ,
569
- {
570
- let mem = self . arena . alloc_raw ( Layout :: new :: < T > ( ) ) as * mut T ;
571
- // Write into uninitialized memory.
572
- ptr:: write ( mem, object) ;
573
- let result = & mut * mem;
574
- // Record the destructor after doing the allocation as that may panic
575
- // and would cause `object`'s destructor to run twice if it was recorded before.
576
- self . destructors . borrow_mut ( ) . push ( DropType :: new ( result) ) ;
577
- result
578
- }
579
-
580
- #[ inline]
581
- pub unsafe fn alloc_from_iter < T , I > ( & self , iter : I ) -> & mut [ T ]
582
- where
583
- T : sync:: Send ,
584
- I : IntoIterator < Item = T > ,
585
- {
586
- let mut vec: SmallVec < [ _ ; 8 ] > = iter. into_iter ( ) . collect ( ) ;
587
- if vec. is_empty ( ) {
588
- return & mut [ ] ;
589
- }
590
- let len = vec. len ( ) ;
591
-
592
- let start_ptr = self . arena . alloc_raw ( Layout :: array :: < T > ( len) . unwrap ( ) ) as * mut T ;
593
-
594
- let mut destructors = self . destructors . borrow_mut ( ) ;
595
- // Reserve space for the destructors so we can't panic while adding them.
596
- destructors. reserve ( len) ;
597
-
598
- // Move the content to the arena by copying it and then forgetting
599
- // the content of the SmallVec.
600
- vec. as_ptr ( ) . copy_to_nonoverlapping ( start_ptr, len) ;
601
- mem:: forget ( vec. drain ( ..) ) ;
602
-
603
- // Record the destructors after doing the allocation as that may panic
604
- // and would cause `object`'s destructor to run twice if it was recorded before.
605
- for i in 0 ..len {
606
- destructors. push ( DropType :: new ( start_ptr. add ( i) ) ) ;
607
- }
608
-
609
- slice:: from_raw_parts_mut ( start_ptr, len)
610
- }
611
- }
612
-
613
- pub macro arena_for_type {
614
- ( [ ] [ $ty: ty] ) => {
615
- $crate:: TypedArena <$ty>
616
- } ,
617
- ( [ few $( , $attrs: ident) * ] [ $ty: ty] ) => {
618
- :: std:: marker:: PhantomData <$ty>
619
- } ,
620
- ( [ $ignore: ident $( , $attrs: ident) * ] $args: tt) => {
621
- $crate:: arena_for_type!( [ $( $attrs) , * ] $args)
622
- } ,
623
- }
624
-
625
- pub macro which_arena_for_type {
626
- ( [ ] [ $arena: expr] ) => {
627
- :: std:: option:: Option :: Some ( $arena)
628
- } ,
629
- ( [ few $( , $attrs: ident) * ] [ $arena: expr] ) => {
630
- :: std:: option:: Option :: None
631
- } ,
632
- ( [ $ignore: ident$( , $attrs: ident) * ] $args: tt) => {
633
- $crate:: which_arena_for_type!( [ $( $attrs) , * ] $args)
634
- } ,
635
- }
636
-
637
519
#[ rustc_macro_transparency = "semitransparent" ]
638
520
pub macro declare_arena ( [ $( $a: tt $name: ident: $ty: ty, ) * ] , $tcx: lifetime) {
639
521
#[ derive( Default ) ]
640
522
pub struct Arena < $tcx> {
641
523
pub dropless : $crate:: DroplessArena ,
642
- drop : $crate:: DropArena ,
643
- $( $name: $crate:: arena_for_type!( $a[ $ty] ) , ) *
524
+ $( $name: $crate:: TypedArena <$ty>, ) *
644
525
}
645
526
646
527
pub trait ArenaAllocatable < ' tcx , T = Self > : Sized {
@@ -670,13 +551,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
670
551
#[ inline]
671
552
fn allocate_on < ' a > ( self , arena : & ' a Arena < $tcx> ) -> & ' a mut Self {
672
553
if !:: std:: mem:: needs_drop :: < Self > ( ) {
673
- return arena. dropless . alloc ( self ) ;
674
- }
675
- match $crate:: which_arena_for_type!( $a[ & arena. $name] ) {
676
- :: std:: option:: Option :: < & $crate:: TypedArena < Self > > :: Some ( ty_arena) => {
677
- ty_arena. alloc ( self )
678
- }
679
- :: std:: option:: Option :: None => unsafe { arena. drop . alloc ( self ) } ,
554
+ arena. dropless . alloc ( self )
555
+ } else {
556
+ arena. $name. alloc ( self )
680
557
}
681
558
}
682
559
@@ -686,13 +563,9 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
686
563
iter : impl :: std:: iter:: IntoIterator < Item = Self > ,
687
564
) -> & ' a mut [ Self ] {
688
565
if !:: std:: mem:: needs_drop :: < Self > ( ) {
689
- return arena. dropless . alloc_from_iter ( iter) ;
690
- }
691
- match $crate:: which_arena_for_type!( $a[ & arena. $name] ) {
692
- :: std:: option:: Option :: < & $crate:: TypedArena < Self > > :: Some ( ty_arena) => {
693
- ty_arena. alloc_from_iter ( iter)
694
- }
695
- :: std:: option:: Option :: None => unsafe { arena. drop . alloc_from_iter ( iter) } ,
566
+ arena. dropless . alloc_from_iter ( iter)
567
+ } else {
568
+ arena. $name. alloc_from_iter ( iter)
696
569
}
697
570
}
698
571
}
0 commit comments