[foreign-memaccess] RFR 8224843: Refine ByteBuffer interop support

John Rose john.r.rose at oracle.com
Mon May 27 19:12:01 UTC 2019


I'm glad to see this.  The code looks good.  I've been
hoping we'd see this day!  I agree with your choices
about ofArray(byte[]), "final", and CharBuffer.

The new scope-aware type of BB will, I hope, be useful
for people who want the capabilities of Panama, including
better pointer safety, but prefer to work with BB APIs
for slinging the bits.

FTR, here are a couple of future moves that this one
unlocks:

* Timely deallocation.  If the _buffer field of the new BB
class is a DBB then a deallocate operation can be defined
which releases the underlying storage immediately, instead
of via a Cleaner.  This is safe for the same reason scope
deallocation is safe.  There's a catch:  The _buffer needs
to be unaliased to any external "wild" BB or separately
managed Panama memory block.  This typically means
(a) the new BB constructor allocates foreign storage directly
rather than having it handed to the constructor as an
argument and (b) the new BB class has a boolean which
encodes the unaliased state.  In effect, this means that
the underlying block is handled under a discipline of
"linear ownership", like a linear type in some formalisms.
Which leads to the next point:

* Handoff operations on BBs.  If/when we do protocols
for pushing linear ownership of scopes across threads,
the BBs come along for the ride.  This will widen the
circumstances where scoped BBs will be useful, by
removing the constraint the all work happens in one
thread.

More FTR:

The elements of cross-thread handoff are simple,
though tricky in implementation details.  A memory
block B can (in principle) be re-scoped from an owning
T1 to a new owner T2 if T1 synchronously finishes all
operations on B (release fence) and then locks itself
out from B.  The transfer to T2 is finished by reversing
this process (acquire fence).  The midpoint of the process
is, all by itself, a useful state, where B is locked out of
both T1 and T2 (and all other threads); this is a neutral
state from which any thread T2 can pick it up.  This
neutral state is neither readable nor writable, but is
perfect for placing B on a queue, to be picked up by
a future thread whose identity is not yet known.  So
hand-off factors into T1 putting B down, into neutral
state, and T2 picking it up some time later.  A mutex
of some sort is needed to prevent T2 and T3 both
picking up a neutral B due to races.

This is future stuff which I think will eventually happen
but TBH might not.  The present integration between
BB's and Panama is really neat and doesn't need the
extra future stuff… at present.

Thanks Maurizio!  This breathes new life into BBs, IMO.

— John

> On May 27, 2019, at 10:45 AM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
> 
> Hi,
> as you know, the foreign memory access API supports bidirectional interop between MemoryAddress and ByteBuffer:
> 
> 1) MemorySegment::ofByteBuffer(ByteBuffer)
> 2) MemoryAddress:;asDirectByteBuffer(int bytes)
> 
> That is (1) can be used to create a memory segment out of an existing byte buffer, whereas (2) can be used to do the opposite, that is, to convert a memory address into a byte buffer.
> 
> While (1) works pretty reliably (but I've added some tests for it), the implementation for (2) leaves to be desired:
> 
> * The resulting byte buffer is unaware of the fact that the backing memory is attached to a scope that can be closed
> * There's no way to create a buffer if the address encapsulates some heap-based memory address
> 
> This patch solves both issues - and also adds a supported way for creating a memory segment out of a heap-allocated byte array (MemorySegment.ofArray(byte[])) which I think is useful.



More information about the panama-dev mailing list