RFR: 8219233: 3x performance drop for some Clojure applications

David Holmes david.holmes at oracle.com
Wed Feb 27 11:37:34 UTC 2019


Hi Claes,

On 27/02/2019 5:56 pm, Claes Redestad wrote:
> Hi David,
> 
> On 2019-02-27 05:17, David Holmes wrote:
>> webrev: http://cr.openjdk.java.net/~dholmes/8219233/webrev.v2/
> 
> patch looks good to me.

Thanks for looking at this.

>> bug: https://bugs.openjdk.java.net/browse/JDK-8219233
> 
> As this is only a partial fix (about a 10% improvement in the clojure
> startup repro), I'd suggest moving it to a subtask and leaving
> JDK-8219233 open for the time being - if only to not give the false
> impression the issue is resolved in its entirety.

Yes I can do that. Though I may use the existing sub-task for this part 
and let the main bug become the C1/C2 issue that Vladimir is working on 
- the discussion is all in the comments of the main bug anyway.

Thanks,
David

> I've verified this recuperates performance completely in cases where
> we're calling into static methods from the class itself, e.g., "Bad"[1],
> and also that it doesn't help in cases where call are routed back via
> another class, e.g., "AlsoBad".
> 
> Thanks!
> 
> /Claes
> 
> [1] https://cl4es.github.io/2019/02/21/Cljinit-Woes.html
> 
>>
>> We had a bug whereby the callsite to a static method was resolved as 
>> soon as it was executed, allowing other threads to execute the same 
>> code and skip the class initialization check. The fix to that was to 
>> not do the resolution if the target class was not fully initialized. 
>> This has a consequence that calls to static methods of the current 
>> class from the <clinit> (including transitively) can't be resolved and 
>> effectively compiled and so we can take a huge performance hit for 
>> those cases (which is a rare case and regular benchmarking showed no 
>> issue). Clojure unfortunately uses a style of coding that is 
>> significantly impacted by this.
>>
>> There is a simple fix for the direct case of calling a static method 
>> from <clinit>: when we are dealing with the same class then it's okay 
>> to do the resolution as the current thread must have <clinit> on its 
>> callstack. No other thread can execute the code being resolved until 
>> the initial thread completes the static initialization.
>>
>> Unfortunately that doesn't address the main pattern used by Clojure, 
>> but we have a subtask open where Vladimir Ivanov continues to look 
>> into that case. And Claes Redestad has also given coding advice on how 
>> to avoid the problem in the first place.
>>
>> Testing: tier 1-3
>> Microbenchmarking - see bug report.
>>
>> Thanks,
>> David
>> -----


More information about the hotspot-dev mailing list