Using Layouts on heap - JDK18

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Jun 3 18:08:58 UTC 2022


On 03/06/2022 18:59, leerho wrote:
> Maurizio,
>
>     ```
>     MemorySegment segment = MemorySegment.ofArray(new
>     byte[layout.byteSize()]);
>     ```
>
>
> I thought of that too. It is obvious that I can derive a byteSize from 
> the layout, which passes to the ofArray method, but it isn't obvious 
> to me that I can subsequently access the array using the layout as I 
> don't see any linkage between the layout and the segment, because the 
> ofArray method is just getting a size and is oblivious to the fact 
> that I'm using a layout to get it.  Similarly, I can't find any 
> reference in the Layout API of a way to "assign" a layout to a 
> (previously created) segment.
Layouts cannot be "assigned" to segments. Layouts and segments are 
orthogonal abstractions. You create a segment, which contain some bytes, 
then you use layouts to _dereference_ the segment. A layout has 
knowledge about size, alignment and endianness, so if you pass that 
(along with a segment) to a dereference API, you have all the 
ingredients you need.
>
> I am just learning about layouts so I may be missing something.
>
> ###
>
>     * throw if the slice is not compatible with the layout alignment
>     constraints, or
>     * align the slice 
>
> 1. If the slice is just bytes wouldn't that always work?
> 2. I'm not sure what "align the slice" means? What would happen 
> underneath?  If the segment was created from an int[], and the layout 
> alignment required byte alignment -- what would "align the slice" do?
>
> #####
> Your mentioning of the alignment issue brings up another "asymmetry" 
> that I am somewhat troubled by.
>
> The "segment.asByteBuffer()" method is very limited to the case where 
> the segment was created from pure bytes.  If a segment wraps a heap 
> int[], and I try to acquire a ByteBuffer from the segment it fails.  
>  (And I do see the caveat "Throws UnsupportedOperationException" ... " 
> in the Javadocs.)  What also surprised me is that internally inside 
> the segment you retain the int[] structure!  Why?  Why don't you just 
> convert all inputs to just bytes?
You mean copying int[] into a byte[] ? That would not be just a "view" 
then, it would allocate memory. All the "as" methods are meant to create 
views over memory, and not copy contents.
>
> This is very different from ByteBuffer, where I can extract any of the 
> multibyte primitive arrays from the raw bytes of the buffer, because 
> the raw resource under the ByteBuffer is just a blob of bytes.  And 
> Unsafe provides even more flexibility.  I can start with an array of 
> longs and extract an array of ints because the underlying resource 
> view of Unsafe is just bytes.   So I am surprised you didn't do that 
> here.  I would think that having the internal view being just a blob 
> of bytes would be the most flexible.    If you want me to provide you 
> with a use case for this I can provide you one.

I think you are mistaken w.r.t. ByteBuffer. A ByteBuffer is backed by a 
byte[] - you can't turn that into an int[] w/o copying.

I also don't think that there is an Unsafe facility that lets you view a 
portion of a long[] as an int[] (you need a new Object header for the 
int[], so... again... allocation and copy).

Maybe you are talking about different things? Please provide a snippet 
of code using either Unsafe or ByteBuffer that does something that you 
think MemorySegment does not support. Perhaps the discussion would be 
easier that way.

Thanks
Maurizio

> Lee.
>
>
>
> On Fri, Jun 3, 2022 at 10:06 AM Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com> wrote:
>
>     Hi Lee,
>     in terms of heap allocation, how is your "allocate" different from
>     this:
>
>     ```
>     MemorySegment segment = MemorySegment.ofArray(new
>     byte[layout.byteSize()]);
>     ```
>
>     The above doesn't do any copy, it just creates a segment view over
>     the
>     array. (note that the carrier type used is important here - e.g. a
>     segment that wraps a byte[] has different properties when it comes to
>     alignment, than a segment that wraps long[]).
>
>     But then you bring up the slice method, which makes me think that,
>     perhaps you aren't after allocation at all - you have an existing
>     segment and you want to slice it, using a layout.
>
>     I think the slicing API overload you describe is a nice one (and one
>     that I found myself wanting at times too). Is "layout-oriented"
>     slicing
>     the main use case you are referring to here?
>
>     If we do this the "right" way, the slicing method would have to take
>     into account the required alignment of the provided layout and either:
>
>     * throw if the slice is not compatible with the layout alignment
>     constraints, or
>     * align the slice
>
>     Of these I would probably prefer the former, because it's "less
>     magic".
>
>     Maurizio
>
>     On 03/06/2022 17:56, leerho wrote:
>     > Hi,
>     > It is straightforward to create a native MemorySegment governed by a
>     > layout, but I can't see a way to create a heap segment governed
>     by a layout
>     > (without a copy).  We need to be able to read and write to
>     structs on-heap
>     > as well as off-heap.  Being able to overlay a Layout on a
>     segment derived
>     > from a ByteBuffer or from a mapped file would also be useful.
>     Perhaps these
>     > could be implemented via a slice?
>     >
>     > What I would like to see is something like:
>     >
>     > *MemorySegment *allocate*(MemoryLayout layout);  //base resource
>     is byte[]*
>     >
>     > OR
>     >
>     >> *MemorySegment *asSlice*(long offset, MemoryLayout layout)*
>     >
>     > The second could be applied to any base resource, not just off-heap.
>     >
>     > Am I missing something?
>     >
>     > Cheers,
>     > Lee.
>


More information about the panama-dev mailing list