Skip to content

Commit

Permalink
Allow different GC triggers (#712)
Browse files Browse the repository at this point in the history
This PR adds `GCTrigger` and forwards calls related with GC triggering to `GCTrigger`. `GCTrigger` would allow different implementations, such as fixed heap size, dynamic resizing, and runtime delegation. This PR only implements `FixedHeapSizeTrigger` and a simplified version of `MemBalancerTrigger`. This PR closes #561, and makes it easier to implement #641.

Changes:
* Adds `util::heap::gc_trigger::GCTrigger`. `Plan::poll()` is moved to `GCTrigger`. Any call to `Plan::poll()` is replaced with `GCTrigger::poll()`.
* Adds `util::options::GCTriggerSelector` and `gc_trigger` in `Options`. `gc_trigger` defaults to a fixed heap size of half of the physical memory.
* Refactoring on arguments for creating plans and spaces.
  * I needed to pass `GCTrigger` to plans and spaces so I think it would be better that I just take this chance to do the refactoring. 
  * We now have structs to organize the arguments and any plan and space will receive the same set of the arguments for their constructors. This greatly simplifies our code.
  • Loading branch information
qinsoon authored Dec 18, 2022
1 parent fc144cf commit 2300ce1
Show file tree
Hide file tree
Showing 30 changed files with 849 additions and 794 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ strum = "0.24"
strum_macros = "0.24"
cfg-if = "1.0"
itertools = "0.10.5"
sys-info = "0.9"
regex = "1.7.0"

[dev-dependencies]
rand = "0.7.3"
Expand Down
38 changes: 10 additions & 28 deletions docs/tutorial/code/mygc_semispace/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::plan::global::BasePlan; //Modify
use crate::plan::global::CommonPlan; // Add
use crate::plan::global::GcStatus; // Add
use crate::plan::global::{CreateGeneralPlanArgs, CreateSpecificPlanArgs};
use crate::plan::mygc::mutator::ALLOCATOR_MAPPING;
use crate::plan::mygc::gc_work::MyGCWorkContext;
use crate::plan::AllocationSemantics;
Expand Down Expand Up @@ -171,40 +172,21 @@ impl<VM: VMBinding> Plan for MyGC<VM> {
// Add
impl<VM: VMBinding> MyGC<VM> {
// ANCHOR: plan_new
fn new(
vm_map: &'static VMMap,
mmapper: &'static Mmapper,
options: Arc<Options>,
) -> Self {
fn new(args: CreateGeneralPlanArgs<VM>) -> Self {
// Modify
let mut heap = HeapMeta::new(&options);
let global_metadata_specs = SideMetadataContext::new_global_specs(&[]);
let mut plan_args = CreateSpecificPlanArgs {
global_args: args,
constraints: &MYGC_CONSTRAINTS,
global_side_metadata_specs: SideMetadataContext::new_global_specs(&[]),
};

let res = MyGC {
hi: AtomicBool::new(false),
// ANCHOR: copyspace_new
copyspace0: CopySpace::new(
"copyspace0",
false,
true,
VMRequest::discontiguous(),
global_metadata_specs.clone(),
vm_map,
mmapper,
&mut heap,
),
copyspace0: CopySpace::new(plan_args.get_space_args("copyspace0", true, VMRequest::discontiguous()), false),
// ANCHOR_END: copyspace_new
copyspace1: CopySpace::new(
"copyspace1",
true,
true,
VMRequest::discontiguous(),
global_metadata_specs.clone(),
vm_map,
mmapper,
&mut heap,
),
common: CommonPlan::new(vm_map, mmapper, options, heap, &MYGC_CONSTRAINTS, global_metadata_specs.clone()),
copyspace1: CopySpace::new(plan_args.get_space_args("copyspace1", true, VMRequest::discontiguous()), true),
common: CommonPlan::new(plan_args),
};

// Use SideMetadataSanity to check if each spec is valid. This is also needed for check
Expand Down
10 changes: 3 additions & 7 deletions docs/tutorial/src/mygc/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,13 @@ files.
options: Arc<UnsafeOptionsWrapper>,
) -> Box<dyn Plan<VM = VM>> {
match plan {
PlanSelector::NoGC => Box::new(crate::plan::nogc::NoGC::new(vm_map, mmapper, options)),
PlanSelector::SemiSpace => Box::new(crate::plan::semispace::SemiSpace::new(
vm_map, mmapper, options,
)),
PlanSelector::NoGC => Box::new(crate::plan::nogc::NoGC::new(args)),
PlanSelector::SemiSpace => Box::new(crate::plan::semispace::SemiSpace::new(args)),

// ...

// Create MyGC plan based on selector
PlanSelector::MyGC => Box::new(crate::plan::mygc::MyGC::new(
vm_map, mmapper, options,
))
PlanSelector::MyGC => Box::new(crate::plan::mygc::MyGC::new(args))
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion src/memory_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ pub fn gc_poll<VM: VMBinding>(mmtk: &MMTK<VM>, tls: VMMutatorThread) {
);

let plan = mmtk.get_plan();
if plan.should_trigger_gc_when_heap_is_full() && plan.poll(false, None) {
if plan.should_trigger_gc_when_heap_is_full() && plan.base().gc_trigger.poll(false, None) {
debug!("Collection required");
assert!(plan.is_initialized(), "GC is not allowed here: collection is not initialized (did you call initialize_collection()?).");
VM::VMCollection::block_for_gc(tls);
Expand Down
44 changes: 12 additions & 32 deletions src/plan/generational/copying/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use super::mutator::ALLOCATOR_MAPPING;
use crate::plan::generational::global::Gen;
use crate::plan::global::BasePlan;
use crate::plan::global::CommonPlan;
use crate::plan::global::CreateGeneralPlanArgs;
use crate::plan::global::CreateSpecificPlanArgs;
use crate::plan::global::GcStatus;
use crate::plan::AllocationSemantics;
use crate::plan::Plan;
Expand All @@ -13,17 +15,12 @@ use crate::policy::space::Space;
use crate::scheduler::*;
use crate::util::alloc::allocators::AllocatorSelector;
use crate::util::copy::*;
use crate::util::heap::layout::heap_layout::Mmapper;
use crate::util::heap::layout::heap_layout::VMMap;
use crate::util::heap::HeapMeta;
use crate::util::heap::VMRequest;
use crate::util::metadata::side_metadata::SideMetadataSanity;
use crate::util::options::Options;
use crate::util::VMWorkerThread;
use crate::vm::*;
use enum_map::EnumMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

use mmtk_macros::PlanTraceObject;

Expand Down Expand Up @@ -175,42 +172,25 @@ impl<VM: VMBinding> Plan for GenCopy<VM> {
}

impl<VM: VMBinding> GenCopy<VM> {
pub fn new(vm_map: &'static VMMap, mmapper: &'static Mmapper, options: Arc<Options>) -> Self {
let mut heap = HeapMeta::new(&options);
// We have no specific side metadata for copying. So just use the ones from generational.
let global_metadata_specs =
crate::plan::generational::new_generational_global_metadata_specs::<VM>();
pub fn new(args: CreateGeneralPlanArgs<VM>) -> Self {
let mut plan_args = CreateSpecificPlanArgs {
global_args: args,
constraints: &GENCOPY_CONSTRAINTS,
global_side_metadata_specs:
crate::plan::generational::new_generational_global_metadata_specs::<VM>(),
};

let copyspace0 = CopySpace::new(
"copyspace0",
plan_args.get_space_args("copyspace0", true, VMRequest::discontiguous()),
false,
true,
VMRequest::discontiguous(),
global_metadata_specs.clone(),
vm_map,
mmapper,
&mut heap,
);
let copyspace1 = CopySpace::new(
"copyspace1",
true,
plan_args.get_space_args("copyspace1", true, VMRequest::discontiguous()),
true,
VMRequest::discontiguous(),
global_metadata_specs.clone(),
vm_map,
mmapper,
&mut heap,
);

let res = GenCopy {
gen: Gen::new(
heap,
global_metadata_specs,
&GENCOPY_CONSTRAINTS,
vm_map,
mmapper,
options,
),
gen: Gen::new(plan_args),
hi: AtomicBool::new(false),
copyspace0,
copyspace1,
Expand Down
37 changes: 8 additions & 29 deletions src/plan/generational/global.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
use crate::plan::global::CommonPlan;
use crate::plan::global::CreateSpecificPlanArgs;
use crate::plan::ObjectQueue;
use crate::plan::Plan;
use crate::plan::PlanConstraints;
use crate::policy::copyspace::CopySpace;
use crate::policy::space::Space;
use crate::scheduler::*;
use crate::util::conversions;
use crate::util::copy::CopySemantics;
use crate::util::heap::layout::heap_layout::Mmapper;
use crate::util::heap::layout::heap_layout::VMMap;
use crate::util::heap::HeapMeta;
use crate::util::heap::VMRequest;
use crate::util::metadata::side_metadata::SideMetadataSanity;
use crate::util::metadata::side_metadata::SideMetadataSpec;
use crate::util::options::Options;
use crate::util::statistics::counter::EventCounter;
use crate::util::ObjectReference;
use crate::util::VMWorkerThread;
Expand Down Expand Up @@ -42,32 +37,16 @@ pub struct Gen<VM: VMBinding> {
}

impl<VM: VMBinding> Gen<VM> {
pub fn new(
mut heap: HeapMeta,
global_metadata_specs: Vec<SideMetadataSpec>,
constraints: &'static PlanConstraints,
vm_map: &'static VMMap,
mmapper: &'static Mmapper,
options: Arc<Options>,
) -> Self {
pub fn new(mut args: CreateSpecificPlanArgs<VM>) -> Self {
let nursery = CopySpace::new(
"nursery",
false,
args.get_space_args(
"nursery",
true,
VMRequest::fixed_extent(args.global_args.options.get_max_nursery(), false),
),
true,
VMRequest::fixed_extent(options.get_max_nursery(), false),
global_metadata_specs.clone(),
vm_map,
mmapper,
&mut heap,
);
let common = CommonPlan::new(
vm_map,
mmapper,
options,
heap,
constraints,
global_metadata_specs,
);
let common = CommonPlan::new(args);

let full_heap_gc_count = common.base.stats.new_event_counter("majorGC", true, true);

Expand Down
45 changes: 15 additions & 30 deletions src/plan/generational/immix/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use super::gc_work::GenImmixNurseryGCWorkContext;
use crate::plan::generational::global::Gen;
use crate::plan::global::BasePlan;
use crate::plan::global::CommonPlan;
use crate::plan::global::CreateGeneralPlanArgs;
use crate::plan::global::CreateSpecificPlanArgs;
use crate::plan::global::GcStatus;
use crate::plan::AllocationSemantics;
use crate::plan::Plan;
Expand All @@ -13,17 +15,13 @@ use crate::policy::space::Space;
use crate::scheduler::GCWorkScheduler;
use crate::util::alloc::allocators::AllocatorSelector;
use crate::util::copy::*;
use crate::util::heap::layout::heap_layout::Mmapper;
use crate::util::heap::layout::heap_layout::VMMap;
use crate::util::heap::HeapMeta;
use crate::util::options::Options;
use crate::util::heap::VMRequest;
use crate::util::VMWorkerThread;
use crate::vm::*;

use enum_map::EnumMap;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::Arc;

use mmtk_macros::PlanTraceObject;

Expand Down Expand Up @@ -216,34 +214,21 @@ impl<VM: VMBinding> Plan for GenImmix<VM> {
}

impl<VM: VMBinding> GenImmix<VM> {
pub fn new(
vm_map: &'static VMMap,
mmapper: &'static Mmapper,
options: Arc<Options>,
scheduler: Arc<GCWorkScheduler<VM>>,
) -> Self {
let mut heap = HeapMeta::new(&options);
// We have no specific side metadata for copying. So just use the ones from generational.
let global_metadata_specs =
crate::plan::generational::new_generational_global_metadata_specs::<VM>();
let immix_space = ImmixSpace::new(
pub fn new(args: CreateGeneralPlanArgs<VM>) -> Self {
let mut plan_args = CreateSpecificPlanArgs {
global_args: args,
constraints: &GENIMMIX_CONSTRAINTS,
global_side_metadata_specs:
crate::plan::generational::new_generational_global_metadata_specs::<VM>(),
};
let immix_space = ImmixSpace::new(plan_args.get_space_args(
"immix_mature",
vm_map,
mmapper,
&mut heap,
scheduler,
global_metadata_specs.clone(),
);
true,
VMRequest::discontiguous(),
));

let genimmix = GenImmix {
gen: Gen::new(
heap,
global_metadata_specs,
&GENIMMIX_CONSTRAINTS,
vm_map,
mmapper,
options,
),
gen: Gen::new(plan_args),
immix: immix_space,
last_gc_was_defrag: AtomicBool::new(false),
last_gc_was_full_heap: AtomicBool::new(false),
Expand Down
Loading

0 comments on commit 2300ce1

Please sign in to comment.