From 8f6fcd8e8de8ac332577f4cc44af1c9cb8b0b065 Mon Sep 17 00:00:00 2001 From: Kunal Sareen Date: Thu, 18 Jul 2024 04:18:05 +0000 Subject: [PATCH] Fix stale unlog bits for LOS and MarkSweepSpace objects We now: - Clear the unlog bits for dead LOS objects - Bulk clear the unlog bits for MarkSweepSpace for full heap GC - Set the unlog bits for LOS and MarkSweepSpace objects during trace object This is because we want to ensure the unlog bits are only set for objects that are alive. We do not reset the unlogs bits inside the `ProcessModBuf` work packet because we do not know what objects are alive at that moment in time. --- src/policy/largeobjectspace.rs | 8 +++++++- src/policy/marksweepspace/native_ms/global.rs | 14 ++++++++++++-- src/util/metadata/log_bit.rs | 5 +++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/policy/largeobjectspace.rs b/src/policy/largeobjectspace.rs index 64a13c8f37..f5305d0a09 100644 --- a/src/policy/largeobjectspace.rs +++ b/src/policy/largeobjectspace.rs @@ -209,7 +209,9 @@ impl LargeObjectSpace { trace!("LOS object {} is being marked now", object); self.treadmill.copy(object, nursery_object); // We just moved the object out of the logical nursery, mark it as unlogged. - if nursery_object && self.common.needs_log_bit { + // We also set the unlog bit for mature objects to ensure that + // any modifications to them are logged + if self.common.needs_log_bit { VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC .mark_as_unlogged::(object, Ordering::SeqCst); } @@ -228,6 +230,10 @@ impl LargeObjectSpace { let sweep = |object: ObjectReference| { #[cfg(feature = "vo_bit")] crate::util::metadata::vo_bit::unset_vo_bit::(object); + if self.common.needs_log_bit { + VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC + .clear::(object, Ordering::SeqCst); + } self.pr .release_pages(get_super_page(object.to_object_start::())); }; diff --git a/src/policy/marksweepspace/native_ms/global.rs b/src/policy/marksweepspace/native_ms/global.rs index 81cc10fdf5..7db92cf73c 100644 --- a/src/policy/marksweepspace/native_ms/global.rs +++ b/src/policy/marksweepspace/native_ms/global.rs @@ -321,7 +321,7 @@ impl MarkSweepSpace { block.set_state(BlockState::Marked); queue.enqueue(object); if self.common.needs_log_bit { - VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC.mark_as_unlogged::(object, Ordering::SeqCst); + VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC.mark_byte_as_unlogged::(object, Ordering::SeqCst); } } object @@ -337,7 +337,7 @@ impl MarkSweepSpace { Block::NEXT_BLOCK_TABLE } - pub fn prepare(&mut self, _full_heap: bool) { + pub fn prepare(&mut self, full_heap: bool) { if let MetadataSpec::OnSide(side) = *VM::VMObjectModel::LOCAL_MARK_BIT_SPEC { for chunk in self.chunk_map.all_chunks() { side.bzero_metadata(chunk.start(), Chunk::BYTES); @@ -345,6 +345,16 @@ impl MarkSweepSpace { } else { unimplemented!("in header mark bit is not supported"); } + + if self.common.needs_log_bit && full_heap { + if let MetadataSpec::OnSide(side) = *VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC { + for chunk in self.chunk_map.all_chunks() { + side.bzero_metadata(chunk.start(), Chunk::BYTES); + } + } else { + unimplemented!("in header log bit is not supported"); + } + } } pub fn release(&mut self) { diff --git a/src/util/metadata/log_bit.rs b/src/util/metadata/log_bit.rs index 6b387041fb..d29ca6ebf2 100644 --- a/src/util/metadata/log_bit.rs +++ b/src/util/metadata/log_bit.rs @@ -6,6 +6,11 @@ use std::sync::atomic::Ordering; use super::MetadataSpec; impl VMGlobalLogBitSpec { + /// Clear the unlog bit to log object (0 means logged) + pub fn clear(&self, object: ObjectReference, order: Ordering) { + self.store_atomic::(object, 0, None, order) + } + /// Mark the log bit as unlogged (1 means unlogged) pub fn mark_as_unlogged(&self, object: ObjectReference, order: Ordering) { self.store_atomic::(object, 1, None, order)