Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This PR enables transitively pinning (TP) objects from particular roots for Immix/StickyImmix #897

Merged
merged 32 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
51dcf50
Supporting moving immix (wip)
udesou Aug 3, 2023
f4cb338
Removing print to file statements
udesou Aug 9, 2023
6f691af
Merge branch 'master' into feature/rb-roots
udesou Aug 9, 2023
fa68296
Fixing incompatibilities from other plans to support immovable trace
udesou Aug 10, 2023
b1db978
Adding option for not moving during nursery GCs for sticky immix
udesou Aug 10, 2023
a349cc7
Minor.
udesou Aug 10, 2023
b1b31cf
Fixing formatting and tests
udesou Aug 10, 2023
17f3356
Merge branch 'master' into feature/rb-roots
udesou Aug 10, 2023
2089e0a
Fixing sanity GC
udesou Aug 10, 2023
a37fb56
Fix warning in tests
udesou Aug 10, 2023
325d61b
Applying cargo fmt
udesou Aug 10, 2023
b054fd2
Fixing docs code
udesou Aug 10, 2023
407047b
Renaming immovable => transitive pin (TP); Adding NodeRootsTrace to h…
udesou Aug 16, 2023
8921ed7
Run cargo fmt
udesou Aug 16, 2023
5a8c8a6
Merge remote-tracking branch 'origin/master' into feature/rb-roots
udesou Aug 23, 2023
48dde07
Turning off stress copying as default; fixing logic to prefer copy on…
udesou Aug 23, 2023
b414746
Fixed naming of node roots => pinned roots, and tp => tpinned/tpinning
udesou Aug 24, 2023
a33fc30
Apply suggestions from code review (comments, and renaming)
udesou Sep 4, 2023
7f96d15
Apply suggestions from code review (more comments)
udesou Sep 4, 2023
b23898b
GCWorkContext should always have 'static and Send
wks Aug 24, 2023
1b40a94
Addressing comments in the review
udesou Sep 5, 2023
0b3d358
Merge remote-tracking branch 'udesou/master' into feature/rb-roots
udesou Sep 5, 2023
57f298f
Applying cargo fmt
udesou Sep 5, 2023
5d2cab4
Fixing code inside conditional compilation
udesou Sep 5, 2023
73ab10a
Fixing tests
udesou Sep 5, 2023
4773952
Fixing formatting in macros.
udesou Sep 5, 2023
a26101f
Merge branch 'mmtk:master' into feature/rb-roots
udesou Sep 6, 2023
119a752
Merge branch 'master' into feature/rb-roots
udesou Sep 6, 2023
a91453f
Fixing bug when replacing MarkingProcessEdges in markcompact/global.rs
udesou Sep 6, 2023
d3fa977
Fixing import that failed cargo clippy
udesou Sep 6, 2023
f184064
Fix dependency replacing script
wks Sep 7, 2023
2e80e92
Merge branch 'master' into feature/rb-roots
udesou Sep 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ object_pinning = []
# Disable any object copying in Immix. This makes Immix a non-moving policy.
immix_non_moving = []

# Disable any object copying in nursery GC for Sticky Immix while allowing other kinds of copying.
# `immix_non_moving` disables all kinds of copying in Immix, so this feature is not needed
# if `immix_non_moving` is in use.
sticky_immix_non_moving_nursery = []


# Reduce block size for ImmixSpace. This mitigates fragmentation when defrag is disabled.
immix_smaller_block = []
# Zero the unmarked lines after a GC cycle in immix. This helps debug untraced objects.
Expand Down
24 changes: 16 additions & 8 deletions docs/userguide/src/tutorial/code/mygc_semispace/gc_work.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ANCHOR: imports
use super::global::MyGC;
use crate::scheduler::gc_work::*;
use crate::scheduler::{gc_work::*, WorkBucketStage};
use crate::vm::VMBinding;
use std::ops::{Deref, DerefMut};
// ANCHOR_END: imports
Expand All @@ -11,24 +11,26 @@ impl<VM: VMBinding> crate::scheduler::GCWorkContext for MyGCWorkContext<VM> {
type VM = VM;
type PlanType = MyGC<VM>;
type ProcessEdgesWorkType = SFTProcessEdges<Self::VM>;
type TPProcessEdges = UnsupportedProcessEdges<Self::VM>;
}
// ANCHOR_END: workcontext_sft

// ANCHOR: workcontext_plan
use crate::scheduler::gc_work::PlanProcessEdges;
use crate::policy::gc_work::DEFAULT_TRACE;
use crate::scheduler::gc_work::PlanProcessEdges;
pub struct MyGCWorkContext2<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for MyGCWorkContext2<VM> {
type VM = VM;
type PlanType = MyGC<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<Self::VM, MyGC<VM>, DEFAULT_TRACE>;
type TPProcessEdges = UnsupportedProcessEdges<Self::VM>;
}
// ANCHOR_END: workcontext_plan

use crate::util::ObjectReference;
use crate::policy::space::Space;
use crate::util::copy::CopySemantics;
use crate::util::ObjectReference;
use crate::MMTK;
use crate::policy::space::Space;

// ANCHOR: mygc_process_edges
pub struct MyGCProcessEdges<VM: VMBinding> {
Expand All @@ -38,12 +40,17 @@ pub struct MyGCProcessEdges<VM: VMBinding> {
// ANCHOR_END: mygc_process_edges

// ANCHOR: mygc_process_edges_impl
impl<VM:VMBinding> ProcessEdgesWork for MyGCProcessEdges<VM> {
impl<VM: VMBinding> ProcessEdgesWork for MyGCProcessEdges<VM> {
type VM = VM;
type ScanObjectsWorkType = ScanObjects<Self>;

fn new(edges: Vec<EdgeOf<Self>>, roots: bool, mmtk: &'static MMTK<VM>) -> Self {
let base = ProcessEdgesBase::new(edges, roots, mmtk);
fn new(
edges: Vec<EdgeOf<Self>>,
roots: bool,
mmtk: &'static MMTK<VM>,
bucket: WorkBucketStage,
) -> Self {
let base = ProcessEdgesBase::new(edges, roots, mmtk, bucket);
let plan = base.plan().downcast_ref::<MyGC<VM>>().unwrap();
Self { base, plan }
}
Expand Down Expand Up @@ -74,7 +81,7 @@ impl<VM:VMBinding> ProcessEdgesWork for MyGCProcessEdges<VM> {
}

fn create_scan_work(&self, nodes: Vec<ObjectReference>, roots: bool) -> ScanObjects<Self> {
ScanObjects::<Self>::new(nodes, false, roots)
ScanObjects::<Self>::new(nodes, false, roots, self.bucket)
}
}
// ANCHOR_END: mygc_process_edges_impl
Expand All @@ -100,5 +107,6 @@ impl<VM: VMBinding> crate::scheduler::GCWorkContext for MyGCWorkContext3<VM> {
type VM = VM;
type PlanType = MyGC<VM>;
type ProcessEdgesWorkType = MyGCProcessEdges<Self::VM>;
type TPProcessEdges = UnsupportedProcessEdges<Self::VM>;
}
// ANCHOR: workcontext_mygc
4 changes: 3 additions & 1 deletion src/plan/generational/copying/gc_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ use crate::plan::generational::gc_work::GenNurseryProcessEdges;
use crate::vm::*;

use crate::policy::gc_work::DEFAULT_TRACE;
use crate::scheduler::gc_work::PlanProcessEdges;
use crate::scheduler::gc_work::{PlanProcessEdges, UnsupportedProcessEdges};

pub struct GenCopyNurseryGCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for GenCopyNurseryGCWorkContext<VM> {
type VM = VM;
type PlanType = GenCopy<VM>;
type ProcessEdgesWorkType = GenNurseryProcessEdges<Self::VM, Self::PlanType>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}

pub struct GenCopyGCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for GenCopyGCWorkContext<VM> {
type VM = VM;
type PlanType = GenCopy<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<Self::VM, GenCopy<VM>, DEFAULT_TRACE>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}
21 changes: 15 additions & 6 deletions src/plan/generational/gc_work.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use atomic::Ordering;

use crate::plan::PlanTraceObject;
use crate::scheduler::{gc_work::*, GCWork, GCWorker};
use crate::scheduler::{gc_work::*, GCWork, GCWorker, WorkBucketStage};
use crate::util::ObjectReference;
use crate::vm::edge_shape::{Edge, MemorySlice};
use crate::vm::*;
Expand All @@ -25,8 +25,13 @@ impl<VM: VMBinding, P: GenerationalPlanExt<VM> + PlanTraceObject<VM>> ProcessEdg
type VM = VM;
type ScanObjectsWorkType = PlanScanObjects<Self, P>;

fn new(edges: Vec<EdgeOf<Self>>, roots: bool, mmtk: &'static MMTK<VM>) -> Self {
let base = ProcessEdgesBase::new(edges, roots, mmtk);
fn new(
edges: Vec<EdgeOf<Self>>,
roots: bool,
mmtk: &'static MMTK<VM>,
bucket: WorkBucketStage,
) -> Self {
let base = ProcessEdgesBase::new(edges, roots, mmtk, bucket);
let plan = base.plan().downcast_ref().unwrap();
Self { plan, base }
}
Expand All @@ -51,7 +56,7 @@ impl<VM: VMBinding, P: GenerationalPlanExt<VM> + PlanTraceObject<VM>> ProcessEdg
nodes: Vec<ObjectReference>,
roots: bool,
) -> Self::ScanObjectsWorkType {
PlanScanObjects::new(self.plan, nodes, false, roots)
PlanScanObjects::new(self.plan, nodes, false, roots, self.bucket)
}
}

Expand Down Expand Up @@ -111,7 +116,7 @@ impl<E: ProcessEdgesWork> GCWork<E::VM> for ProcessModBuf<E> {
// Scan objects in the modbuf and forward pointers
let modbuf = std::mem::take(&mut self.modbuf);
GCWork::do_work(
&mut ScanObjects::<E>::new(modbuf, false, false),
&mut ScanObjects::<E>::new(modbuf, false, false, WorkBucketStage::Closure),
worker,
mmtk,
)
Expand Down Expand Up @@ -154,7 +159,11 @@ impl<E: ProcessEdgesWork> GCWork<E::VM> for ProcessRegionModBuf<E> {
}
}
// Forward entries
GCWork::do_work(&mut E::new(edges, false, mmtk), worker, mmtk)
GCWork::do_work(
&mut E::new(edges, false, mmtk, WorkBucketStage::Closure),
worker,
mmtk,
)
}
}
}
3 changes: 3 additions & 0 deletions src/plan/generational/immix/gc_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use super::global::GenImmix;
use crate::plan::generational::gc_work::GenNurseryProcessEdges;
use crate::policy::gc_work::TraceKind;
use crate::scheduler::gc_work::PlanProcessEdges;
use crate::scheduler::gc_work::UnsupportedProcessEdges;
use crate::vm::VMBinding;

pub struct GenImmixNurseryGCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for GenImmixNurseryGCWorkContext<VM> {
type VM = VM;
type PlanType = GenImmix<VM>;
type ProcessEdgesWorkType = GenNurseryProcessEdges<VM, Self::PlanType>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}

pub(super) struct GenImmixMatureGCWorkContext<VM: VMBinding, const KIND: TraceKind>(
Expand All @@ -20,4 +22,5 @@ impl<VM: VMBinding, const KIND: TraceKind> crate::scheduler::GCWorkContext
type VM = VM;
type PlanType = GenImmix<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<VM, GenImmix<VM>, KIND>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}
2 changes: 2 additions & 0 deletions src/plan/immix/gc_work.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::global::Immix;
use crate::policy::gc_work::TraceKind;
use crate::policy::gc_work::TRACE_KIND_TRANSITIVE_PIN;
use crate::scheduler::gc_work::PlanProcessEdges;
use crate::vm::VMBinding;

Expand All @@ -12,4 +13,5 @@ impl<VM: VMBinding, const KIND: TraceKind> crate::scheduler::GCWorkContext
type VM = VM;
type PlanType = Immix<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<VM, Immix<VM>, KIND>;
type TPProcessEdges = PlanProcessEdges<VM, Immix<VM>, TRACE_KIND_TRANSITIVE_PIN>;
}
4 changes: 2 additions & 2 deletions src/plan/immix/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ impl<VM: VMBinding> Immix<VM> {
/// to schedule a full heap collection. A plan must call set_collection_kind and set_gc_status before this method.
pub(crate) fn schedule_immix_full_heap_collection<
PlanType: Plan<VM = VM>,
FastContext: 'static + GCWorkContext<VM = VM, PlanType = PlanType>,
DefragContext: 'static + GCWorkContext<VM = VM, PlanType = PlanType>,
FastContext: GCWorkContext<VM = VM, PlanType = PlanType>,
DefragContext: GCWorkContext<VM = VM, PlanType = PlanType>,
>(
plan: &'static DefragContext::PlanType,
immix_space: &ImmixSpace<VM>,
Expand Down
16 changes: 13 additions & 3 deletions src/plan/markcompact/gc_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ impl<VM: VMBinding> GCWork<VM> for UpdateReferences<VM> {
.get_and_clear_worker_live_bytes();

for mutator in VM::VMActivePlan::mutators() {
mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots]
.add(ScanMutatorRoots::<ForwardingProcessEdges<VM>>(mutator));
mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots].add(ScanMutatorRoots::<
MarkCompactForwardingGCWorkContext<VM>,
>(mutator));
}

mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots]
.add(ScanVMSpecificRoots::<ForwardingProcessEdges<VM>>::new());
.add(ScanVMSpecificRoots::<MarkCompactForwardingGCWorkContext<VM>>::new());
}
}

Expand Down Expand Up @@ -102,4 +103,13 @@ impl<VM: VMBinding> crate::scheduler::GCWorkContext for MarkCompactGCWorkContext
type VM = VM;
type PlanType = MarkCompact<VM>;
type ProcessEdgesWorkType = MarkingProcessEdges<VM>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}

pub struct MarkCompactForwardingGCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for MarkCompactForwardingGCWorkContext<VM> {
type VM = VM;
type PlanType = MarkCompact<VM>;
type ProcessEdgesWorkType = ForwardingProcessEdges<VM>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}
4 changes: 2 additions & 2 deletions src/plan/markcompact/global.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::gc_work::MarkCompactGCWorkContext;
use super::gc_work::{
CalculateForwardingAddress, Compact, ForwardingProcessEdges, MarkingProcessEdges,
UpdateReferences,
};
use super::gc_work::{MarkCompactForwardingGCWorkContext, MarkCompactGCWorkContext};
use crate::plan::global::CommonPlan;
use crate::plan::global::GcStatus;
use crate::plan::global::{BasePlan, CreateGeneralPlanArgs, CreateSpecificPlanArgs};
Expand Down Expand Up @@ -92,7 +92,7 @@ impl<VM: VMBinding> Plan for MarkCompact<VM> {

// Stop & scan mutators (mutator scanning can happen before STW)
scheduler.work_buckets[WorkBucketStage::Unconstrained]
.add(StopMutators::<MarkingProcessEdges<VM>>::new());
.add(StopMutators::<MarkCompactForwardingGCWorkContext<VM>>::new());

// Prepare global/collectors/mutators
scheduler.work_buckets[WorkBucketStage::Prepare]
Expand Down
1 change: 1 addition & 0 deletions src/plan/marksweep/gc_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ impl<VM: VMBinding> crate::scheduler::GCWorkContext for MSGCWorkContext<VM> {
type VM = VM;
type PlanType = MarkSweep<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<Self::VM, MarkSweep<VM>, DEFAULT_TRACE>;
type TPProcessEdges = PlanProcessEdges<Self::VM, MarkSweep<VM>, DEFAULT_TRACE>;
}
1 change: 1 addition & 0 deletions src/plan/pageprotect/gc_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ impl<VM: VMBinding> crate::scheduler::GCWorkContext for PPGCWorkContext<VM> {
type VM = VM;
type PlanType = PageProtect<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<Self::VM, PageProtect<VM>, DEFAULT_TRACE>;
type TPProcessEdges = PlanProcessEdges<Self::VM, PageProtect<VM>, DEFAULT_TRACE>;
}
3 changes: 2 additions & 1 deletion src/plan/semispace/gc_work.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use super::global::SemiSpace;
use crate::policy::gc_work::DEFAULT_TRACE;
use crate::scheduler::gc_work::PlanProcessEdges;
use crate::scheduler::gc_work::{PlanProcessEdges, UnsupportedProcessEdges};
use crate::vm::VMBinding;

pub struct SSGCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for SSGCWorkContext<VM> {
type VM = VM;
type PlanType = SemiSpace<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<Self::VM, SemiSpace<VM>, DEFAULT_TRACE>;
type TPProcessEdges = UnsupportedProcessEdges<VM>;
}
3 changes: 3 additions & 0 deletions src/plan/sticky/immix/gc_work.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::policy::gc_work::TraceKind;
use crate::policy::gc_work::TRACE_KIND_TRANSITIVE_PIN;
use crate::scheduler::gc_work::PlanProcessEdges;
use crate::{plan::generational::gc_work::GenNurseryProcessEdges, vm::VMBinding};

Expand All @@ -9,6 +10,7 @@ impl<VM: VMBinding> crate::scheduler::GCWorkContext for StickyImmixNurseryGCWork
type VM = VM;
type PlanType = StickyImmix<VM>;
type ProcessEdgesWorkType = GenNurseryProcessEdges<VM, Self::PlanType>;
type TPProcessEdges = GenNurseryProcessEdges<VM, Self::PlanType>;
}

pub struct StickyImmixMatureGCWorkContext<VM: VMBinding, const KIND: TraceKind>(
Expand All @@ -20,4 +22,5 @@ impl<VM: VMBinding, const KIND: TraceKind> crate::scheduler::GCWorkContext
type VM = VM;
type PlanType = StickyImmix<VM>;
type ProcessEdgesWorkType = PlanProcessEdges<VM, Self::PlanType, KIND>;
type TPProcessEdges = PlanProcessEdges<VM, Self::PlanType, TRACE_KIND_TRANSITIVE_PIN>;
}
8 changes: 5 additions & 3 deletions src/plan/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,24 @@ impl ObjectQueue for VectorQueue<ObjectReference> {
pub struct ObjectsClosure<'a, E: ProcessEdgesWork> {
buffer: VectorQueue<EdgeOf<E>>,
pub(crate) worker: &'a mut GCWorker<E::VM>,
bucket: WorkBucketStage,
}

impl<'a, E: ProcessEdgesWork> ObjectsClosure<'a, E> {
pub fn new(worker: &'a mut GCWorker<E::VM>) -> Self {
pub fn new(worker: &'a mut GCWorker<E::VM>, bucket: WorkBucketStage) -> Self {
Self {
buffer: VectorQueue::new(),
worker,
bucket,
}
}

fn flush(&mut self) {
let buf = self.buffer.take();
if !buf.is_empty() {
self.worker.add_work(
WorkBucketStage::Closure,
E::new(buf, false, self.worker.mmtk),
self.bucket,
E::new(buf, false, self.worker.mmtk, self.bucket),
);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/policy/copyspace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::plan::{ObjectQueue, VectorObjectQueue};
use crate::policy::copy_context::PolicyCopyContext;
use crate::policy::gc_work::TRACE_KIND_TRANSITIVE_PIN;
use crate::policy::sft::GCWorkerMutRef;
use crate::policy::sft::SFT;
use crate::policy::space::{CommonSpace, Space};
Expand Down Expand Up @@ -126,6 +127,10 @@ impl<VM: VMBinding> crate::policy::gc_work::PolicyTraceObject<VM> for CopySpace<
copy: Option<CopySemantics>,
worker: &mut GCWorker<VM>,
) -> ObjectReference {
debug_assert!(
KIND != TRACE_KIND_TRANSITIVE_PIN,
"Copyspace does not support transitive pin trace."
);
self.trace_object(queue, object, copy, worker)
}

Expand Down
1 change: 1 addition & 0 deletions src/policy/gc_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub(crate) type TraceKind = u8;

pub const DEFAULT_TRACE: u8 = u8::MAX;
pub const TRACE_KIND_TRANSITIVE_PIN: u8 = DEFAULT_TRACE - 1;

use crate::plan::ObjectQueue;
use crate::scheduler::GCWorker;
Expand Down
Loading
Loading