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