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.