Skip to content

Commit

Permalink
swiper: iterate full pages
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Dec 17, 2023
1 parent 61b9ccc commit fabb0b4
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 74 deletions.
2 changes: 1 addition & 1 deletion dora-runtime/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ pub fn fill_region(vm: &VM, start: Address, end: Address) {
*start.offset(mem::ptr_width_usize()).to_mut_ptr::<usize>() = 0;
*start.offset(Header::size() as usize).to_mut_ptr::<usize>() = length;

if cfg!(debug) {
if cfg!(debug_assertions) {
for idx in 0..length {
*start
.offset(Header::size() as usize)
Expand Down
44 changes: 2 additions & 42 deletions dora-runtime/src/gc/swiper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::gc::swiper::young::YoungGen;
use crate::gc::tlab;
use crate::gc::Collector;
use crate::gc::GcReason;
use crate::gc::{align_page_up, fill_region, formatted_size, Address, Region, K};
use crate::gc::{align_page_up, formatted_size, Address, Region, K};
use crate::mem;
use crate::object::Obj;
use crate::os::{self, MemoryPermission, Reservation};
Expand Down Expand Up @@ -634,48 +634,8 @@ where
fct(object, scan, object_size);
scan = scan.offset(object_size);
}
}

const MIN_OBJECTS_TO_SKIP: usize = 4;

pub fn walk_region_and_skip_garbage<F>(vm: &VM, region: Region, mut fct: F)
where
F: FnMut(&mut Obj, Address, usize) -> bool,
{
let mut scan = region.start;
let mut garbage_start = Address::null();
let mut garbage_objects = 0;

while scan < region.end {
let object = scan.to_mut_obj();

if object.header().vtblptr().is_null() {
scan = scan.add_ptr(1);
continue;
}

let object_size = object.size();
let marked = fct(object, scan, object_size);
scan = scan.offset(object_size);

if marked {
if garbage_objects >= MIN_OBJECTS_TO_SKIP {
fill_region(vm, garbage_start, object.address());
}

garbage_objects = 0;
} else {
if garbage_objects == 0 {
garbage_start = object.address();
}

garbage_objects += 1;
}
}

if garbage_objects >= MIN_OBJECTS_TO_SKIP {
fill_region(vm, garbage_start, region.end);
}
assert_eq!(scan, region.end);
}

pub trait CommonOldGen {
Expand Down
32 changes: 10 additions & 22 deletions dora-runtime/src/gc/swiper/full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::gc::swiper::crossing::CrossingMap;
use crate::gc::swiper::large::LargeSpace;
use crate::gc::swiper::old::{OldGen, OldGenProtected, Page};
use crate::gc::swiper::young::YoungGen;
use crate::gc::swiper::{forward_full, walk_region, walk_region_and_skip_garbage};
use crate::gc::swiper::{forward_full, walk_region};
use crate::gc::{fill_region, iterate_strong_roots, iterate_weak_roots, marking, Slot};
use crate::gc::{Address, GcReason, Region};
use crate::object::Obj;
Expand Down Expand Up @@ -194,9 +194,6 @@ impl<'a> FullCollector<'a> {
if object.header().is_marked_non_atomic() {
let fwd = full.allocate(object_size);
object.header_mut().set_fwdptr_non_atomic(fwd);
true
} else {
false
}
});

Expand Down Expand Up @@ -362,38 +359,29 @@ impl<'a> FullCollector<'a> {

fn walk_old_and_young_and_skip_garbage<F>(&mut self, mut fct: F)
where
F: FnMut(&mut FullCollector, &mut Obj, Address, usize) -> bool,
F: FnMut(&mut FullCollector, &mut Obj, Address, usize),
{
let vm = self.vm;

let pages = self.old_protected.pages.clone();
let mut last = self.old.total_start();

for page in pages {
assert_eq!(last, page.start());

let region = if page.end() == self.old_protected.current_limit {
Region::new(page.start(), self.old_protected.top)
} else {
page.area()
};

walk_region_and_skip_garbage(vm, region, |obj, addr, size| fct(self, obj, addr, size));
last = region.end();
walk_region(page.area(), |obj, addr, size| {
fct(self, obj, addr, size);
});
last = page.end();
}

assert_eq!(self.old_protected.active_region().end(), last);

// This is a bit strange at first: from-space might not be empty,
// after too many survivors in the minor GC of the young gen.
let used_region = self.young.from_active();
walk_region_and_skip_garbage(vm, used_region, |obj, addr, size| {
fct(self, obj, addr, size)
walk_region(used_region, |obj, addr, size| {
fct(self, obj, addr, size);
});

let used_region = self.young.to_active();
walk_region_and_skip_garbage(vm, used_region, |obj, addr, size| {
fct(self, obj, addr, size)
walk_region(used_region, |obj, addr, size| {
fct(self, obj, addr, size);
});
}

Expand Down
6 changes: 6 additions & 0 deletions dora-runtime/src/gc/swiper/old.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ impl GenerationAllocator for OldGen {
let mut protected = self.protected.lock();

if let Some(address) = protected.raw_alloc(size) {
fill_region(get_vm(), protected.top, protected.current_limit);
self.update_crossing(protected.top, protected.current_limit);
return Some(address);
}

Expand All @@ -122,6 +124,10 @@ impl GenerationAllocator for OldGen {
let result = protected.raw_alloc(size);
assert!(result.is_some());

// Make rest of page iterable.
fill_region(get_vm(), protected.top, protected.current_limit);
self.update_crossing(protected.top, protected.current_limit);

result
} else {
None
Expand Down
11 changes: 2 additions & 9 deletions dora-runtime/src/gc/swiper/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,8 @@ impl<'a> Verifier<'a> {

for page in pages {
assert_eq!(last, page.start());

let region = if page.end() == self.old_protected.current_limit {
Region::new(page.start(), self.old_protected.top)
} else {
page.area()
};

self.verify_objects(region, "old gen");
last = region.end();
self.verify_objects(page.area(), "old gen");
last = page.end();
}

self.in_old = false;
Expand Down

0 comments on commit fabb0b4

Please sign in to comment.