Closed wks closed 7 months ago
Oh did I not upstream my fix for this? I encountered this in my ART port and fixed it. Unfortunately, it was not a complete fix as I didn't properly implement transitively pinning roots.
EDIT: Discussion here
Closed with #1108
In default setting, if a nursery GC is triggered in StickyImmix, and an object is pointed by a pinning root (transitive or not), it will still attempt to copy the object. This contradicts with the contract of "pinning roots".
Details:
The VM binding can deliver lists of pinning roots via
RootsWorkFactory::create_process_pinning_roots_work(nodes: Vec<ObjectReference>)
. The object graph edges pointing from roots (stack slots or global variables) to heap objects are represented asObjectReference
of the heap objects. That's sufficient because the objects won't be moved, therefore there is no need to update the stack slots or global variables.Here,
E
andI
are type parameters.E
is used for non-pinning edges, whileI
is used for pinning edges. In this case,ProcessRootNode::<VM, I, E>::new(nodes, ...
tells the newly createdProcessRootNode
work packet that the edges represented by thenodes
vector shall be traced byI
, and their transitively reached edges shall be traced byE
.For StickyImmix, the
I
andE
come from theTPProcessEdges
andProcessEdgesWorkType
members ofStickyImmixNurseryGCWorkContext
:Here
ProcessEdgesWorkType
andTPProcessEdges
are identical. The same work packet will be used for tracing both pinning and movable roots.GenNurseryProcessEdges::trace_object
will eventually callStickyImmix::trace_object_nursery
.By default, the constant
PREFER_COPY_ON_NURSERY_GC
istrue
, unless disabled by the "immix_non_moving" or "sticky_immix_non_moving_nursery" Cargo features. This means even ifobject
is from theProcessRootNode
work packet, it will still callimmix_space.trace_object_with_opportunistic_copy
, and that'll copy the object.Desired behavior
Anyway, objects pointed by pinning roots should never be moved. There are two ways to realize that in StickyImmix
The former can be achieved by setting the cargo feature "sticky_immix_non_moving_nursery". It is an easy workaround.
The latter may need some effort to implement.
StickyImmixNurseryGCWorkContext
needs to have two different type members forProcessEdgesWorkType
andTPProcessEdges
. Currently they are bothGenNurseryProcessEdges
.We may need to add a
KIND: TraceKind
type parameter toGenNurseryProcessEdges
, just likePlanProcessEdges<VM, Self::PlanType, KIND>
. TheKIND
argument can be used to distinguish between non-moving and moving work packets.Then
GenerationalPlanExt::trace_object_nursery
will also need aKIND: TraceKind
type parameter, or simply apinning: bool
value parameter. This will either (1) overridePREFER_COPY_ON_NURSERY_GC
so that it will calltrace_object_without_moving
instead, or (2) raise an assertion error, showing that there cannot be pinning roots whenPREFER_COPY_ON_NURSERY_GC
is true.