JDK-8058309 : Class loading deoptimization checks scale devastatingly poorly
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u40,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Cannot Reproduce
  • Submitted: 2014-09-12
  • Updated: 2015-05-22
  • Resolved: 2015-05-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Relates :  
Description
If you apply the prototype patch from JDK-8057967, and re-run and profile Nashorn doing the entire suite of benchmarks: 

~/trunks/jdk9-dev/build/linux-x86_64-normal-server-release/images/j2sdk-image/bin/java -jar ~/trunks/jdk9-dev/build/linux-x86_64-normal-server-release/images/j2sdk-image/jre/lib/ext/nashorn.jar -Dnashorn.typeInfo.disabled=false --class-cache-size=0 --persistent-code-cache=false -scripting --log=time test/script/basic/run-octane.js 

...then you will see this interesting subtree in profile: 

150.180	Unsafe_DefineAnonymousClass
  + 133.480	SystemDictionary::parse_stream(Symbol*,Handle,Handle,ClassFileStream*,KlassHandle,GrowableArray<Handle>*,Thread*)
     + 133.480	Universe::flush_dependents_on(instanceKlassHandle)
         + 133.220	CodeCache::mark_for_deoptimization(DepChange&)
            +133.060	InstanceKlass::mark_dependent_nmethods(DepChange&)
               + 123.730	nmethod::check_dependency_on(DepChange&)
                  + 104.530	Dependencies::DepStream::spot_check_dependency_at(DepChange&)
   + 10.150	ClassFileParser::parseClassFile(Symbol*,ClassLoaderData*,Handle,KlassHandle,GrowableArray<Handle>*,TempNewSymbol&,bool,Thread*)

Here, one can see that out of 150 seconds spent in Unsafe.defineAnonymousClass, we spend >130 seconds looking for dependees on a newly-defined class.

The offending call is at:

void SystemDictionary::add_to_hierarchy(instanceKlassHandle k, TRAPS) {
  ...
  // Now flush all code that depended on old class hierarchy.
  // Note: must be done *after* linking k into the hierarchy (was bug 12/9/97)
  // Also, first reinitialize vtable because it may have gotten out of synch
  // while the new class wasn't connected to the class hierarchy.
  Universe::flush_dependents_on(k);
}
Comments
Cannot reproduce in any sensible scenario. Please reopen if such a scenario re-occurs.
22-05-2015

After a day trying to catch this in a synthetic test, with proxies, method accessors and everything else, and the performance issue is elusive. It seems that LFs were really hitting a rather unconventional corner case. I would try a few other approaches, and if those fail, will close the issue as "Not an Issue". The latest VM patch is here: http://cr.openjdk.java.net/~shade/8058309/8058309-trace-2.patch The latest benchmarks are here: http://cr.openjdk.java.net/~shade/8058309/benchmark.zip
19-05-2015

It was suggested by Remi Forax that, proxy generation code (j.l.r.Proxy) and the method accessor generation code (j.l.r.Method) might have the same issue.
30-09-2014

With JDK-8058661 fix, the issue seem not to manifest in known workloads yet. We will make a targeted experiment, and follow up then. Meanwhile, ILW is MLH => P4.
17-09-2014

The fix for LambdaForms is forked to JDK-8058661.
17-09-2014

More accurate data on Nashorn: http://cr.openjdk.java.net/~shade/8058309/usdacdependency.txt Seems to improve the scores across the board, although first iteration is very noisy to estimate <10% improvements. Typescript seems to be affected the most.
14-09-2014

This minuscule patch decouples lambda forms from j.l.invoke.LambdaForm interface, and the entire Universe branch gets gone from Unsafe.defineAnonymousClasses: http://cr.openjdk.java.net/~shade/8058309/lf-decouple-1.patch
13-09-2014

Instrumented the relevant parts of the VM with this patch: http://cr.openjdk.java.net/~shade/8058309/8058309-trace.patch ...and this is a very typical case: http://cr.openjdk.java.net/~shade/8058309/sample-deopt.txt So, we indeed deoptimize when loading the java.lang.invoke.LambdaForm subclass, and we go ahead and track all the nmethods from there. Notice we also walk through other LFs, which might explain why the number of dependees is always growing.
12-09-2014

ILW: MMH => P3
12-09-2014