[foreign-memaccess] Simplifying memory access var handles

Paul Sandoz paul.sandoz at oracle.com
Tue Jun 23 15:16:43 UTC 2020

That plays well with a MemorySegment being addressable.

FWIW in my simple tensor experiment the following would collapse:

static final class OfIntUsingSegment extends UsingSegment<Integer> implements OfInt {
    static final MemoryLayout L = MemoryLayout.ofSequence(MemoryLayouts.JAVA_INT);
    static final VarHandle VH = L.varHandle(int.class, MemoryLayout.PathElement.sequenceElement());

And linear access becomes simpler.


> On Jun 23, 2020, at 3:38 AM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
> As I was exploring the consequences of the latest API moves, I realized that, perhaps, our VarHandle story is too complex, and not in sync with the lower energy equilibrium of the new API configuration. I think this is pretty clear if you look at how the behavior of the static accessors is specified in my experimental branch - let’s take for instance the Java int accessor:
> |This is equivalent to the following code: VarHandle handle = MemoryHandles.withStride(JAVA_INT.withBitAlignment(8).varHandle(int.class), 1L); int value = (int)handle.get(addr, offset); |
> It feels odd that, to get to such a low-level, primitive accessor, we have to jump through all these hops - e.g. crate a basic VH with given carrier and alignment, then using the stride combinator, setting the stride at 1, so that the offset taken as input is interpreted as a plain byte offset.
> So, an idea occurred to me: what if the basic VH /was/ a VH that took a byte offset?
> E.g.
> |MemoryHandles.varHandle(int.class) -> VH(MemortSegment, long) -> int |
> This feels like a good move, as a VH such as this one certainly does feel primitive - we can express all the other handles on top of it (with VH adaptations).
> One of the questions posed by such an approach is: what do we do with the existing MemoryHandles.withStride/withOffset combinators? If we go for this approach I think the most sensible thing would be to just drop them: after all, accessing at an offset is simply binding a long into the basic VH; and adding a stride can also be easily achieved with coordinate filtering. Also, the layout API would do all this stuff for free, so it’s not like users will have to write complex combinator code: this actually plays to the strengths of the APIs we already have: use the layout info we captured in the API to construct complex, structured access.
> The advantages are many:
> * there are less ways to do the same things - e.g. if you want
>   structured access, you really need a layout now
> * we can drop all the VarHandle code generation support - the
>   (MemorySegment, long) coordinate pair is general enough that we can
>   derive anything from it, using just plain combination (this also
>   means, likley, less startup cost)
> * since the offsets are expressed in longs, we no longer have the
>   issue we had in the past where we had to adapt a MemoryAddress
>   coordinate (e.g. by adding an offset to it) which was very expensive
>   - in other words, adaptation can be made as fast as the current code
> * we no longer need to differentiate between “memory access var
>   handle” and “regular var handles” and do different tricks depending
>   on that
> So I think, overall, the advantages of this approach are many - and there are no disadvantages I can see. It’s again one of those moves that goes towards regularizing the API and make it more tight, by moving around functionalities and simplifying the underlying impl, but w/o impacting usability much.
> Maurizio

More information about the panama-dev mailing list