@@ -404,18 +404,22 @@ pub struct CreateSpecificPlanArgs<'a, VM: VMBinding> {
404
404
405
405
impl < VM : VMBinding > CreateSpecificPlanArgs < ' _ , VM > {
406
406
/// Get a PlanCreateSpaceArgs that can be used to create a space
407
- pub fn get_space_args (
407
+ pub fn _get_space_args (
408
408
& mut self ,
409
409
name : & ' static str ,
410
410
zeroed : bool ,
411
411
permission_exec : bool ,
412
+ unlog_allocated_object : bool ,
413
+ unlog_traced_object : bool ,
412
414
vmrequest : VMRequest ,
413
415
) -> PlanCreateSpaceArgs < ' _ , VM > {
414
416
PlanCreateSpaceArgs {
415
417
name,
416
418
zeroed,
417
419
permission_exec,
418
420
vmrequest,
421
+ unlog_allocated_object,
422
+ unlog_traced_object,
419
423
global_side_metadata_specs : self . global_side_metadata_specs . clone ( ) ,
420
424
vm_map : self . global_args . vm_map ,
421
425
mmapper : self . global_args . mmapper ,
@@ -427,39 +431,121 @@ impl<VM: VMBinding> CreateSpecificPlanArgs<'_, VM> {
427
431
global_state : self . global_args . state . clone ( ) ,
428
432
}
429
433
}
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
+ }
430
519
}
431
520
432
521
impl < VM : VMBinding > BasePlan < VM > {
433
522
#[ allow( unused_mut) ] // 'args' only needs to be mutable for certain features
434
523
pub fn new ( mut args : CreateSpecificPlanArgs < VM > ) -> BasePlan < VM > {
524
+ let _generational = args. constraints . generational ;
435
525
BasePlan {
436
526
#[ 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,
438
529
"code_space" ,
439
530
true ,
440
- true ,
441
- VMRequest :: discontiguous ( ) ,
442
531
) ) ,
443
532
#[ 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,
445
535
"code_lo_space" ,
446
536
true ,
447
- true ,
448
- VMRequest :: discontiguous ( ) ,
449
537
) ) ,
450
538
#[ 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,
452
541
"ro_space" ,
453
- true ,
454
542
false ,
455
- VMRequest :: discontiguous ( ) ,
456
543
) ) ,
457
544
#[ 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,
459
547
"vm_space" ,
460
- false ,
461
548
false , // it doesn't matter -- we are not mmapping for VM space.
462
- VMRequest :: discontiguous ( ) ,
463
549
) ) ,
464
550
465
551
global_state : args. global_args . state . clone ( ) ,
@@ -517,6 +603,28 @@ impl<VM: VMBinding> BasePlan<VM> {
517
603
self . vm_space . release ( ) ;
518
604
}
519
605
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
+
520
628
pub fn end_of_gc ( & mut self , _tls : VMWorkerThread ) {
521
629
// Do nothing here. None of the spaces needs end_of_gc.
522
630
}
@@ -584,16 +692,19 @@ pub struct CommonPlan<VM: VMBinding> {
584
692
585
693
impl < VM : VMBinding > CommonPlan < VM > {
586
694
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 ;
587
697
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" ) ) ,
594
699
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
+ } ,
596
706
false ,
707
+ needs_log_bit,
597
708
) ,
598
709
nonmoving : Self :: new_nonmoving_space ( & mut args) ,
599
710
base : BasePlan :: new ( args) ,
@@ -621,6 +732,18 @@ impl<VM: VMBinding> CommonPlan<VM> {
621
732
self . base . release ( tls, full_heap)
622
733
}
623
734
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
+
624
747
pub fn end_of_gc ( & mut self , tls : VMWorkerThread ) {
625
748
self . end_of_gc_nonmoving_space ( ) ;
626
749
self . base . end_of_gc ( tls) ;
@@ -639,7 +762,7 @@ impl<VM: VMBinding> CommonPlan<VM> {
639
762
}
640
763
641
764
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" ) ;
643
766
cfg_if:: cfg_if! {
644
767
if #[ cfg( any( feature = "immortal_as_nonmoving" , feature = "marksweep_as_nonmoving" ) ) ] {
645
768
NonMovingSpace :: new( space_args)
@@ -648,8 +771,6 @@ impl<VM: VMBinding> CommonPlan<VM> {
648
771
NonMovingSpace :: new(
649
772
space_args,
650
773
crate :: policy:: immix:: ImmixSpaceArgs {
651
- unlog_object_when_traced: false ,
652
- #[ cfg( feature = "vo_bit" ) ]
653
774
mixed_age: false ,
654
775
never_move_objects: true ,
655
776
} ,
0 commit comments