Skip to content

Commit 2d7b569

Browse files
authored
Clear all side forwarding bits (#974)
This reverts an optimization which was intended to reduce the number of side forwarding bits cleared for ImmixSpace by clearing the forwarding bits metadata of defrag sources, only. This approach does not work for StickyImmix because it may move young objects, which is not "defrag". Now ImmixSpace clears the on-the-side forwarding bits for all chunks just like how it clears the on-the-side marking bits. This PR prefers correctness over performance, and may degrade the performance of VMs that use on-the-side forwarding bits. Currently it only affects the Ruby binding, but we plan to let the Ruby binding use in-header forwarding states, too. The performance of VMs that use in-header forwarding bits is not affected by this PR. Fixes: #972
1 parent 0328b05 commit 2d7b569

File tree

1 file changed

+6
-25
lines changed

1 file changed

+6
-25
lines changed

src/policy/immix/immixspace.rs

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ impl<VM: VMBinding> SFT for ImmixSpace<VM> {
8686
}
8787

8888
fn get_forwarded_object(&self, object: ObjectReference) -> Option<ObjectReference> {
89-
if !Block::containing::<VM>(object).is_defrag_source() {
89+
// If we never move objects, look no further.
90+
if super::NEVER_MOVE_OBJECTS {
9091
return None;
9192
}
9293

@@ -108,17 +109,6 @@ impl<VM: VMBinding> SFT for ImmixSpace<VM> {
108109
return false;
109110
}
110111

111-
// If the forwarding bits are on the side,
112-
if VM::VMObjectModel::LOCAL_FORWARDING_BITS_SPEC.is_on_side() {
113-
// we need to ensure `object` is in a defrag source
114-
// because `PrepareBlockState` does not clear forwarding bits
115-
// for non-defrag-source blocks.
116-
if !Block::containing::<VM>(object).is_defrag_source() {
117-
// Objects not in defrag sources cannot be forwarded.
118-
return false;
119-
}
120-
}
121-
122112
// If the object is forwarded, it is live, too.
123113
ForwardingWord::is_forwarded::<VM>(object)
124114
}
@@ -843,6 +833,10 @@ impl<VM: VMBinding> PrepareBlockState<VM> {
843833
unimplemented!("We cannot bulk zero unlogged bit.")
844834
}
845835
}
836+
// If the forwarding bits are on the side, we need to clear them, too.
837+
if let MetadataSpec::OnSide(side) = *VM::VMObjectModel::LOCAL_FORWARDING_BITS_SPEC {
838+
side.bzero_metadata(self.chunk.start(), Chunk::BYTES);
839+
}
846840
}
847841
}
848842

@@ -876,19 +870,6 @@ impl<VM: VMBinding> GCWork<VM> for PrepareBlockState<VM> {
876870
block.set_state(BlockState::Unmarked);
877871
debug_assert!(!block.get_state().is_reusable());
878872
debug_assert_ne!(block.get_state(), BlockState::Marked);
879-
// Clear forwarding bits if necessary.
880-
if is_defrag_source {
881-
// Note that `ImmixSpace::is_live` depends on the fact that we only clear side
882-
// forwarding bits for defrag sources. If we change the code here, we need to
883-
// make sure `ImmixSpace::is_live` is fixed, too.
884-
if let MetadataSpec::OnSide(side) = *VM::VMObjectModel::LOCAL_FORWARDING_BITS_SPEC {
885-
// Clear on-the-side forwarding bits.
886-
side.bzero_metadata(block.start(), Block::BYTES);
887-
}
888-
}
889-
// NOTE: We don't need to reset the forwarding pointer metadata because it is meaningless
890-
// until the forwarding bits are also set, at which time we also write the forwarding
891-
// pointer.
892873
}
893874
}
894875
}

0 commit comments

Comments
 (0)