[foreign-memaccess+abi] RFR: 8317514: Ensure MemorySegment is initialized before touching NativeMemorySegmentImpl [v2]

Maurizio Cimadamore mcimadamore at openjdk.org
Mon Oct 9 21:06:28 UTC 2023


On Mon, 9 Oct 2023 19:15:59 GMT, Jorn Vernee <jvernee at openjdk.org> wrote:

>> Please review this fix for a class initializer deadlock.
>> 
>> The issue is that `MemorySegment` references `NativeMemorySegmentImpl` in its initializer, through the `NULL` constant. `NativeMemorySegmentImpl` also depends on `MemorySegment` to be initialized, since it's a super interface with default methods. The VM does not drop the initialization monitor of `NativeMemorySegmentImpl` while trying to initialize super classes/interfaces (as mandated by the JVM spec).
>> 
>> When 2 threads try to intialize `MemorySegment` (e.g. through `ofAddress`) and `NativeMemorySegmentImpl` (e.g. through Arena::allocateFrom), at the same time, a deadlock can occur.
>> 
>> This PR fixes this issue by ensuring `MemorySegment` is initialized in all cases where we directly access `NativeMemorySegmentImpl` or `MappedMemorySegmentImpl`.
>> 
>> We might consider a fix that removes the cycle in the future as well.
>
> Jorn Vernee has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Add test for FileChannel::map

src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java line 40:

> 38:         // if multiple threads try to initialize NativeMemorySegmentImpl and MS through allocateNoInit
> 39:         // and a method on MS at the same time
> 40:         Unsafe.getUnsafe().ensureClassInitialized(MemorySegment.class);

If you want to avoid unsafe, another way is to use:
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/invoke/MethodHandles.Lookup.html#ensureInitialized(java.lang.Class)

-------------

PR Review Comment: https://git.openjdk.org/panama-foreign/pull/902#discussion_r1350785482


More information about the panama-dev mailing list