@@ -197,7 +197,7 @@ pub trait Plan: 'static + HasSpaces + Sync + Downcast {
197
197
198
198
/// Inform the plan about the end of a GC. It is guaranteed that there is no further work for this GC.
199
199
/// This is invoked once per GC by one worker thread. `tls` is the worker thread that executes this method.
200
- fn end_of_gc ( & mut self , _tls : VMWorkerThread ) { }
200
+ fn end_of_gc ( & mut self , _tls : VMWorkerThread ) ;
201
201
202
202
/// Notify the plan that an emergency collection will happen. The plan should try to free as much memory as possible.
203
203
/// The default implementation will force a full heap collection for generational plans.
@@ -511,6 +511,10 @@ impl<VM: VMBinding> BasePlan<VM> {
511
511
self . vm_space . release ( ) ;
512
512
}
513
513
514
+ pub fn end_of_gc ( & mut self , _tls : VMWorkerThread ) {
515
+ // Do nothing here. None of the spaces needs end_of_gc.
516
+ }
517
+
514
518
pub ( crate ) fn collection_required < P : Plan > ( & self , plan : & P , space_full : bool ) -> bool {
515
519
let stress_force_gc =
516
520
crate :: util:: heap:: gc_trigger:: GCTrigger :: < VM > :: should_do_stress_gc_inner (
@@ -542,6 +546,17 @@ impl<VM: VMBinding> BasePlan<VM> {
542
546
}
543
547
}
544
548
549
+ cfg_if:: cfg_if! {
550
+ // Use immortal or mark sweep as the non moving space if the features are enabled. Otherwise use Immix.
551
+ if #[ cfg( feature = "immortal_as_nonmoving" ) ] {
552
+ pub type NonMovingSpace <VM > = crate :: policy:: immortalspace:: ImmortalSpace <VM >;
553
+ } else if #[ cfg( feature = "marksweep_as_nonmoving" ) ] {
554
+ pub type NonMovingSpace <VM > = crate :: policy:: marksweepspace:: native_ms:: MarkSweepSpace <VM >;
555
+ } else {
556
+ pub type NonMovingSpace <VM > = crate :: policy:: immix:: ImmixSpace <VM >;
557
+ }
558
+ }
559
+
545
560
/**
546
561
CommonPlan is for representing state and features used by _many_ plans, but that are not fundamental to _all_ plans. Examples include the Large Object Space and an Immortal space. Features that are fundamental to _all_ plans must be included in BasePlan.
547
562
*/
@@ -551,9 +566,12 @@ pub struct CommonPlan<VM: VMBinding> {
551
566
pub immortal : ImmortalSpace < VM > ,
552
567
#[ space]
553
568
pub los : LargeObjectSpace < VM > ,
554
- // TODO: We should use a marksweep space for nonmoving.
555
569
#[ space]
556
- pub nonmoving : ImmortalSpace < VM > ,
570
+ #[ cfg_attr(
571
+ not( any( feature = "immortal_as_nonmoving" , feature = "marksweep_as_nonmoving" ) ) ,
572
+ post_scan
573
+ ) ] // Immix space needs post_scan
574
+ pub nonmoving : NonMovingSpace < VM > ,
557
575
#[ parent]
558
576
pub base : BasePlan < VM > ,
559
577
}
@@ -571,12 +589,7 @@ impl<VM: VMBinding> CommonPlan<VM> {
571
589
args. get_space_args ( "los" , true , false , VMRequest :: discontiguous ( ) ) ,
572
590
false ,
573
591
) ,
574
- nonmoving : ImmortalSpace :: new ( args. get_space_args (
575
- "nonmoving" ,
576
- true ,
577
- false ,
578
- VMRequest :: discontiguous ( ) ,
579
- ) ) ,
592
+ nonmoving : Self :: new_nonmoving_space ( & mut args) ,
580
593
base : BasePlan :: new ( args) ,
581
594
}
582
595
}
@@ -591,17 +604,22 @@ impl<VM: VMBinding> CommonPlan<VM> {
591
604
pub fn prepare ( & mut self , tls : VMWorkerThread , full_heap : bool ) {
592
605
self . immortal . prepare ( ) ;
593
606
self . los . prepare ( full_heap) ;
594
- self . nonmoving . prepare ( ) ;
607
+ self . prepare_nonmoving_space ( full_heap ) ;
595
608
self . base . prepare ( tls, full_heap)
596
609
}
597
610
598
611
pub fn release ( & mut self , tls : VMWorkerThread , full_heap : bool ) {
599
612
self . immortal . release ( ) ;
600
613
self . los . release ( full_heap) ;
601
- self . nonmoving . release ( ) ;
614
+ self . release_nonmoving_space ( full_heap ) ;
602
615
self . base . release ( tls, full_heap)
603
616
}
604
617
618
+ pub fn end_of_gc ( & mut self , tls : VMWorkerThread ) {
619
+ self . end_of_gc_nonmoving_space ( ) ;
620
+ self . base . end_of_gc ( tls) ;
621
+ }
622
+
605
623
pub fn get_immortal ( & self ) -> & ImmortalSpace < VM > {
606
624
& self . immortal
607
625
}
@@ -610,9 +628,65 @@ impl<VM: VMBinding> CommonPlan<VM> {
610
628
& self . los
611
629
}
612
630
613
- pub fn get_nonmoving ( & self ) -> & ImmortalSpace < VM > {
631
+ pub fn get_nonmoving ( & self ) -> & NonMovingSpace < VM > {
614
632
& self . nonmoving
615
633
}
634
+
635
+ fn new_nonmoving_space ( args : & mut CreateSpecificPlanArgs < VM > ) -> NonMovingSpace < VM > {
636
+ let space_args = args. get_space_args ( "nonmoving" , true , false , VMRequest :: discontiguous ( ) ) ;
637
+ cfg_if:: cfg_if! {
638
+ if #[ cfg( any( feature = "immortal_as_nonmoving" , feature = "marksweep_as_nonmoving" ) ) ] {
639
+ NonMovingSpace :: new( space_args)
640
+ } else {
641
+ // Immix requires extra args.
642
+ NonMovingSpace :: new(
643
+ space_args,
644
+ crate :: policy:: immix:: ImmixSpaceArgs {
645
+ unlog_object_when_traced: false ,
646
+ #[ cfg( feature = "vo_bit" ) ]
647
+ mixed_age: false ,
648
+ never_move_objects: true ,
649
+ } ,
650
+ )
651
+ }
652
+ }
653
+ }
654
+
655
+ fn prepare_nonmoving_space ( & mut self , _full_heap : bool ) {
656
+ cfg_if:: cfg_if! {
657
+ if #[ cfg( feature = "immortal_as_nonmoving" ) ] {
658
+ self . nonmoving. prepare( ) ;
659
+ } else if #[ cfg( feature = "marksweep_as_nonmoving" ) ] {
660
+ self . nonmoving. prepare( _full_heap) ;
661
+ } else {
662
+ self . nonmoving. prepare( _full_heap, None ) ;
663
+ }
664
+ }
665
+ }
666
+
667
+ fn release_nonmoving_space ( & mut self , _full_heap : bool ) {
668
+ cfg_if:: cfg_if! {
669
+ if #[ cfg( feature = "immortal_as_nonmoving" ) ] {
670
+ self . nonmoving. release( ) ;
671
+ } else if #[ cfg( feature = "marksweep_as_nonmoving" ) ] {
672
+ self . nonmoving. prepare( _full_heap) ;
673
+ } else {
674
+ self . nonmoving. release( _full_heap) ;
675
+ }
676
+ }
677
+ }
678
+
679
+ fn end_of_gc_nonmoving_space ( & mut self ) {
680
+ cfg_if:: cfg_if! {
681
+ if #[ cfg( feature = "immortal_as_nonmoving" ) ] {
682
+ // Nothing we need to do for immortal space.
683
+ } else if #[ cfg( feature = "marksweep_as_nonmoving" ) ] {
684
+ self . nonmoving. end_of_gc( ) ;
685
+ } else {
686
+ self . nonmoving. end_of_gc( ) ;
687
+ }
688
+ }
689
+ }
616
690
}
617
691
618
692
use crate :: policy:: gc_work:: TraceKind ;
0 commit comments