Eirik

See my answers bellow.

But before that. Alan Bateman said to me that Loom project has much simpler 
implementation to what you want.
Thread local scopedCache which is Object[] array referenced from current thread:

https://github.com/openjdk/loom/blob/fibers/src/java.base/share/classes/java/lang/Thread.java#L310
https://github.com/openjdk/loom/blob/fibers/src/hotspot/share/prims/jvm.cpp#L3130

It will be much easy to optimize.

On 3/5/21 11:13 AM, Eirik Bjørsnøs wrote:
On Fri, Mar 5, 2021 at 6:41 PM Vladimir Kozlov <vladimir.koz...@oracle.com 
<mailto:vladimir.koz...@oracle.com>> wrote:

Vladimir,

Thanks a lot for taking time to consider this! Some comments inline:

    Currently it is "impossible" for JIT compiler to reliably know that value 
stored by set() in hash map is the same as
    read by get().


My layman (perhaps naive?) thinking was that a JIT could cheat and infer this by definition. Since a ThreadLocal holds memory that is by definition local to the executing thread, a JIT should have exclusive access to the content of the ThreadLocal. Any back-to-back set/get (or get/get) should therefore yield the same value (because no other thread can update the contents of the ThreadLocal).

However, the JMM doesn't seem to mention ThreadLocals explicitly, so perhaps a JIT would need to look at the implementation.. As a programmer I would certainly be somewhat surprised if a ThreadLocal get yielded another value than my immediately preceding set, or if my two consecutive gets would yield different values.

What kind of access patterns could you see breaking this assumption? Reflective access into Thread.threadLocals internals by clever frameworks, similar to how final fields aren't really final?

Can't do that. JIT have to update underlying hash table to correctly execute 
application.


    Also because of ThreadLocal accessors's complex code, some calls may not be 
inlined and JIT does not know what side
    effect they may have - it assumes that they can modify a value.


Not sure I'm following completely. Your concern is that the added "bulk" of ThreadLocal.get could prevent inlining? But wouldn't this suggested optimization simply replace the get with a local variable access, thus removing the bulk. Or isn't this the order inlining happens in?

Note, currently JIT does not treat ThreadLocal as something special. It will 
inline set() and get() as normal methods.
It will try to inline all hot methods which are called. For example, 
ThreadLocalMap::getEntry()
https://github.com/openjdk/jdk/blob/e1cad97049642ab201d53ff608937f7e7ef3ff3e/src/java.base/share/classes/java/lang/ThreadLocal.java#L433

It has 2 paths: miss and not miss. Depending on profile of execution getEntryAfterMiss() method may not be called or called very little. It is considered cold call site - JIT will not inline it and it does not know what it will do with hash table and values in it.

Regards,
Vladimir


Thanks,
Eirik.

Reply via email to