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 afterobject_forwarding::forward_object returns.
Related issues:
https://github.com/mmtk/mmtk-ruby/issues/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.
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 toFORWARDED
. However, inImmixSpace::trace_object_with_opportunistic_copy
, we set VO bits on the to-space object afterforward_object
returns. So there is a moment where the forwarding bits areFORWARDED
, 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 afterobject_forwarding::forward_object
returns.Related issues:
The obvious fix is letting
object_forwarding::forward_object
set the VO bit. Currently all VO bit strategies (regardless whetherObjectModel::NEED_VO_BITS_DURING_TRACING
is true) need to set VO bits on to-space objects when forwarded, so it is reasonable to letobject_forwarding::forward_object
unconditionally set the VO bit before setting forwarding bits when the "vo_bit" feature is enabled.