MemoryAddress object changes once put into memory
Ty Young
youngty1997 at gmail.com
Tue Jan 14 17:32:29 UTC 2020
On 1/14/20 11:12 AM, Maurizio Cimadamore wrote:
>
> On 14/01/2020 16:58, Ty Young wrote:
>>
>> On 1/14/20 10:46 AM, Maurizio Cimadamore wrote:
>>>
>>> On 14/01/2020 16:38, Ty Young wrote:
>>>>
>>>> On 1/14/20 10:34 AM, Maurizio Cimadamore wrote:
>>>>> 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.
>>>>
>>>>
>>>> Ah, OK. Thanks for the clarification.
>>>>
>>>>
>>>> What would you use to rebase the segment with? Obviously when I go
>>>> to reconstruct the array in Java all I have is what's stored at
>>>> that same point in the larger segment:
>>>>
>>>>
>>>> @Override
>>>> public Array<E> getValue(int index)
>>>> {
>>>> 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());
>>>>
>>>> MemoryAddress address =
>>>> (MemoryAddress)addressHandle.get(addressSegment.baseAddress());
>>>> long layout =
>>>> (long)layoutHandle.get(layoutSegment.baseAddress());
>>>> long length =
>>>> (long)lengthHandle.get(lengthSegment.baseAddress());
>>>>
>>>> return new MemoryArray(address, layout, length);
>>>> }
>>>>
>>>>
>>>> So how do you go about rebasing something like this?
>>>
>>> In your case there's not much you can do, other than to rebase to an
>>> unchecked segment - after all you know the length of the saved array
>>> (because you are storing and recovering it), so you could do:
>>>
>>> MemoryAddress newAddress =
>>> address.rebase(ForeignUnsafe.ofNativeUnchecked(address, length))
>>
>>
>> IIRC no decision has been made regarding the mechanism of making
>> ForeignUnsafe available and Netbeans isn't suggesting a class import.
>> Which module do I need to add for that?
>
> No decision has been made yet.
>
> For now you will need something like
> --add-exports=jdk.incubator.foreign/jdk.incubator.foreign.unsafe=<your
> module>
Netbeans is going absolutely insane right now whenever more than 2
modules are exported/opened so I think I'll just export the package from
the module-info and compile from source. IIRC there were some method
name changes recently anyway with offset().
>
>>
>>
>> Or is there any other "safe" way of implementing multi-dimensional
>> arrays that I'm not aware of?
>
> It largely depends on how your implementation works - but if your
> mutidimensional array is just a sparse collection of pointers to other
> arrays with given size, which can live anywhere in memory, I don't
> think there's much you can do safely (at least not on top of my head).
>
> If you implement a more dense representation (e.g. like a tensor -
> where elements are stored in a N1 * N2 * ... NM matrix) then you know
> by construction that rows, columns, elements will always be bound by
> the toplevel segment which contains the entire tensor. But a dense
> representation doesn't need pointers, so the code would be very
> different from the one you have.
Alright, thanks.
>
> Maurizio
>
>>
>>
>>>
>>> Maurizio
More information about the panama-dev
mailing list