Proposal: Edge::update
, a single method to read-modify-write a slot (Edge
)
#1033
Labels
P-normal
Priority: Normal.
Note: Ruby currently doesn't require this change in order to work with slot (Edge) enqueuing. But V8 will need this change to efficiently forward references while preserving tags.
Proposal
I propose a new method for the
Edge
trait:Edge::update
.The semantics of
Edge::update
is:updater
.Some(new_object)
, update the slot so that it holds a reference tonew_object
.None
, do nothing.The
updater
is usually implemented byProcessEdgesWork::process_edge
to calltrace_object
and forward the slot.Rationale
Supporting tagged union of references and values
#626 described the need to support slots that hold non-ref values in addition to null (such as tagged values including small integers). By letting
Edge::update
decide whether to call theupdater
, the VM binding will have a chance to decode the tagged pointer, and choose not to call theupdater
(which callstrace_object
) if the slot holds a small integer or special non-reference values such astrue
,false
,nil
, etc.Supporting object references with tags.
Ruby never store object references together with tags. If a slot holds an object reference, its last three bits are zero, making the whole word a valid object reference.
If a VM stores object reference together with a tag, then the VM needs to preserve the tag while updating the reference.
Edge::update
allows the VM binding to preserve the tag during the call.If the
Edge
trait only has theload
andstore
, it will be sub-optimal. Theload()
method can remove the tag and give mmtk-core only the object reference. But thestore()
method will have to load from the slot again to retrieve the tag.Supporting slots with an offset
Similar to slots with a tag, the
update
method can re-apply the offset when storing. However, unlike references with tags, because the offset is usually known when scanning the object, it does not need to load from the slot again even if we are usingload()
andstore()
directly.When do we need it?
The
load()
andstore()
method is currently enough to support Ruby.V8 may have a problem because according to https://v8.dev/blog/pointer-compression, if a slot holds a reference, the lowest bit will be 1, and the second lowest bit will indicate whether the reference is strong or weak. Currently the
v8-support
branch ofmmtk/mmtk-core
is hacked so thatProcessEdgesWork::process_edge
remvoes the tag before callingtrace_object
. This makes themmtk-core
specific to v8. See:mmtk-core/src/scheduler/gc_work.rs
Lines 459 to 469 in dc62d10
The text was updated successfully, but these errors were encountered: