@@ -404,18 +404,22 @@ pub struct CreateSpecificPlanArgs<'a, VM: VMBinding> {
404404
405405impl < VM : VMBinding > CreateSpecificPlanArgs < ' _ , VM > {
406406 /// Get a PlanCreateSpaceArgs that can be used to create a space
407- pub fn get_space_args (
407+ pub fn _get_space_args (
408408 & mut self ,
409409 name : & ' static str ,
410410 zeroed : bool ,
411411 permission_exec : bool ,
412+ unlog_allocated_object : bool ,
413+ unlog_traced_object : bool ,
412414 vmrequest : VMRequest ,
413415 ) -> PlanCreateSpaceArgs < ' _ , VM > {
414416 PlanCreateSpaceArgs {
415417 name,
416418 zeroed,
417419 permission_exec,
418420 vmrequest,
421+ unlog_allocated_object,
422+ unlog_traced_object,
419423 global_side_metadata_specs : self . global_side_metadata_specs . clone ( ) ,
420424 vm_map : self . global_args . vm_map ,
421425 mmapper : self . global_args . mmapper ,
@@ -427,39 +431,121 @@ impl<VM: VMBinding> CreateSpecificPlanArgs<'_, VM> {
427431 global_state : self . global_args . state . clone ( ) ,
428432 }
429433 }
434+
435+ // The following are some convenience methods for common presets.
436+ // These are not an exhaustive list -- it is just common presets that are used by most plans.
437+
438+ /// Get a preset for a nursery space (where young objects are located).
439+ pub fn get_nursery_space_args (
440+ & mut self ,
441+ name : & ' static str ,
442+ zeroed : bool ,
443+ permission_exec : bool ,
444+ vmrequest : VMRequest ,
445+ ) -> PlanCreateSpaceArgs < ' _ , VM > {
446+ // Objects are allocatd as young, and when traced, they stay young. If they are copied out of the nursery space, they will be moved to a mature space,
447+ // and log bits will be set in that case by the mature space.
448+ self . _get_space_args ( name, zeroed, permission_exec, false , false , vmrequest)
449+ }
450+
451+ /// Get a preset for a mature space (where mature objects are located).
452+ pub fn get_mature_space_args (
453+ & mut self ,
454+ name : & ' static str ,
455+ zeroed : bool ,
456+ permission_exec : bool ,
457+ vmrequest : VMRequest ,
458+ ) -> PlanCreateSpaceArgs < ' _ , VM > {
459+ // Objects are allocated as mature (pre-tenured), and when traced, they stay mature.
460+ // If an object gets copied into a mature space, the object is also mature,
461+ self . _get_space_args ( name, zeroed, permission_exec, true , true , vmrequest)
462+ }
463+
464+ // Get a preset for a mixed age space (where both young and mature objects are located).
465+ pub fn get_mixed_age_space_args (
466+ & mut self ,
467+ name : & ' static str ,
468+ zeroed : bool ,
469+ permission_exec : bool ,
470+ vmrequest : VMRequest ,
471+ ) -> PlanCreateSpaceArgs < ' _ , VM > {
472+ // Objects are allocated as young, and when traced, they become mature objects.
473+ self . _get_space_args ( name, zeroed, permission_exec, false , true , vmrequest)
474+ }
475+
476+ /// Get a preset for spaces in a non-generational plan.
477+ pub fn get_normal_space_args (
478+ & mut self ,
479+ name : & ' static str ,
480+ zeroed : bool ,
481+ permission_exec : bool ,
482+ vmrequest : VMRequest ,
483+ ) -> PlanCreateSpaceArgs < ' _ , VM > {
484+ // Non generational plan: we do not use any of the flags about log bits.
485+ self . _get_space_args ( name, zeroed, permission_exec, false , false , vmrequest)
486+ }
487+
488+ /// Get a preset for spaces in [`crate::plan::global::CommonPlan`].
489+ /// Spaces like LOS which may include both young and mature objects should not use this method.
490+ pub fn get_common_space_args (
491+ & mut self ,
492+ generational : bool ,
493+ name : & ' static str ,
494+ ) -> PlanCreateSpaceArgs < ' _ , VM > {
495+ self . get_base_space_args (
496+ generational,
497+ name,
498+ false , // Common spaces are not executable.
499+ )
500+ }
501+
502+ /// Get a preset for spaces in [`crate::plan::global::BasePlan`].
503+ pub fn get_base_space_args (
504+ & mut self ,
505+ generational : bool ,
506+ name : & ' static str ,
507+ permission_exec : bool ,
508+ ) -> PlanCreateSpaceArgs < ' _ , VM > {
509+ if generational {
510+ // In generational plans, common/base spaces behave like a mature space:
511+ // * the objects in these spaces are not traced in a nursery GC
512+ // * the log bits for the objects are maintained exactly the same as a mature space.
513+ // Thus we consider them as mature spaces.
514+ self . get_mature_space_args ( name, true , permission_exec, VMRequest :: discontiguous ( ) )
515+ } else {
516+ self . get_normal_space_args ( name, true , permission_exec, VMRequest :: discontiguous ( ) )
517+ }
518+ }
430519}
431520
432521impl < VM : VMBinding > BasePlan < VM > {
433522 #[ allow( unused_mut) ] // 'args' only needs to be mutable for certain features
434523 pub fn new ( mut args : CreateSpecificPlanArgs < VM > ) -> BasePlan < VM > {
524+ let _generational = args. constraints . generational ;
435525 BasePlan {
436526 #[ cfg( feature = "code_space" ) ]
437- code_space : ImmortalSpace :: new ( args. get_space_args (
527+ code_space : ImmortalSpace :: new ( args. get_base_space_args (
528+ _generational,
438529 "code_space" ,
439530 true ,
440- true ,
441- VMRequest :: discontiguous ( ) ,
442531 ) ) ,
443532 #[ cfg( feature = "code_space" ) ]
444- code_lo_space : ImmortalSpace :: new ( args. get_space_args (
533+ code_lo_space : ImmortalSpace :: new ( args. get_base_space_args (
534+ _generational,
445535 "code_lo_space" ,
446536 true ,
447- true ,
448- VMRequest :: discontiguous ( ) ,
449537 ) ) ,
450538 #[ cfg( feature = "ro_space" ) ]
451- ro_space : ImmortalSpace :: new ( args. get_space_args (
539+ ro_space : ImmortalSpace :: new ( args. get_base_space_args (
540+ _generational,
452541 "ro_space" ,
453- true ,
454542 false ,
455- VMRequest :: discontiguous ( ) ,
456543 ) ) ,
457544 #[ cfg( feature = "vm_space" ) ]
458- vm_space : VMSpace :: new ( args. get_space_args (
545+ vm_space : VMSpace :: new ( args. get_base_space_args (
546+ _generational,
459547 "vm_space" ,
460- false ,
461548 false , // it doesn't matter -- we are not mmapping for VM space.
462- VMRequest :: discontiguous ( ) ,
463549 ) ) ,
464550
465551 global_state : args. global_args . state . clone ( ) ,
@@ -517,6 +603,28 @@ impl<VM: VMBinding> BasePlan<VM> {
517603 self . vm_space . release ( ) ;
518604 }
519605
606+ pub fn clear_side_log_bits ( & self ) {
607+ #[ cfg( feature = "code_space" ) ]
608+ self . code_space . clear_side_log_bits ( ) ;
609+ #[ cfg( feature = "code_space" ) ]
610+ self . code_lo_space . clear_side_log_bits ( ) ;
611+ #[ cfg( feature = "ro_space" ) ]
612+ self . ro_space . clear_side_log_bits ( ) ;
613+ #[ cfg( feature = "vm_space" ) ]
614+ self . vm_space . clear_side_log_bits ( ) ;
615+ }
616+
617+ pub fn set_side_log_bits ( & self ) {
618+ #[ cfg( feature = "code_space" ) ]
619+ self . code_space . set_side_log_bits ( ) ;
620+ #[ cfg( feature = "code_space" ) ]
621+ self . code_lo_space . set_side_log_bits ( ) ;
622+ #[ cfg( feature = "ro_space" ) ]
623+ self . ro_space . set_side_log_bits ( ) ;
624+ #[ cfg( feature = "vm_space" ) ]
625+ self . vm_space . set_side_log_bits ( ) ;
626+ }
627+
520628 pub fn end_of_gc ( & mut self , _tls : VMWorkerThread ) {
521629 // Do nothing here. None of the spaces needs end_of_gc.
522630 }
@@ -584,16 +692,19 @@ pub struct CommonPlan<VM: VMBinding> {
584692
585693impl < VM : VMBinding > CommonPlan < VM > {
586694 pub fn new ( mut args : CreateSpecificPlanArgs < VM > ) -> CommonPlan < VM > {
695+ let needs_log_bit = args. constraints . needs_log_bit ;
696+ let generational = args. constraints . generational ;
587697 CommonPlan {
588- immortal : ImmortalSpace :: new ( args. get_space_args (
589- "immortal" ,
590- true ,
591- false ,
592- VMRequest :: discontiguous ( ) ,
593- ) ) ,
698+ immortal : ImmortalSpace :: new ( args. get_common_space_args ( generational, "immortal" ) ) ,
594699 los : LargeObjectSpace :: new (
595- args. get_space_args ( "los" , true , false , VMRequest :: discontiguous ( ) ) ,
700+ // LOS is a bit special, as it is a mixed age space. It has a logical nursery.
701+ if generational {
702+ args. get_mixed_age_space_args ( "los" , true , false , VMRequest :: discontiguous ( ) )
703+ } else {
704+ args. get_normal_space_args ( "los" , true , false , VMRequest :: discontiguous ( ) )
705+ } ,
596706 false ,
707+ needs_log_bit,
597708 ) ,
598709 nonmoving : Self :: new_nonmoving_space ( & mut args) ,
599710 base : BasePlan :: new ( args) ,
@@ -621,6 +732,18 @@ impl<VM: VMBinding> CommonPlan<VM> {
621732 self . base . release ( tls, full_heap)
622733 }
623734
735+ pub fn clear_side_log_bits ( & self ) {
736+ self . immortal . clear_side_log_bits ( ) ;
737+ self . los . clear_side_log_bits ( ) ;
738+ self . base . clear_side_log_bits ( ) ;
739+ }
740+
741+ pub fn set_side_log_bits ( & self ) {
742+ self . immortal . set_side_log_bits ( ) ;
743+ self . los . set_side_log_bits ( ) ;
744+ self . base . set_side_log_bits ( ) ;
745+ }
746+
624747 pub fn end_of_gc ( & mut self , tls : VMWorkerThread ) {
625748 self . end_of_gc_nonmoving_space ( ) ;
626749 self . base . end_of_gc ( tls) ;
@@ -639,7 +762,7 @@ impl<VM: VMBinding> CommonPlan<VM> {
639762 }
640763
641764 fn new_nonmoving_space ( args : & mut CreateSpecificPlanArgs < VM > ) -> NonMovingSpace < VM > {
642- let space_args = args. get_space_args ( "nonmoving" , true , false , VMRequest :: discontiguous ( ) ) ;
765+ let space_args = args. get_common_space_args ( args . constraints . generational , "nonmoving" ) ;
643766 cfg_if:: cfg_if! {
644767 if #[ cfg( any( feature = "immortal_as_nonmoving" , feature = "marksweep_as_nonmoving" ) ) ] {
645768 NonMovingSpace :: new( space_args)
@@ -648,8 +771,6 @@ impl<VM: VMBinding> CommonPlan<VM> {
648771 NonMovingSpace :: new(
649772 space_args,
650773 crate :: policy:: immix:: ImmixSpaceArgs {
651- unlog_object_when_traced: false ,
652- #[ cfg( feature = "vo_bit" ) ]
653774 mixed_age: false ,
654775 never_move_objects: true ,
655776 } ,
0 commit comments