@@ -13,11 +13,9 @@ use crate::scheduler::*;
13
13
use crate :: util:: alloc:: allocators:: AllocatorSelector ;
14
14
#[ cfg( feature = "analysis" ) ]
15
15
use crate :: util:: analysis:: AnalysisManager ;
16
- use crate :: util:: conversions:: bytes_to_pages;
17
16
use crate :: util:: copy:: { CopyConfig , GCWorkerCopyContext } ;
18
17
use crate :: util:: heap:: layout:: heap_layout:: Mmapper ;
19
18
use crate :: util:: heap:: layout:: heap_layout:: VMMap ;
20
- use crate :: util:: heap:: layout:: map:: Map ;
21
19
use crate :: util:: heap:: HeapMeta ;
22
20
use crate :: util:: heap:: VMRequest ;
23
21
use crate :: util:: metadata:: side_metadata:: SideMetadataSanity ;
@@ -70,30 +68,39 @@ pub fn create_plan<VM: VMBinding>(
70
68
options : Arc < Options > ,
71
69
scheduler : Arc < GCWorkScheduler < VM > > ,
72
70
) -> Box < dyn Plan < VM = VM > > {
73
- match plan {
74
- PlanSelector :: NoGC => Box :: new ( crate :: plan:: nogc:: NoGC :: new ( vm_map, mmapper, options) ) ,
71
+ let plan = match plan {
72
+ PlanSelector :: NoGC => Box :: new ( crate :: plan:: nogc:: NoGC :: new ( vm_map, mmapper, options) )
73
+ as Box < dyn Plan < VM = VM > > ,
75
74
PlanSelector :: SemiSpace => Box :: new ( crate :: plan:: semispace:: SemiSpace :: new (
76
75
vm_map, mmapper, options,
77
- ) ) ,
76
+ ) ) as Box < dyn Plan < VM = VM > > ,
78
77
PlanSelector :: GenCopy => Box :: new ( crate :: plan:: generational:: copying:: GenCopy :: new (
79
78
vm_map, mmapper, options,
80
- ) ) ,
79
+ ) ) as Box < dyn Plan < VM = VM > > ,
81
80
PlanSelector :: GenImmix => Box :: new ( crate :: plan:: generational:: immix:: GenImmix :: new (
82
81
vm_map, mmapper, options, scheduler,
83
- ) ) ,
82
+ ) ) as Box < dyn Plan < VM = VM > > ,
84
83
PlanSelector :: MarkSweep => Box :: new ( crate :: plan:: marksweep:: MarkSweep :: new (
85
84
vm_map, mmapper, options,
86
- ) ) ,
85
+ ) ) as Box < dyn Plan < VM = VM > > ,
87
86
PlanSelector :: Immix => Box :: new ( crate :: plan:: immix:: Immix :: new (
88
87
vm_map, mmapper, options, scheduler,
89
- ) ) ,
88
+ ) ) as Box < dyn Plan < VM = VM > > ,
90
89
PlanSelector :: PageProtect => Box :: new ( crate :: plan:: pageprotect:: PageProtect :: new (
91
90
vm_map, mmapper, options,
92
- ) ) ,
91
+ ) ) as Box < dyn Plan < VM = VM > > ,
93
92
PlanSelector :: MarkCompact => Box :: new ( crate :: plan:: markcompact:: MarkCompact :: new (
94
93
vm_map, mmapper, options,
95
- ) ) ,
96
- }
94
+ ) ) as Box < dyn Plan < VM = VM > > ,
95
+ } ;
96
+
97
+ // We have created Plan in the heap, and we won't explicitly move it. So each space
98
+ // now has a fixed address for its lifetime. It is safe now to initialize SFT.
99
+ plan. get_spaces ( )
100
+ . into_iter ( )
101
+ . for_each ( |s| s. initialize_sft ( ) ) ;
102
+
103
+ plan
97
104
}
98
105
99
106
/// Create thread local GC worker.
@@ -156,8 +163,8 @@ pub trait Plan: 'static + Sync + Downcast {
156
163
& self . base ( ) . options
157
164
}
158
165
159
- // unsafe because this can only be called once by the init thread
160
- fn gc_init ( & mut self , heap_size : usize , vm_map : & ' static VMMap ) ;
166
+ /// get all the spaces in the plan
167
+ fn get_spaces ( & self ) -> Vec < & dyn Space < Self :: VM > > ;
161
168
162
169
fn get_allocator_mapping ( & self ) -> & ' static EnumMap < AllocationSemantics , AllocatorSelector > ;
163
170
@@ -437,7 +444,7 @@ pub fn create_vm_space<VM: VMBinding>(
437
444
use crate :: util:: heap:: layout:: vm_layout_constants:: BYTES_IN_CHUNK ;
438
445
let boot_segment_mb = raw_align_up ( boot_segment_bytes, BYTES_IN_CHUNK ) >> LOG_BYTES_IN_MBYTE ;
439
446
440
- ImmortalSpace :: new (
447
+ let space = ImmortalSpace :: new (
441
448
"boot" ,
442
449
false ,
443
450
VMRequest :: fixed_size ( boot_segment_mb) ,
@@ -446,7 +453,12 @@ pub fn create_vm_space<VM: VMBinding>(
446
453
mmapper,
447
454
heap,
448
455
constraints,
449
- )
456
+ ) ;
457
+
458
+ // The space is mapped externally by the VM. We need to update our mmapper to mark the range as mapped.
459
+ space. ensure_mapped ( ) ;
460
+
461
+ space
450
462
}
451
463
452
464
impl < VM : VMBinding > BasePlan < VM > {
@@ -539,27 +551,17 @@ impl<VM: VMBinding> BasePlan<VM> {
539
551
}
540
552
}
541
553
542
- pub fn gc_init ( & mut self , heap_size : usize , vm_map : & ' static VMMap ) {
543
- vm_map. boot ( ) ;
544
- vm_map. finalize_static_space_map (
545
- self . heap . get_discontig_start ( ) ,
546
- self . heap . get_discontig_end ( ) ,
547
- ) ;
548
- self . heap
549
- . total_pages
550
- . store ( bytes_to_pages ( heap_size) , Ordering :: Relaxed ) ;
551
-
552
- #[ cfg( feature = "code_space" ) ]
553
- self . code_space . init ( vm_map) ;
554
- #[ cfg( feature = "code_space" ) ]
555
- self . code_lo_space . init ( vm_map) ;
556
- #[ cfg( feature = "ro_space" ) ]
557
- self . ro_space . init ( vm_map) ;
558
- #[ cfg( feature = "vm_space" ) ]
559
- {
560
- self . vm_space . init ( vm_map) ;
561
- self . vm_space . ensure_mapped ( ) ;
562
- }
554
+ pub fn get_spaces ( & self ) -> Vec < & dyn Space < VM > > {
555
+ vec ! [
556
+ #[ cfg( feature = "code_space" ) ]
557
+ & self . code_space,
558
+ #[ cfg( feature = "code_space" ) ]
559
+ & self . code_lo_space,
560
+ #[ cfg( feature = "ro_space" ) ]
561
+ & self . ro_space,
562
+ #[ cfg( feature = "vm_space" ) ]
563
+ & self . vm_space,
564
+ ]
563
565
}
564
566
565
567
/// The application code has requested a collection.
@@ -927,10 +929,11 @@ impl<VM: VMBinding> CommonPlan<VM> {
927
929
}
928
930
}
929
931
930
- pub fn gc_init ( & mut self , heap_size : usize , vm_map : & ' static VMMap ) {
931
- self . base . gc_init ( heap_size, vm_map) ;
932
- self . immortal . init ( vm_map) ;
933
- self . los . init ( vm_map) ;
932
+ pub fn get_spaces ( & self ) -> Vec < & dyn Space < VM > > {
933
+ let mut ret = self . base . get_spaces ( ) ;
934
+ ret. push ( & self . immortal ) ;
935
+ ret. push ( & self . los ) ;
936
+ ret
934
937
}
935
938
936
939
pub fn get_used_pages ( & self ) -> usize {
0 commit comments