[foreign-memaccess] RFR 8225172: Add way to create deref VarHandles without using the Layout API

Jorn Vernee jbvernee at xs4all.nl
Thu Jun 13 15:40:40 UTC 2019


On 2019-06-13 16:33, Maurizio Cimadamore wrote:
> Looks really good.
> 
> The code is really clean, I have nothing to object as to the choices
> you've made.

Thanks!

> I wonder if we can do some further consolidation in the VarHandles
> code - that is, we pass the 'dims' to the generator - if we passed the
> stride array directly (after all, 'dims' == 'strides.length'), we
> could then use CP patching for that too in the accessor, which will
> simplify the code quite a bit... but I also realize that this would
> send the caching logic off to the drain, so... nvm :-)

Yep - we generate a class per arity, but the actual values of the 
strides can differ per VarHandle instance.

> Also, I would check for negative strides in the VH constructor and
> throw eagerly if that's not valid, rather than wait until VarHandles.

Okay.

> Another nit is that I find the 'sizeof(Class)' routine repeated in
> multiple places:
> 
> * LayoutPathImpl
> * VarHandles
> * MemoryAccessVarHandles
> 
> This should be consolidated somehow. One option is also to use
> `sun.invoke.util.Wrapper.findPrimitive(carrier).bitWidth() / 8`

Thanks for the suggestion! I knew there must have been a utility laying 
around for that :)

> Finally, there's a typo in the javadoc for MemoryAccessVarHandles:
> 'it's accesses' vs. 'its accesses'.

Thanks for catching this.

> Overall, it seems like we have a nice set of Lego bricks here :-)

:)

Updated webrev: 
https://cr.openjdk.java.net/~jvernee/panama/webrevs/8225172/webrev.04/

The sizeOf(Class) call was also implicitly doing a carrier type check, 
so I'm now doing that explicitly in 
MemoryAccessVarHandles::dereferenceVarHandle and 
LayoutPathImpl::dereferenceVarHandle instead, and added a test case for 
this as well.

Cheers,
Jorn

> Maurizio
> 
> On 13/06/2019 14:02, Jorn Vernee wrote:
>> Hi,
>> 
>> I've made a new version that works like the proposed combinator-like 
>> API.
>> 
>> Webrev: 
>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/8225172/webrev.03/
>> 
>> This adds a new class called MemoryAccessVarHandles to 
>> java.lang.invoke which has these combinators:
>> 
>>   VarHandle dereferenceVarHandle(Class<?> carrier)
>>   VarHandle offsetHandle(VarHandle handle, long offset)
>>   VarHandle elementHandle(VarHandle handle, long scale)
>>   VarHandle alignAccess(VarHandle handle, long align)
>>   VarHandle byteOrder(VarHandle handle, ByteOrder order)
>> 
>> I put this class in j.l.i to get easy access to 
>> VarHandleMemoryAddressBase, which is used to get the needed 
>> information out of a VarHandle to use in a combinator call.
>> 
>> In order to get the carrier type and strides array out of an existing 
>> VarHandle I added to accessor methods to VarHandleMemoryAddressBase, 
>> which are spun dynamically. Adding them as fields could work as well, 
>> but this was my attempt to keep the footprint of the VarHandle 
>> instance smaller.
>> 
>> Cheers,
>> Jorn
>> 
>> On 2019-06-04 02:15, Jorn Vernee wrote:
>>> Maurizio Cimadamore schreef op 2019-06-04 01:41:
>>>> Hi Jorn,
>>>> I too feel some of the tension you are talking about, but I'm quite
>>>> opposed to a builder API such as the one you described.
>>> 
>>> Yeah - this was more of a suggestion to get the conversation going, 
>>> in
>>> hindsight.
>>> 
>>>> Rather, what I'd be interested to explore, is whether we could built
>>>> complex dereference expressions out  of simpler ones, using an
>>>> approach similar to MethodHandle combinators. Let's assume that each
>>>> memory access VH has an offset, denoted as O. Then it seems to me 
>>>> that
>>>> there are only a bunch of moves we want to allow:
>>>> 
>>>> * obtain a memory address dereference for a given carrier type - 
>>>> this
>>>> is the entry point VH, whose O = zero
>>>> 
>>>> * starting from a given memory address VH with offset O, obtain a 
>>>> new
>>>> VH' whose O' =  O + C (where C is an argument to the combinator)
>>>> 
>>>> * starting from a given memory address VH with offset O, obtain a 
>>>> new
>>>> one, called VH' whose offset O' = (S * N) + O (where S is an 
>>>> argument
>>>> to the combinator - the scale - and N is a dynamic argument to VH' -
>>>> the array index)
>>>> 
>>>> So, let's say I want to access the i32 in the layout below:
>>>> 
>>>> [5 : [ x32 i32 ] ]
>>>> 
>>>> What I'd do would be something like:
>>>> 
>>>> VarHandle handle = MemoryAddresses.dereferenceHandle(int.class); 
>>>> //(MA) -> I
>>>> handle = MemoryAddresses.offsetHandle(handle, 4); //(MA) -> I
>>>> handle = MemoryAddresses.elementHandle(handle, 8); //(MA, J) -> I
>>>> 
>>>> 
>>>> I think this is expressive enough to do what our API currently 
>>>> allows,
>>>> and I kind of like that it gets there in a more primitive way (and
>>>> very similar to how MH are constructed bottom up).
>>> 
>>> Yes, this seems much better than my idea :)
>>> 
>>> One thing I like about it is that we immediately get a VarHandle for
>>> the most simple case, rather than having to do several API calls to
>>> get there.
>>> 
>>>> Whether I'd like to completely give up Layout/LayoutPath for 
>>>> something
>>>> like this I'm not sure though. The ability of constructing a full
>>>> memory layout and then obtaining a var handle from one of its path
>>>> seems pretty good. I've written examples with this API where going
>>>> down the Layout route immediately spotted latent alignment issues 
>>>> that
>>>> were present in the Unsafe code that it replaced. So, while we can 
>>>> get
>>>> there in a more primitive way, I'm not 100% sure of whether that 
>>>> means
>>>> we should get rid of layouts too. At the very least, layouts are
>>>> useful whenever there's some kind of size/alignment/offset 
>>>> computation
>>>> to be done, which, with layout, can be expressed at a slightly 
>>>> higher
>>>> level.
>>> 
>>> Agree here as well. I just entertained the thought of removing
>>> Layouts, but also remembered that this is something that people
>>> actaully asked for w.r.t. direct ByteBuffers. So I think it's good to
>>> keep. But at the same time I'd like to see the Layout API being
>>> decoupled a bit more from the deref VarHandle API. Having a separate
>>> API layer in between seems like a good way to assure that, while also
>>> offering users the additional option to user their own layout APIs.
>>> 
>>> Jorn
>>> 
>>>> Maurizio
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On 03/06/2019 17:46, Jorn Vernee wrote:
>>>>> Forgot to 'hg add' one file. See updated webrev: 
>>>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/8225172/webrev.02/
>>>>> 
>>>>> Thanks,
>>>>> Jorn
>>>>> 
>>>>> Jorn Vernee schreef op 2019-06-03 18:38:
>>>>>> Hi,
>>>>>> 
>>>>>> I've implemented an alternative way of creating memory access
>>>>>> VarHandles, which bypasses the Layout API. One reason for having 
>>>>>> such
>>>>>> an alternative API is that it offers users the opportunity to use
>>>>>> their own (pre-existing) layout APIs when creating VarHandles. 
>>>>>> This
>>>>>> mainly consists of a builder API called 
>>>>>> MemoryAccessVarHandleBuilder,
>>>>>> which can be used similarly to LayoutPath to construct a 
>>>>>> VarHandle.
>>>>>> 
>>>>>> As a side effect I've removed the dependency on Layout/LayoutPath 
>>>>>> from
>>>>>> VarHandles::makeMemoryAddressViewHandle. I think this decoupling 
>>>>>> makes
>>>>>> this API point more suited to what's possible to do with memory 
>>>>>> access
>>>>>> VarHandles.
>>>>>> 
>>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8225172
>>>>>> Webrev: 
>>>>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/8225172/webrev.01/
>>>>>> 
>>>>>> Added tests are pretty minimal since the resulting VarHandle is
>>>>>> already tested by the existing tests using the Layout API.
>>>>>> 
>>>>>> This also opens up the possibility of removing the Layout API
>>>>>> altogether if we wanted. Another TODO is adding a way to disable
>>>>>> alignment checking upon access (which would need changes to the
>>>>>> VarHandle impl classes I think).
>>>>>> 
>>>>>> Thanks,
>>>>>> Jorn


More information about the panama-dev mailing list