Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e6afb63
init commit
tianleq Sep 24, 2021
91a26a8
implement single-threaded lisp2 mark-compact
tianleq Oct 1, 2021
0f88032
fix missing TLAB bump allocator reset
tianleq Oct 6, 2021
6916306
fix missing reset cursor
tianleq Oct 6, 2021
8df62b6
initial clean up
tianleq Oct 7, 2021
9daceae
remove dependency on global alloc bit feature
tianleq Oct 7, 2021
da9ff70
fix 1. infinite gc loop due to incorrect page accounting
tianleq Oct 8, 2021
8e49469
fix extra header calculation
tianleq Oct 11, 2021
ecad445
get upstream changes
tianleq Oct 11, 2021
0d3ed9a
bring upstream changes and fixes
tianleq Oct 12, 2021
5d67c70
bring upstream changes and fixes
tianleq Oct 12, 2021
7e3b029
implement fast path allocation
tianleq Oct 15, 2021
f1e2784
fix object alignment
tianleq Oct 18, 2021
7fc9162
bring upstream changes
tianleq Oct 19, 2021
f46449c
fix duplicate edges in the second round of tracing
tianleq Oct 29, 2021
45cc071
add new allocator semantics(bump pointer with global alloc bit enabled)
tianleq Nov 2, 2021
0c7960c
clean up
tianleq Nov 3, 2021
eb4110c
clean up
tianleq Nov 4, 2021
10b134d
add missing implementation in dummyvm
tianleq Nov 4, 2021
92dd28c
fix failed tests
tianleq Nov 4, 2021
c88f8fc
fix style issue
tianleq Nov 4, 2021
963d02d
rollback changes
tianleq Nov 4, 2021
0b462ff
clean up
tianleq Nov 5, 2021
4c0e8cb
backup
tianleq Nov 8, 2021
e181e7b
implement the markcompact allocator
tianleq Nov 8, 2021
07bd00f
clean up
tianleq Nov 9, 2021
139a47a
use copy_to api
tianleq Nov 9, 2021
c188a2a
fix crash on mutator iteration
tianleq Nov 10, 2021
2785837
remove object_alignment()
tianleq Nov 10, 2021
62b44b6
clean up
tianleq Nov 10, 2021
c6e57a2
clean up
tianleq Nov 10, 2021
27c18dd
add finalization to markcompact
tianleq Nov 11, 2021
e0c9ba9
remove BumpPointerAllocBit
tianleq Nov 11, 2021
46c1cd2
clean up
tianleq Nov 12, 2021
d30bce0
remove unused code
tianleq Nov 25, 2021
28f13ed
clean up
tianleq Nov 25, 2021
bc3babb
Merge branch 'master' into mark-compact
tianleq Nov 25, 2021
fdfb88d
merge upstream changes
tianleq Nov 25, 2021
60c5c68
merge upstream updates of scanned stack
tianleq Nov 25, 2021
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 src/plan/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ pub fn create_mutator<VM: VMBinding>(
PlanSelector::PageProtect => {
crate::plan::pageprotect::mutator::create_pp_mutator(tls, &*mmtk.plan)
}
PlanSelector::MarkCompact => {
crate::plan::markcompact::mutator::create_markcompact_mutator(tls, &*mmtk.plan)
}
})
}

Expand Down Expand Up @@ -165,6 +168,9 @@ pub fn create_plan<VM: VMBinding>(
PlanSelector::PageProtect => Box::new(crate::plan::pageprotect::PageProtect::new(
vm_map, mmapper, options,
)),
PlanSelector::MarkCompact => Box::new(crate::plan::markcompact::MarkCompact::new(
vm_map, mmapper, options,
)),
}
}

Expand Down
197 changes: 197 additions & 0 deletions src/plan/markcompact/gc_work.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use super::global::MarkCompact;
use crate::plan::global::NoCopy;
use crate::policy::markcompactspace::MarkCompactSpace;
use crate::policy::space::Space;
use crate::scheduler::gc_work::*;
use crate::scheduler::GCWork;
use crate::scheduler::GCWorker;
use crate::scheduler::WorkBucketStage;
use crate::util::{Address, ObjectReference};
use crate::vm::ActivePlan;
use crate::vm::Scanning;
use crate::vm::VMBinding;
use crate::MMTK;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

/// iterate through the heap and calculate the new location of live objects
pub struct CalculateForwardingAddress<VM: VMBinding> {
mc_space: &'static MarkCompactSpace<VM>,
}

impl<VM: VMBinding> GCWork<VM> for CalculateForwardingAddress<VM> {
#[inline]
fn do_work(&mut self, _worker: &mut GCWorker<VM>, _mmtk: &'static MMTK<VM>) {
self.mc_space.calculate_forwarding_pointer();
}
}

impl<VM: VMBinding> CalculateForwardingAddress<VM> {
pub fn new(mc_space: &'static MarkCompactSpace<VM>) -> Self {
Self { mc_space }
}
}

/// create another round of root scanning work packets
/// to update object references
pub struct UpdateReferences<VM: VMBinding> {
p: PhantomData<VM>,
}

impl<VM: VMBinding> GCWork<VM> for UpdateReferences<VM> {
#[inline]
fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
// The following needs to be done right before the second round of root scanning
VM::VMScanning::prepare_for_roots_re_scanning();
mmtk.plan.base().prepare_for_stack_scanning();
#[cfg(feature = "extreme_assertions")]
crate::util::edge_logger::reset();

// TODO investigate why the following will create duplicate edges
// scheduler.work_buckets[WorkBucketStage::RefForwarding]
// .add(ScanStackRoots::<ForwardingProcessEdges<VM>>::new());
for mutator in VM::VMActivePlan::mutators() {
mmtk.scheduler.work_buckets[WorkBucketStage::RefForwarding]
.add(ScanStackRoot::<ForwardingProcessEdges<VM>>(mutator));
}

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

impl<VM: VMBinding> UpdateReferences<VM> {
pub fn new() -> Self {
Self { p: PhantomData }
}
}

/// compact live objects based on forwarding pointers calculated before
pub struct Compact<VM: VMBinding> {
mc_space: &'static MarkCompactSpace<VM>,
}

impl<VM: VMBinding> GCWork<VM> for Compact<VM> {
#[inline]
fn do_work(&mut self, _worker: &mut GCWorker<VM>, _mmtk: &'static MMTK<VM>) {
self.mc_space.compact();
}
}

impl<VM: VMBinding> Compact<VM> {
pub fn new(mc_space: &'static MarkCompactSpace<VM>) -> Self {
Self { mc_space }
}
}

// Transitive closure to mark live objects
pub struct MarkingProcessEdges<VM: VMBinding> {
plan: &'static MarkCompact<VM>,
base: ProcessEdgesBase<MarkingProcessEdges<VM>>,
}

impl<VM: VMBinding> MarkingProcessEdges<VM> {
fn markcompact(&self) -> &'static MarkCompact<VM> {
self.plan
}
}

impl<VM: VMBinding> ProcessEdgesWork for MarkingProcessEdges<VM> {
type VM = VM;
fn new(edges: Vec<Address>, roots: bool, mmtk: &'static MMTK<VM>) -> Self {
let base = ProcessEdgesBase::new(edges, roots, mmtk);
let plan = base.plan().downcast_ref::<MarkCompact<VM>>().unwrap();
Self { base, plan }
}

#[inline]
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
if object.is_null() {
return object;
}
if self.markcompact().mc_space().in_space(object) {
self.markcompact()
.mc_space()
.trace_mark_object::<Self>(self, object)
} else {
self.markcompact()
.common
.trace_object::<Self, NoCopy<VM>>(self, object)
}
}
}

impl<VM: VMBinding> Deref for MarkingProcessEdges<VM> {
type Target = ProcessEdgesBase<Self>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.base
}
}

impl<VM: VMBinding> DerefMut for MarkingProcessEdges<VM> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}

/// Transitive closure to update object references
pub struct ForwardingProcessEdges<VM: VMBinding> {
plan: &'static MarkCompact<VM>,
base: ProcessEdgesBase<ForwardingProcessEdges<VM>>,
}

impl<VM: VMBinding> ForwardingProcessEdges<VM> {
fn markcompact(&self) -> &'static MarkCompact<VM> {
self.plan
}
}

impl<VM: VMBinding> ProcessEdgesWork for ForwardingProcessEdges<VM> {
type VM = VM;
fn new(edges: Vec<Address>, roots: bool, mmtk: &'static MMTK<VM>) -> Self {
let base = ProcessEdgesBase::new(edges, roots, mmtk);
let plan = base.plan().downcast_ref::<MarkCompact<VM>>().unwrap();
Self { base, plan }
}

#[inline]
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
if object.is_null() {
return object;
}
if self.markcompact().mc_space().in_space(object) {
self.markcompact()
.mc_space()
.trace_forward_object::<Self>(self, object)
} else {
self.markcompact()
.common
.trace_object::<Self, NoCopy<VM>>(self, object)
}
}
}

impl<VM: VMBinding> Deref for ForwardingProcessEdges<VM> {
type Target = ProcessEdgesBase<Self>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.base
}
}

impl<VM: VMBinding> DerefMut for ForwardingProcessEdges<VM> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}

pub struct MarkCompactGCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
impl<VM: VMBinding> crate::scheduler::GCWorkContext for MarkCompactGCWorkContext<VM> {
type VM = VM;
type PlanType = MarkCompact<VM>;
type CopyContextType = NoCopy<VM>;
type ProcessEdgesWorkType = MarkingProcessEdges<VM>;
}
Loading