[External] : Re: ThreadLocal lookup elimination
Vladimir Kozlov
vladimir.kozlov at oracle.com
Fri Mar 5 19:50:14 UTC 2021
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.kozlov at oracle.com <mailto:vladimir.kozlov at 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.
More information about the core-libs-dev
mailing list