From fabb0b4234fce490bd1c594cb1f059a5ddedf473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Inf=C3=BChr?= Date: Sun, 17 Dec 2023 23:14:28 +0100 Subject: [PATCH] swiper: iterate full pages --- dora-runtime/src/gc.rs | 2 +- dora-runtime/src/gc/swiper.rs | 44 ++-------------------------- dora-runtime/src/gc/swiper/full.rs | 32 +++++++------------- dora-runtime/src/gc/swiper/old.rs | 6 ++++ dora-runtime/src/gc/swiper/verify.rs | 11 ++----- 5 files changed, 21 insertions(+), 74 deletions(-) diff --git a/dora-runtime/src/gc.rs b/dora-runtime/src/gc.rs index 786220f00..746a3edc2 100644 --- a/dora-runtime/src/gc.rs +++ b/dora-runtime/src/gc.rs @@ -599,7 +599,7 @@ pub fn fill_region(vm: &VM, start: Address, end: Address) { *start.offset(mem::ptr_width_usize()).to_mut_ptr::() = 0; *start.offset(Header::size() as usize).to_mut_ptr::() = length; - if cfg!(debug) { + if cfg!(debug_assertions) { for idx in 0..length { *start .offset(Header::size() as usize) diff --git a/dora-runtime/src/gc/swiper.rs b/dora-runtime/src/gc/swiper.rs index 20adae5b2..ddd1e9cad 100644 --- a/dora-runtime/src/gc/swiper.rs +++ b/dora-runtime/src/gc/swiper.rs @@ -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}; @@ -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(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 { diff --git a/dora-runtime/src/gc/swiper/full.rs b/dora-runtime/src/gc/swiper/full.rs index 926e5d86e..92bba7b69 100644 --- a/dora-runtime/src/gc/swiper/full.rs +++ b/dora-runtime/src/gc/swiper/full.rs @@ -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; @@ -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 } }); @@ -362,38 +359,29 @@ impl<'a> FullCollector<'a> { fn walk_old_and_young_and_skip_garbage(&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); }); } diff --git a/dora-runtime/src/gc/swiper/old.rs b/dora-runtime/src/gc/swiper/old.rs index c8a6d8061..5a8240e7b 100644 --- a/dora-runtime/src/gc/swiper/old.rs +++ b/dora-runtime/src/gc/swiper/old.rs @@ -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); } @@ -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 diff --git a/dora-runtime/src/gc/swiper/verify.rs b/dora-runtime/src/gc/swiper/verify.rs index 693ab74ad..29addcf2c 100644 --- a/dora-runtime/src/gc/swiper/verify.rs +++ b/dora-runtime/src/gc/swiper/verify.rs @@ -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;