@@ -197,7 +197,7 @@ pub trait Plan: 'static + HasSpaces + Sync + Downcast {
197197
198198 /// Inform the plan about the end of a GC. It is guaranteed that there is no further work for this GC.
199199 /// 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 ) ;
201201
202202 /// Notify the plan that an emergency collection will happen. The plan should try to free as much memory as possible.
203203 /// The default implementation will force a full heap collection for generational plans.
@@ -511,6 +511,10 @@ impl<VM: VMBinding> BasePlan<VM> {
511511 self . vm_space . release ( ) ;
512512 }
513513
514+ pub fn end_of_gc ( & mut self , _tls : VMWorkerThread ) {
515+ // Do nothing here. None of the spaces needs end_of_gc.
516+ }
517+
514518 pub ( crate ) fn collection_required < P : Plan > ( & self , plan : & P , space_full : bool ) -> bool {
515519 let stress_force_gc =
516520 crate :: util:: heap:: gc_trigger:: GCTrigger :: < VM > :: should_do_stress_gc_inner (
@@ -542,6 +546,17 @@ impl<VM: VMBinding> BasePlan<VM> {
542546 }
543547}
544548
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+
545560/**
546561CommonPlan 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.
547562*/
@@ -551,9 +566,12 @@ pub struct CommonPlan<VM: VMBinding> {
551566 pub immortal : ImmortalSpace < VM > ,
552567 #[ space]
553568 pub los : LargeObjectSpace < VM > ,
554- // TODO: We should use a marksweep space for nonmoving.
555569 #[ 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 > ,
557575 #[ parent]
558576 pub base : BasePlan < VM > ,
559577}
@@ -571,12 +589,7 @@ impl<VM: VMBinding> CommonPlan<VM> {
571589 args. get_space_args ( "los" , true , false , VMRequest :: discontiguous ( ) ) ,
572590 false ,
573591 ) ,
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) ,
580593 base : BasePlan :: new ( args) ,
581594 }
582595 }
@@ -591,17 +604,22 @@ impl<VM: VMBinding> CommonPlan<VM> {
591604 pub fn prepare ( & mut self , tls : VMWorkerThread , full_heap : bool ) {
592605 self . immortal . prepare ( ) ;
593606 self . los . prepare ( full_heap) ;
594- self . nonmoving . prepare ( ) ;
607+ self . prepare_nonmoving_space ( full_heap ) ;
595608 self . base . prepare ( tls, full_heap)
596609 }
597610
598611 pub fn release ( & mut self , tls : VMWorkerThread , full_heap : bool ) {
599612 self . immortal . release ( ) ;
600613 self . los . release ( full_heap) ;
601- self . nonmoving . release ( ) ;
614+ self . release_nonmoving_space ( full_heap ) ;
602615 self . base . release ( tls, full_heap)
603616 }
604617
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+
605623 pub fn get_immortal ( & self ) -> & ImmortalSpace < VM > {
606624 & self . immortal
607625 }
@@ -610,9 +628,65 @@ impl<VM: VMBinding> CommonPlan<VM> {
610628 & self . los
611629 }
612630
613- pub fn get_nonmoving ( & self ) -> & ImmortalSpace < VM > {
631+ pub fn get_nonmoving ( & self ) -> & NonMovingSpace < VM > {
614632 & self . nonmoving
615633 }
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+ }
616690}
617691
618692use crate :: policy:: gc_work:: TraceKind ;
0 commit comments