Skip to content

Commit

Permalink
Fix stale unlog bits for LOS and MarkSweepSpace objects
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
k-sareen committed Jul 18, 2024
1 parent 059723f commit 8f6fcd8
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/policy/largeobjectspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ impl<VM: VMBinding> LargeObjectSpace<VM> {
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::<VM>(object, Ordering::SeqCst);
}
Expand All @@ -228,6 +230,10 @@ impl<VM: VMBinding> LargeObjectSpace<VM> {
let sweep = |object: ObjectReference| {
#[cfg(feature = "vo_bit")]
crate::util::metadata::vo_bit::unset_vo_bit::<VM>(object);
if self.common.needs_log_bit {
VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC
.clear::<VM>(object, Ordering::SeqCst);
}
self.pr
.release_pages(get_super_page(object.to_object_start::<VM>()));
};
Expand Down
14 changes: 12 additions & 2 deletions src/policy/marksweepspace/native_ms/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl<VM: VMBinding> MarkSweepSpace<VM> {
block.set_state(BlockState::Marked);
queue.enqueue(object);
if self.common.needs_log_bit {
VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC.mark_as_unlogged::<VM>(object, Ordering::SeqCst);
VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC.mark_byte_as_unlogged::<VM>(object, Ordering::SeqCst);
}
}
object
Expand All @@ -337,14 +337,24 @@ impl<VM: VMBinding> MarkSweepSpace<VM> {
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);
}
} 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) {
Expand Down
5 changes: 5 additions & 0 deletions src/util/metadata/log_bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<VM: VMBinding>(&self, object: ObjectReference, order: Ordering) {
self.store_atomic::<VM, u8>(object, 0, None, order)
}

/// Mark the log bit as unlogged (1 means unlogged)
pub fn mark_as_unlogged<VM: VMBinding>(&self, object: ObjectReference, order: Ordering) {
self.store_atomic::<VM, u8>(object, 1, None, order)
Expand Down

0 comments on commit 8f6fcd8

Please sign in to comment.