Separation of immovability and immortality in `@uvm.native.pin` instruction
Problem Description
Currently @uvm.native.pin
instruction bestows both immovability (not able to move) and immortality (kept alive) on the pinned object. However some times we might only want an object to be immovable but can still be collected by the GC.
This need was raised in mu-client-pypy#10. When an object p
in PyPy heap (Mu heap) is bound to an object o
in C (CCALL malloc
), p
is pinned and o
keeps the address of p
as an integer, and the reference count on o
is set to a special value to mark this bounding. PyPy's GC, however, can still collect p
, and it has different implications on o
depending on the reference count. This behaviour is currently not supported in Mu. The current semantic of @uvm.native.pin
can result in memory leak as p
is never collected.
Currently the spec doesn't seem to have a very clear specification on this issue. In general-issue-tracker#28 it is mentioned that the pointer can be used until the object is unpinned. This does imply both immovability and immortality until a corresponding @uvm.native.unpin
instruction. This should be clarified further in the spec.
This does raise the problem of pointer validity. If an object is pinned with the option of being mortal, when it is collected, the pointer become invalid. Do we just then push the responsibility to the client and say that the client must know what they are doing and must not access an invalid pointer in this way?
Proposed change
Add an optional flag to @uvm.native.pin
instruction to allow mortal pinning:
[0x240]@uvm.native.pin [#MORTAL] <T> (%opnd: T) -> uptr<U>
- The presence of the flag
#MORTAL
allows the pinned object to be collected by the GC when it becomes unreachable. When the object is collected, all deriveduptr
s become invalid.