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