RFR: 8287788: Implement a better allocator for downcalls [v8]

Maurizio Cimadamore mcimadamore at openjdk.org
Thu Jan 23 14:34:51 UTC 2025


On Thu, 23 Jan 2025 14:28:57 GMT, Matthias Ernst <duke at openjdk.org> wrote:

>>> Ah no, the allocate fails of course:
>>> 
>>> ```
>>> java.lang.WrongThreadException: Attempted access outside owning thread
>>> 	at java.base/jdk.internal.foreign.MemorySessionImpl.wrongThread(MemorySessionImpl.java:322)
>>> 	at java.base/jdk.internal.misc.ScopedMemoryAccess$ScopedAccessError.newRuntimeException(ScopedMemoryAccess.java:114)
>>> 	at java.base/jdk.internal.foreign.MemorySessionImpl.checkValidState(MemorySessionImpl.java:217)
>>> 	at java.base/jdk.internal.foreign.SegmentFactories.allocateSegment(SegmentFactories.java:181)
>>> 	at java.base/jdk.internal.foreign.ArenaImpl.allocateNoInit(ArenaImpl.java:52)
>>> 	at java.base/jdk.internal.foreign.ArenaImpl.allocate(ArenaImpl.java:57)
>>> 	at java.base/jdk.internal.foreign.ArenaImpl.allocate(ArenaImpl.java:31)
>>> 	at java.base/java.lang.foreign.SegmentAllocator.allocate(SegmentAllocator.java:644)
>>> 	at java.base/jdk.internal.foreign.abi.BufferStack$PerThread.<init>(BufferStack.java:73)
>>> 	at java.base/jdk.internal.foreign.abi.BufferStack$1.initialValue(BufferStack.java:50)
>>> 	at java.base/jdk.internal.foreign.abi.BufferStack$1.initialValue(BufferStack.java:47)
>>> 	at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:224)
>>> 	at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:193)
>>> 	at java.base/java.lang.ThreadLocal.getCarrierThreadLocal(ThreadLocal.java:180)
>>> 	at java.base/java.lang.System$1.getCarrierThreadLocal(System.java:2237)
>>> 	at java.base/jdk.internal.misc.CarrierThreadLocal.get(CarrierThreadLocal.java:39)
>>> 	at java.base/jdk.internal.foreign.abi.BufferStack.pushFrame(BufferStack.java:61)
>>> 	at TestBufferStack.lambda$stress$1(TestBufferStack.java:113)
>>> ```
>> 
>> I was under the impression (which appears incorrect) that `initialValue` would be called by the carrier thread as well. So, we basically have a mismatch where `initialValue` is called with thread A, but `terminate` is called on thread B ?
>
> Exactly. initialValue happens on-demand, not upfront, i.e. in the very moment the VT calls get().
> Whereas terminate happens as the last action of the CT.

If this is really the case, I agree that there doesn't seem to be an alternative to use `ofAuto`. In which case you don't really need a TerminatingThreadLocal -- a CarrierThreadLocal is just fine (given we don't really have anything to do on close).

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

PR Review Comment: https://git.openjdk.org/jdk/pull/23142#discussion_r1927077515


More information about the core-libs-dev mailing list