MemoryAddress object changes once put into memory

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Jan 14 16:34:46 UTC 2020


If I understand correctly your question, this is to be expected. What is 
really happening is that you are serializing a MemoryAddress into a 
'long' (its address) and save it into native memory. Since we're really 
only storing a 64-bit number, all the characteristics of a MemoryAddress 
are lost after a store - such as the spatial and temporal bounds.

When you read that, later on, you just read a long, and the runtime will 
construct a MemoryAddress instance on top of that. Since no bound 
information is available, the runtime will resurrect that MemoryAddress 
as a Nothing-backed MemoryAddress. Which means the address will be unusable.

But if you are serializing and deserializing segments you know, you can 
do a rebase after the deserialization (the get() operation), so that 
your address will become functionally equivalent to the one you started 
with.

Maurizio


On 14/01/2020 16:18, Ty Young wrote:
> Hi,
>
>
> As mentioned in a different thread, a MemoryAccess instance changes 
> once put into memory. Here are all the relevant bits from the class:
>
>
>     private final MemorySegment segment;
>     private final SequenceLayout sequenceLayout;
>
>     public ArrayArray(long length)
>     {
>         this.sequenceLayout = MemoryLayout.ofSequence(length*24, 
> MemoryLayouts.JAVA_LONG);
>
>         this.segment = MemorySegment.allocateNative(this.sequenceLayout);
>     }
>
>
>     @Override
>     public void setValue(int index, Array<E> value)
>     {
>         MemorySegment elementSegment = this.segment.asSlice(index*192, 
> 192);
>
>         MemorySegment addressSegment = elementSegment.asSlice(0, 64);
>         MemorySegment layoutSegment = elementSegment.asSlice(64, 64);
>         MemorySegment lengthSegment = elementSegment.asSlice(128, 64);
>
>         VarHandle addressHandle = 
> MemoryHandles.varHandle(MemoryAddress.class, ByteOrder.nativeOrder());
>         VarHandle layoutHandle = MemoryHandles.varHandle(long.class, 
> ByteOrder.nativeOrder());
>         VarHandle lengthHandle = MemoryHandles.varHandle(long.class, 
> ByteOrder.nativeOrder());
>
>         addressHandle.set(addressSegment.baseAddress(), 
> value.getAddress());
>         layoutHandle.set(layoutSegment.baseAddress(), 
> value.getElementSequenceLayout().elementLayout().bitSize());
>         lengthHandle.set(lengthSegment.baseAddress(), 
> value.getLength().getAsLong());
>     }
>
>
>     ...
>
>
> As shown here, the address of the array being set is being stored in 
> the addressSegment. However, once read back into Java it changes so 
> that both it's ID changes, has an offset, and its limit is zero when 
> it should be 64 even when read back in using the same VarHandle in 
> setValue method. Am I doing something wrong(like no rebasing?) or is 
> there something else going on?
>


More information about the panama-dev mailing list