[foreign-memaccess] Simplifying memory access var handles
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Jun 23 10:38:29 UTC 2020
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