Skip to content

Commit 45c6a9b

Browse files
authored
Side metadata page accounting (#298)
* Introduce SideMetadataContext and SideMetadata * Move map/unmap to SideMetadata * Extract page accounting code from page resource * Add PageAccounting to SideMetadata
1 parent b3536df commit 45c6a9b

26 files changed

+515
-482
lines changed

docs/tutorial/code/mygc_semispace/global.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::util::heap::layout::heap_layout::VMMap;
2020
use crate::util::heap::layout::vm_layout_constants::{HEAP_END, HEAP_START};
2121
use crate::util::heap::HeapMeta;
2222
use crate::util::heap::VMRequest;
23+
use crate::util::side_metadata::SideMetadataContext;
2324
use crate::util::options::UnsafeOptionsWrapper;
2425
use crate::util::OpaquePointer;
2526
use crate::vm::VMBinding;
@@ -174,6 +175,7 @@ impl<VM: VMBinding> MyGC<VM> {
174175
) -> Self {
175176
// Modify
176177
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
178+
let global_metadata_specs = SideMetadataContext::new_global_specs(&[]);
177179

178180
MyGC {
179181
hi: AtomicBool::new(false),
@@ -183,6 +185,7 @@ impl<VM: VMBinding> MyGC<VM> {
183185
false,
184186
true,
185187
VMRequest::discontiguous(),
188+
global_metadata_specs.clone(),
186189
vm_map,
187190
mmapper,
188191
&mut heap,
@@ -193,11 +196,12 @@ impl<VM: VMBinding> MyGC<VM> {
193196
true,
194197
true,
195198
VMRequest::discontiguous(),
199+
global_metadata_specs.clone(),
196200
vm_map,
197201
mmapper,
198202
&mut heap,
199203
),
200-
common: CommonPlan::new(vm_map, mmapper, options, heap, &MYGC_CONSTRAINTS, &[]),
204+
common: CommonPlan::new(vm_map, mmapper, options, heap, &MYGC_CONSTRAINTS, global_metadata_specs),
201205
}
202206
}
203207
// ANCHOR_END: plan_new

src/plan/gencopy/global.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::{
33
gc_work::{GenCopyCopyContext, GenCopyMatureProcessEdges, GenCopyNurseryProcessEdges},
44
LOGGING_META,
55
};
6+
use crate::plan::global::BasePlan;
67
use crate::plan::global::CommonPlan;
78
use crate::plan::global::GcStatus;
89
use crate::plan::AllocationSemantics;
@@ -22,10 +23,10 @@ use crate::util::heap::VMRequest;
2223
use crate::util::options::UnsafeOptionsWrapper;
2324
#[cfg(feature = "sanity")]
2425
use crate::util::sanity::sanity_checker::*;
26+
use crate::util::side_metadata::SideMetadataContext;
2527
use crate::util::OpaquePointer;
2628
use crate::vm::*;
2729
use crate::{mmtk::MMTK, plan::barriers::BarrierSelector};
28-
use crate::{plan::global::BasePlan, util::side_metadata::SideMetadataSpec};
2930
use enum_map::EnumMap;
3031
use std::sync::atomic::{AtomicBool, Ordering};
3132
use std::sync::Arc;
@@ -168,10 +169,6 @@ impl<VM: VMBinding> Plan for GenCopy<VM> {
168169
fn in_nursery(&self) -> bool {
169170
self.in_nursery.load(Ordering::SeqCst)
170171
}
171-
172-
fn global_side_metadata_specs(&self) -> &[SideMetadataSpec] {
173-
&self.common().global_metadata_specs
174-
}
175172
}
176173

177174
impl<VM: VMBinding> GenCopy<VM> {
@@ -181,18 +178,20 @@ impl<VM: VMBinding> GenCopy<VM> {
181178
options: Arc<UnsafeOptionsWrapper>,
182179
) -> Self {
183180
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
184-
let global_metadata_specs = if super::ACTIVE_BARRIER == BarrierSelector::ObjectBarrier {
181+
let gencopy_specs = if super::ACTIVE_BARRIER == BarrierSelector::ObjectBarrier {
185182
vec![LOGGING_META]
186183
} else {
187184
vec![]
188185
};
186+
let global_metadata_specs = SideMetadataContext::new_global_specs(&gencopy_specs);
189187

190188
GenCopy {
191189
nursery: CopySpace::new(
192190
"nursery",
193191
false,
194192
true,
195193
VMRequest::fixed_extent(NURSERY_SIZE, false),
194+
global_metadata_specs.clone(),
196195
vm_map,
197196
mmapper,
198197
&mut heap,
@@ -203,6 +202,7 @@ impl<VM: VMBinding> GenCopy<VM> {
203202
false,
204203
true,
205204
VMRequest::discontiguous(),
205+
global_metadata_specs.clone(),
206206
vm_map,
207207
mmapper,
208208
&mut heap,
@@ -212,6 +212,7 @@ impl<VM: VMBinding> GenCopy<VM> {
212212
true,
213213
true,
214214
VMRequest::discontiguous(),
215+
global_metadata_specs.clone(),
215216
vm_map,
216217
mmapper,
217218
&mut heap,
@@ -222,7 +223,7 @@ impl<VM: VMBinding> GenCopy<VM> {
222223
options,
223224
heap,
224225
&GENCOPY_CONSTRAINTS,
225-
&&global_metadata_specs,
226+
global_metadata_specs,
226227
),
227228
in_nursery: AtomicBool::default(),
228229
}

src/plan/global.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use crate::util::alloc::allocators::AllocatorSelector;
1313
#[cfg(feature = "analysis")]
1414
use crate::util::analysis::AnalysisManager;
1515
use crate::util::conversions::bytes_to_pages;
16-
use crate::util::gc_byte;
1716
use crate::util::heap::layout::heap_layout::Mmapper;
1817
use crate::util::heap::layout::heap_layout::VMMap;
1918
use crate::util::heap::layout::map::Map;
@@ -309,10 +308,6 @@ pub trait Plan: 'static + Sync + Downcast {
309308
);
310309
}
311310
}
312-
313-
fn global_side_metadata_specs(&self) -> &[SideMetadataSpec] {
314-
&[]
315-
}
316311
}
317312

318313
impl_downcast!(Plan assoc VM);
@@ -381,6 +376,7 @@ pub fn create_vm_space<VM: VMBinding>(
381376
heap: &mut HeapMeta,
382377
boot_segment_bytes: usize,
383378
constraints: &'static PlanConstraints,
379+
global_side_metadata_specs: Vec<SideMetadataSpec>,
384380
) -> ImmortalSpace<VM> {
385381
use crate::util::constants::LOG_BYTES_IN_MBYTE;
386382
// let boot_segment_bytes = BOOT_IMAGE_END - BOOT_IMAGE_DATA_START;
@@ -394,6 +390,7 @@ pub fn create_vm_space<VM: VMBinding>(
394390
"boot",
395391
false,
396392
VMRequest::fixed_size(boot_segment_mb),
393+
global_side_metadata_specs,
397394
vm_map,
398395
mmapper,
399396
heap,
@@ -404,12 +401,14 @@ pub fn create_vm_space<VM: VMBinding>(
404401
impl<VM: VMBinding> BasePlan<VM> {
405402
#[allow(unused_mut)] // 'heap' only needs to be mutable for certain features
406403
#[allow(unused_variables)] // 'constraints' is only needed for certain features
404+
#[allow(clippy::redundant_clone)] // depends on features, the last clone of side metadata specs is not necessary.
407405
pub fn new(
408406
vm_map: &'static VMMap,
409407
mmapper: &'static Mmapper,
410408
options: Arc<UnsafeOptionsWrapper>,
411409
mut heap: HeapMeta,
412410
constraints: &'static PlanConstraints,
411+
global_side_metadata_specs: Vec<SideMetadataSpec>,
413412
) -> BasePlan<VM> {
414413
let stats = Stats::new();
415414
// Initializing the analysis manager and routines
@@ -423,6 +422,7 @@ impl<VM: VMBinding> BasePlan<VM> {
423422
"code_space",
424423
true,
425424
VMRequest::discontiguous(),
425+
global_side_metadata_specs.clone(),
426426
vm_map,
427427
mmapper,
428428
&mut heap,
@@ -433,6 +433,7 @@ impl<VM: VMBinding> BasePlan<VM> {
433433
"ro_space",
434434
true,
435435
VMRequest::discontiguous(),
436+
global_side_metadata_specs.clone(),
436437
vm_map,
437438
mmapper,
438439
&mut heap,
@@ -445,6 +446,7 @@ impl<VM: VMBinding> BasePlan<VM> {
445446
&mut heap,
446447
options.vm_space_size,
447448
constraints,
449+
global_side_metadata_specs,
448450
),
449451
}),
450452
initialized: AtomicBool::new(false),
@@ -721,7 +723,6 @@ CommonPlan is for representing state and features used by _many_ plans, but that
721723
pub struct CommonPlan<VM: VMBinding> {
722724
pub unsync: UnsafeCell<CommonUnsync<VM>>,
723725
pub base: BasePlan<VM>,
724-
pub global_metadata_specs: Vec<SideMetadataSpec>,
725726
}
726727

727728
pub struct CommonUnsync<VM: VMBinding> {
@@ -739,20 +740,15 @@ impl<VM: VMBinding> CommonPlan<VM> {
739740
options: Arc<UnsafeOptionsWrapper>,
740741
mut heap: HeapMeta,
741742
constraints: &'static PlanConstraints,
742-
global_side_metadata_specs: &[SideMetadataSpec],
743+
global_side_metadata_specs: Vec<SideMetadataSpec>,
743744
) -> CommonPlan<VM> {
744-
let mut specs = if cfg!(feature = "side_gc_header") {
745-
vec![gc_byte::SIDE_GC_BYTE_SPEC]
746-
} else {
747-
vec![]
748-
};
749-
specs.extend_from_slice(global_side_metadata_specs);
750745
CommonPlan {
751746
unsync: UnsafeCell::new(CommonUnsync {
752747
immortal: ImmortalSpace::new(
753748
"immortal",
754749
true,
755750
VMRequest::discontiguous(),
751+
global_side_metadata_specs.clone(),
756752
vm_map,
757753
mmapper,
758754
&mut heap,
@@ -762,14 +758,21 @@ impl<VM: VMBinding> CommonPlan<VM> {
762758
"los",
763759
true,
764760
VMRequest::discontiguous(),
761+
global_side_metadata_specs.clone(),
765762
vm_map,
766763
mmapper,
767764
&mut heap,
768765
constraints,
769766
),
770767
}),
771-
base: BasePlan::new(vm_map, mmapper, options, heap, constraints),
772-
global_metadata_specs: specs,
768+
base: BasePlan::new(
769+
vm_map,
770+
mmapper,
771+
options,
772+
heap,
773+
constraints,
774+
global_side_metadata_specs,
775+
),
773776
}
774777
}
775778

src/plan/marksweep/global.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::util::heap::HeapMeta;
2020
use crate::util::options::UnsafeOptionsWrapper;
2121
#[cfg(feature = "sanity")]
2222
use crate::util::sanity::sanity_checker::*;
23+
use crate::util::side_metadata::SideMetadataContext;
2324
use crate::util::OpaquePointer;
2425
use crate::vm::VMBinding;
2526
use std::sync::Arc;
@@ -127,9 +128,11 @@ impl<VM: VMBinding> MarkSweep<VM> {
127128
options: Arc<UnsafeOptionsWrapper>,
128129
) -> Self {
129130
let heap = HeapMeta::new(HEAP_START, HEAP_END);
131+
let specs = SideMetadataContext::new_global_specs(&[]);
132+
130133
MarkSweep {
131-
common: CommonPlan::new(vm_map, mmapper, options, heap, &MS_CONSTRAINTS, &[]),
132-
ms: MallocSpace::new(),
134+
ms: MallocSpace::new(specs.clone()),
135+
common: CommonPlan::new(vm_map, mmapper, options, heap, &MS_CONSTRAINTS, specs),
133136
}
134137
}
135138

src/plan/nogc/global.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::util::heap::HeapMeta;
1616
#[allow(unused_imports)]
1717
use crate::util::heap::VMRequest;
1818
use crate::util::options::UnsafeOptionsWrapper;
19+
use crate::util::side_metadata::SideMetadataContext;
1920
use crate::util::OpaquePointer;
2021
use crate::vm::VMBinding;
2122
use enum_map::EnumMap;
@@ -106,14 +107,20 @@ impl<VM: VMBinding> NoGC<VM> {
106107
#[cfg(feature = "nogc_lock_free")]
107108
let heap = HeapMeta::new(HEAP_START, HEAP_END);
108109

110+
let global_specs = SideMetadataContext::new_global_specs(&[]);
111+
109112
#[cfg(feature = "nogc_lock_free")]
110-
let nogc_space =
111-
NoGCImmortalSpace::new("nogc_space", cfg!(not(feature = "nogc_no_zeroing")));
113+
let nogc_space = NoGCImmortalSpace::new(
114+
"nogc_space",
115+
cfg!(not(feature = "nogc_no_zeroing")),
116+
global_specs.clone(),
117+
);
112118
#[cfg(not(feature = "nogc_lock_free"))]
113119
let nogc_space = NoGCImmortalSpace::new(
114120
"nogc_space",
115121
true,
116122
VMRequest::discontiguous(),
123+
global_specs.clone(),
117124
vm_map,
118125
mmapper,
119126
&mut heap,
@@ -122,7 +129,14 @@ impl<VM: VMBinding> NoGC<VM> {
122129

123130
NoGC {
124131
nogc_space,
125-
base: BasePlan::new(vm_map, mmapper, options, heap, &NOGC_CONSTRAINTS),
132+
base: BasePlan::new(
133+
vm_map,
134+
mmapper,
135+
options,
136+
heap,
137+
&NOGC_CONSTRAINTS,
138+
global_specs,
139+
),
126140
}
127141
}
128142
}

src/plan/semispace/global.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::gc_work::{SSCopyContext, SSProcessEdges};
2+
use crate::mmtk::MMTK;
23
use crate::plan::global::CommonPlan;
34
use crate::plan::global::GcStatus;
45
use crate::plan::semispace::mutator::ALLOCATOR_MAPPING;
@@ -20,8 +21,8 @@ use crate::util::heap::VMRequest;
2021
use crate::util::options::UnsafeOptionsWrapper;
2122
#[cfg(feature = "sanity")]
2223
use crate::util::sanity::sanity_checker::*;
24+
use crate::util::side_metadata::SideMetadataContext;
2325
use crate::util::OpaquePointer;
24-
use crate::{mmtk::MMTK, util::side_metadata::SideMetadataSpec};
2526
use crate::{plan::global::BasePlan, vm::VMBinding};
2627
use std::sync::atomic::{AtomicBool, Ordering};
2728
use std::sync::Arc;
@@ -139,10 +140,6 @@ impl<VM: VMBinding> Plan for SemiSpace<VM> {
139140
fn common(&self) -> &CommonPlan<VM> {
140141
&self.common
141142
}
142-
143-
fn global_side_metadata_specs(&self) -> &[SideMetadataSpec] {
144-
&self.common().global_metadata_specs
145-
}
146143
}
147144

148145
impl<VM: VMBinding> SemiSpace<VM> {
@@ -152,6 +149,7 @@ impl<VM: VMBinding> SemiSpace<VM> {
152149
options: Arc<UnsafeOptionsWrapper>,
153150
) -> Self {
154151
let mut heap = HeapMeta::new(HEAP_START, HEAP_END);
152+
let global_metadata_specs = SideMetadataContext::new_global_specs(&[]);
155153

156154
SemiSpace {
157155
hi: AtomicBool::new(false),
@@ -160,6 +158,7 @@ impl<VM: VMBinding> SemiSpace<VM> {
160158
false,
161159
true,
162160
VMRequest::discontiguous(),
161+
global_metadata_specs.clone(),
163162
vm_map,
164163
mmapper,
165164
&mut heap,
@@ -169,11 +168,19 @@ impl<VM: VMBinding> SemiSpace<VM> {
169168
true,
170169
true,
171170
VMRequest::discontiguous(),
171+
global_metadata_specs.clone(),
172172
vm_map,
173173
mmapper,
174174
&mut heap,
175175
),
176-
common: CommonPlan::new(vm_map, mmapper, options, heap, &SS_CONSTRAINTS, &[]),
176+
common: CommonPlan::new(
177+
vm_map,
178+
mmapper,
179+
options,
180+
heap,
181+
&SS_CONSTRAINTS,
182+
global_metadata_specs,
183+
),
177184
}
178185
}
179186

0 commit comments

Comments
 (0)