No segment method for MemoryAddress?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Aug 21 09:03:20 UTC 2020
On 21/08/2020 01:40, Ty Young wrote:
>
> On 8/20/20 4:43 PM, Maurizio Cimadamore wrote:
>>
>> On 20/08/2020 21:32, Ty Young wrote:
>>> So, apparently the <MemoryAddress>.segment() method was removed and
>>> now provides a seemingly redundant address() method:
>>
>> This was all described here:
>>
>> https://mail.openjdk.java.net/pipermail/panama-dev/2020-July/009928.html
>>
>> Basically, a MemoryAddress no longer has a link to a segment. An
>> address is just a thin wrapper around an Object/long unsafe
>> addressing pair.
>>
>> Addressable is mostly there so that _everything_ that can be
>> converted to an address can be passed to a function. We use this in
>> jextract, so that clients can avoid a lot of calls to
>> ".baseAddress()". If you don't need it, you can ignore it.
>
>
> I read that and came to that very conclusion as you give for the
> reason. I thought it was a minor, optional API change and not
> something that breaks the API's flow though which is why I never
> bothered making a new JDK build.
>
>
> I don't personally understand the logic here - It makes more sense(to
> me, anyway) to talk in MemoryAddress(s) rather than MemorySegment(s),
> MemoryAddress takes up heap representing what could be represented
> using primitive longs(unless I'm missing something?), and you have
> this address() method on MemoryAddress that presumably just returns
> itself(?). The way it was before really wasn't bad, it just needed
> some method name changes(baseAddress() -> address()).
I think we should largely leave the address() method alone in this
discussion. That is part of the Addressable interface, which is a way to
abstract over MemorySegment, MemoryAddress, LibraryLookup.Symbol and
VaList. It's totally orthogonal to the discussion.
While the change might be surprising for people used to the way the API
was, I think in reality is more natural to people coming to the API for
the first time. Note that the recent "state" documents already explained
things in that light. In general, if you want to dereference memory,
its' way clearer if you do so by having a segment; a segment has spatial
and temporal boundaries (which can make dereference safe). An address
doesn't.
Before this change we had a very subtle distinction between *checked*
and *unchecked* addresses; that is, the segment() returned by an address
might sometimes be NULL (which means no dereference, sorry). This made
it extremely difficult to write libraries on top of the FMA, because
whenever you accepted a MemoryAddress you had to ask: is this a MA which
is dereference-able, or not? This was very visible as soon as we started
to add some helper methods in the CSupport class.
The new state is much cleaner: need to dereference? Then you need a
segment. But sometimes a native library will "just" give you a
MemoryAddress back; at which point you can either construct a segment
out of it (using the restricted factory), or dereference it directly, by
projecting it into a long offset (and using the _everything_ segment as
the base segment).
Why not just using a long? Because we cannot represent heap addresses
with just a long. An address is both an Object (base) and a long
(offset); in case of a *native* address, the base is NULL and only the
offset matters. But for an address into an heap array you need both. As
for the "heap waste" argument, since now memory address is a dumb holder
of two final fields (Object, long), making this an inline type is a no
brainer, when Valhalla will allow us to do so.
Maurizio
>
>
> I guess I'll be creating yet another abstraction interface
> "NativeAddress" or something. I hope it doesn't get to the point where
> I need to abstract everything about FMA.
>
>
>>
>> Maurizio
>>
>>
>>>
>>>
>>> private final MemoryAddress address;
>>>
>>>
>>> ...
>>>
>>>
>>> this.address.address();
>>>
>>>
>>> which has the Javadoc:
>>>
>>>
>>> "Map this object into a MemoryAddress instance."
>>>
>>>
>>> ...but it is already a MemoryAddress? What is going on here? How are
>>> you supposed to get a segment from an address? Why is there a
>>> seemingly redundant address() method?
>>>
>>>
>>> Reading the Javadoc of Addressable:
>>>
>>>
>>> "Represents a type which is addressable. An addressable type is one
>>> which can be projected down to a memory address instance (see
>>> address()). Examples of addressable types are MemorySegment,
>>> MemoryAddress, LibraryLookup.Symbol and CSupport.VaList."
>>>
>>>
>>> provides context on why the address() method exists but not why
>>> segment() has been removed.
>>>
>>>
>>> Personally, I think the address() method should be removed and the
>>> components that make up a MemoryAddress be exposed instead if
>>> possible, but that's my 2 cents.
>>>
>>>
>>>
>>>
>>>
More information about the panama-dev
mailing list