Description
It is a helpful debugging technique to assert that a slot holds a valid reference (the target has VO bit set) when scanning an object during GC. When VM::VMObjectModel::NEED_VO_BITS_DURING_TRACING
is set to true, mmtk-core will guarantee the VO bits are available during tracing. In copying GC, VO bit should be set for both from-space and to-space objects. But the current implementation sometimes sees to-space objects not having VO bit.
The cause is the order in which we set the forwarding bits and the VO bit. object_forwarding::forward_object
copies the object and immediately sets the forwarding bits to FORWARDED
. However, in ImmixSpace::trace_object_with_opportunistic_copy
, we set VO bits on the to-space object after forward_object
returns. So there is a moment where the forwarding bits are FORWARDED
, but the VO bit is not set on the to-space object. If another GC worker is attempting to forward the same object, it may observe the to-space object not having VO bit.
CopySpace::trace_object
has the same problem. It also sets the VO bits after object_forwarding::forward_object
returns.
Related issues:
- Destination not object when scanning iseq mmtk-ruby#106 is caused by this bug. The Ruby binding asserts that a field contains a valid reference by checking the VO bit. The Ruby binding sometimes visits the same field multiple times, and may see the field contain a reference to a to-space object, and that doesn't have VO bit due to the bug described here.
The obvious fix is letting object_forwarding::forward_object
set the VO bit. Currently all VO bit strategies (regardless whether ObjectModel::NEED_VO_BITS_DURING_TRACING
is true) need to set VO bits on to-space objects when forwarded, so it is reasonable to let object_forwarding::forward_object
unconditionally set the VO bit before setting forwarding bits when the "vo_bit" feature is enabled.