[Integrated] [foreign-memaccess] RFR: Move MemoryAddress::copy

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon May 18 10:11:17 UTC 2020


On 16/05/2020 02:19, John Rose wrote:
> Anyway, I like the way MS is shaping up, as a small bounded location of
> state, and MA as a working pointer therein.  You all have probably had
> similar thoughts about “what sort of sugary methods we might eventually
> place on MA”.  The placement of MS::copyOf unlocked some of those ideas
> for me, and the above is what I came up with, FWIW.

These are all interesting ideas - thanks John.

I'd like to think some more and to see how they fit with the slicing 
methods we already have.

For instance, sliceAt could be expressed as an overload of 
MemorySegment::asSlice which, in addition to the usual offset/length 
parameters also takes a base address (and throws is the address does not 
belong to the segment).

A feeling I have is that one of the reasons for going back and forth 
through addresses, is, perhaps caused by two factors:

* cannot pass negative offset in MemroySegment::asSlice (that's because 
a slice doesn't know, currently, the offset of its parent)
* cannot have unsized slices (e.g. MemorySegment::asSlice which takes 
only one parameter - the offset)
* cannot pass a MemoryAddress directly instead of a byte offset

My sense is that, since copyFrom is expressed in _segments_ having ways 
to slice segments directly more naturally (rather than to call 
baseAddress() and then do the operation on the address) might be 
slightly better for client code. E.g. let's take the example you have 
written:

p.segment().asSlice(a.segmentOffset(), (some size)).copyFrom(q…)


In most code I've seen, you already start off with two segments (so `p` 
is a segment too), and the really annoying bit is to have to specify a 
size which is going inevitably to be some dependent expression - either 
on `a.segmentOffset() - baseAddress()` or on `q`.

So, I believe that if we offered a no-length overload:

p_segment.asSlice(a.segmentOffset()).copyFrom(q…)

Things would already improve considerably in the common case (remember, 
in such cases, at least the ones we've seen, `p` is a segment already). 
Which kind of leaves out the case where you want a negative offset too.

That said, I think that it would also be nice to provide overloads that, 
rather than taking bytes, it would just take a MA:

p_segment.asSlice(a).copyFrom(q…)

Although this method could now throw (if the address does not belong to 
the segment we're slicing).


So I think I see an incremental path to get to a more sugary final state 
- the big question is gonna be how we're going to deal with slicing 
segments using negative offsets. This is easily expressed if you start 
from an address (like you did in your proposal) - but a tad harder if 
you start from segments. That said, given also past experiences, I'd be 
wary of putting _some_ slicing methods on `MemorySegment` and others on 
`MemoryAddress` as, in the past, that led to poor discoverability of the 
API (users didn't know that the MemoryAddress:copy method existed) which 
was one of the motivation behind the cleanup + move.

Thanks
Maurizio




More information about the panama-dev mailing list