[foreign-memaccess] RFR 8227394: Add MemorySegment::asByteBuffer convenience method
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Jul 11 16:55:02 UTC 2019
On 11/07/2019 17:51, Maurizio Cimadamore wrote:
>
>> This sounds good as well.
>>
>> I was thinking about the lump/split discussion around MA and MS,
>> particularly where we draw the lines of responsibility between the
>> two. I think MS should be used to manage a memory resource
>> (allocating, slicing, closing), while MA should simply be used to
>> access the resource (dereferencing, offset). So, after all, I think
>> any method for slicing the segment (i.e. managing the resource)
>> should be in MS as well.
>>
>> I'm not so sure about the name offset() though, since that seems to
>> clash a bit with ForeignUnsafe::getOffset(), and
>> MemoryAddress::offset(long). Maybe an alternative is offsetOf(), or
>> toSegmentOffset()?
>
> We have other cases in the JDK where the same name is used for getter
> and setter (e.g. ByteBuffer::order). So I'm not overly worried about
> that, and I still prefer that that using get/set.
Actually, virtually all methods here
https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/nio/Buffer.html
use that pattern. So, while not super-ideal, I think that could be
justified.
As for the unsafe methods, I think we should rename them to
getUnsafeOffset and getUnsafeBase
Maurizio
>
> Another option worth looking into would be, IMHO, to explore
> alternatives for the offset(long) method. In a way it feels the use of
> offset is ambiguous here, it is both a noun (which justifies the
> getter semantics) and a verb (which justifies the setter/wither
> semantics). For instance, one possible renaming for offset(long) is
> advance/move
>
> address.advance(42).offset();
>
> I think that reads well? (also implies that negative offsets are kind
> of not accepted?)
>
> Maurizio
>
>>
>> Jorn
>>
>>> Maurizio
>>>
>>>
>>>>
>>>> Like you say, by adding a MemorySegment::asByteBuffer we introduce
>>>> a problem because some segments are too large, but this seems
>>>> pretty similar to being able to pass a size to
>>>> MemoryAddress::asByteBuffer that is too large, which is still
>>>> possible even if it's an `int`. At the same time we have one less
>>>> problem because we can no longer use a MemoryAddress that is out of
>>>> bounds of the segment.
>>>>
>>>> It feels like a pretty much even trade.
>>>>
>>>>> I'm less convinced on the
>>>>> usefulness of turning an entire memory segment into a bytebuffer: if
>>>>> you really wanted to view the entire memory segment as a BB, maybe
>>>>> you
>>>>> just wanted to create a (direct) BB in the first place?
>>>>
>>>> By that same line of thought, do we need
>>>> MemoryAddress::asByteBuffer? This is meant as an interop thing,
>>>> where you just have a MemorySegment that is given to you, and would
>>>> like to turn it into a ByteBuffer.
>>>>
>>>> I agree with the concern of the API explosion. I was also looking
>>>> at removing the asByteBuffer method from MemoryAddress, and
>>>> replacing it with a more general 'sliceAt' method, that slices the
>>>> underlying MemorySegment at the offset denoted by the MemoryAddress
>>>> itself (instead of having to pass that manually as the offset to
>>>> MemorySegment::slice). I could imagine cases where a user has a
>>>> MemoryAddress and wants to do an offset and then slice, e.g. I have
>>>> a pointer to some struct, returned by some third party allocator
>>>> API, and want to give someone else a pointer to access just a
>>>> single field, I can try and call `address.segment().slice(...)`,
>>>> but the problem would be that I don't know what to pass as offset
>>>> (after all, the MemoryAddress I have might not be the base address
>>>> of the segment).
>>>>
>>>> With a `sliceAt` method, the current use of asByteBuffer(int) could
>>>> be replaced with `address.sliceAt(newSize).asByteBuffer()`.
>>>>
>>>> Prototype:
>>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/8227394/webrev.01/
>>>>
>>>> What do you think? Of course, if you'd rather hold off on fiddling
>>>> with the API too much at this time that's fine with me :) (I'm
>>>> guessing we're trying to target JDK 14 as an incubating feature?)
>>>>
>>>> Jorn
>>>>
>>>> On 2019-07-11 14:00, Maurizio Cimadamore wrote:
>>>>> Hi Jorn,
>>>>> I gave some thought about this in the past, and my conclusion was
>>>>> mixed - and I filed this in the "you ain't gonna need it" bucket
>>>>> (YAGNI).
>>>>>
>>>>> The motivations are that (i) it is really simple to emulate the API
>>>>> with the existing methods (as the implementation of the new method
>>>>> shows), and that (ii) the new API is, by necessity, a partial API -
>>>>> not all segments can be mapped onto a byte buffer - some are too
>>>>> large; while the existing API on memory address is total (thanks to
>>>>> the explicit int parameter).
>>>>>
>>>>> In other words, the existing API on MemoryAddress supports what I
>>>>> believe to be the most important interop idiom: slicing a big memory
>>>>> segment into multiple < 32bits buffer views. I'm less convinced on
>>>>> the
>>>>> usefulness of turning an entire memory segment into a bytebuffer: if
>>>>> you really wanted to view the entire memory segment as a BB, maybe
>>>>> you
>>>>> just wanted to create a (direct) BB in the first place?
>>>>>
>>>>> The current model is kind of easy to explain - the moves we allow
>>>>> are:
>>>>>
>>>>> * ByteBuffer -> MemorySegment
>>>>>
>>>>> * MemoryAddress + int -> ByteBuffer
>>>>>
>>>>> This feels minimal. If we add another dimension, as per your patch:
>>>>>
>>>>> * MemorySegment -> ByteBuffer
>>>>>
>>>>> Then the next question is - should we allow also:
>>>>>
>>>>> * ByteBuffer -> MemoryAddress? (e.g. create a big segment from the
>>>>> byte buffer and then have a memory address point at the BB offset)
>>>>>
>>>>> Which feels a bit like a slippery slope. I'd be more confident in
>>>>> adding a facility like this after some real world validation.
>>>>>
>>>>> What do you think?
>>>>>
>>>>> Maurizio
>>>>>
>>>>> On 11/07/2019 12:28, Jorn Vernee wrote:
>>>>>> Hi,
>>>>>>
>>>>>> Please review this small patch that adds an asByteBuffer
>>>>>> convenience method to MemorySegment that returns a buffer the
>>>>>> size of the segment.
>>>>>>
>>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8227394
>>>>>> Webrev:
>>>>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/8227394/webrev.00/
>>>>>>
>>>>>>
>>>>>> (note that the javadoc is largely taken from
>>>>>> MemoryAddress::asByteBuffer).
>>>>>>
>>>>>> My reason for adding this is that I wanted to reach for this
>>>>>> method a few times when playing with the API, but it didn't
>>>>>> exist. So, I thought it would be useful to have.
>>>>>>
>>>>>> (Also, I originally wanted to upload this to GitHub [1] to test
>>>>>> out the Skara [2] tools, but apparently that's not operational
>>>>>> yet :) )
>>>>>>
>>>>>> Thanks,
>>>>>> Jorn
>>>>>>
>>>>>> [1] : https://github.com/openjdk/panama/pull/1
>>>>>> [2] : https://github.com/openjdk/skara#openjdk-project-skara
More information about the panama-dev
mailing list