Dear all, please review this change. Bug: https://bugs.openjdk.java.net/browse/JDK-8161211 Webrev: http://cr.openjdk.java.net/~mhaupt/8161211/webrev.00/
The method handle loop combinators introduced with JEP 274 were originally not intrinsified, leading to poor performance as compared to a pure-Java baseline, but also to handwired method handle combinations. The intrinsics introduced with 8143211 [1] improved on the situation somewhat, but still did not provide good inlining opportunities for the JIT compiler. This change introduces a usage of BoundMethodHandles as arrays to carry the various handles involved in loop execution. Extra credits to Vladimir Ivanov, who suggested the BMH-as-arrays approach in the first place, and Claes Redestad, who suggested to use LambdaForm editing to neatly enable caching. Thanks! Performance improves considerably. The table below reports scores in ns/op. The "unpatched" column contains results from before applying the patch for 8161211; the "patched" column, from thereafter. The create benchmarks measure the cost of loop handle creation. The baseline and baselineMH benchmarks measure the cost of running a pure Java and handwired method handle construct. Relevant comparisons include loop combinator results versus baselines, and versus unpatched loop combinator results. For the latter, there are significant improvements, except for the creation benchmarks (creation has a more complex workflow now). For the former, it can be seen that the BMH-array intrinsics generally perform better than handwired handle constructs, and have moved much closer to. Thanks, Michael [1] https://bugs.openjdk.java.net/browse/JDK-8143211 Benchmark (iterations) unpatched patched MethodHandlesCountedLoop.Create.create3 N/A 16039.108 18400.405 MethodHandlesCountedLoop.Create.create4 N/A 15621.959 17924.696 MethodHandlesCountedLoop.Invoke.baseline3 0 2.858 2.839 MethodHandlesCountedLoop.Invoke.baseline3 1 5.125 5.164 MethodHandlesCountedLoop.Invoke.baseline3 10 11.887 11.924 MethodHandlesCountedLoop.Invoke.baseline3 100 67.441 67.281 MethodHandlesCountedLoop.Invoke.baseline4 0 2.855 2.838 MethodHandlesCountedLoop.Invoke.baseline4 1 5.120 5.179 MethodHandlesCountedLoop.Invoke.baseline4 10 11.875 11.906 MethodHandlesCountedLoop.Invoke.baseline4 100 67.607 67.374 MethodHandlesCountedLoop.Invoke.baselineMH3 0 9.734 9.606 MethodHandlesCountedLoop.Invoke.baselineMH3 1 15.689 15.674 MethodHandlesCountedLoop.Invoke.baselineMH3 10 68.912 69.303 MethodHandlesCountedLoop.Invoke.baselineMH3 100 605.666 606.432 MethodHandlesCountedLoop.Invoke.baselineMH4 0 14.561 13.234 MethodHandlesCountedLoop.Invoke.baselineMH4 1 19.543 19.773 MethodHandlesCountedLoop.Invoke.baselineMH4 10 71.977 72.466 MethodHandlesCountedLoop.Invoke.baselineMH4 100 596.842 602.469 MethodHandlesCountedLoop.Invoke.countedLoop3 0 49.339 5.810 MethodHandlesCountedLoop.Invoke.countedLoop3 1 95.444 7.441 MethodHandlesCountedLoop.Invoke.countedLoop3 10 508.746 21.002 MethodHandlesCountedLoop.Invoke.countedLoop3 100 4701.808 145.996 MethodHandlesCountedLoop.Invoke.countedLoop4 0 49.443 5.798 MethodHandlesCountedLoop.Invoke.countedLoop4 1 98.721 7.438 MethodHandlesCountedLoop.Invoke.countedLoop4 10 503.825 21.049 MethodHandlesCountedLoop.Invoke.countedLoop4 100 4681.803 147.020 MethodHandlesDoWhileLoop.Create.create N/A 7628.312 9100.332 MethodHandlesDoWhileLoop.Invoke.baseline 1 3.868 3.909 MethodHandlesDoWhileLoop.Invoke.baseline 10 16.480 16.461 MethodHandlesDoWhileLoop.Invoke.baseline 100 144.260 144.232 MethodHandlesDoWhileLoop.Invoke.baselineMH 1 14.434 14.494 MethodHandlesDoWhileLoop.Invoke.baselineMH 10 92.542 93.454 MethodHandlesDoWhileLoop.Invoke.baselineMH 100 877.480 880.496 MethodHandlesDoWhileLoop.Invoke.doWhileLoop 1 26.791 7.153 MethodHandlesDoWhileLoop.Invoke.doWhileLoop 10 158.985 16.990 MethodHandlesDoWhileLoop.Invoke.doWhileLoop 100 1391.746 130.946 MethodHandlesIteratedLoop.Create.create N/A 13547.499 15478.542 MethodHandlesIteratedLoop.Invoke.baseline 0 2.973 2.980 MethodHandlesIteratedLoop.Invoke.baseline 1 6.771 6.658 MethodHandlesIteratedLoop.Invoke.baseline 10 14.955 14.955 MethodHandlesIteratedLoop.Invoke.baseline 100 81.842 82.582 MethodHandlesIteratedLoop.Invoke.baselineMH 0 14.893 14.668 MethodHandlesIteratedLoop.Invoke.baselineMH 1 20.998 21.304 MethodHandlesIteratedLoop.Invoke.baselineMH 10 73.677 72.703 MethodHandlesIteratedLoop.Invoke.baselineMH 100 613.913 614.475 MethodHandlesIteratedLoop.Invoke.iteratedLoop 0 33.583 9.603 MethodHandlesIteratedLoop.Invoke.iteratedLoop 1 82.239 14.433 MethodHandlesIteratedLoop.Invoke.iteratedLoop 10 448.356 38.650 MethodHandlesIteratedLoop.Invoke.iteratedLoop 100 4189.034 279.779 MethodHandlesLoop.Create.create N/A 15505.970 17559.399 MethodHandlesLoop.Invoke0.baseline 1 3.179 3.181 MethodHandlesLoop.Invoke0.baseline 10 5.952 6.115 MethodHandlesLoop.Invoke0.baseline 100 50.942 50.943 MethodHandlesLoop.Invoke0.loop 1 46.454 5.353 MethodHandlesLoop.Invoke0.loop 10 514.230 8.487 MethodHandlesLoop.Invoke0.loop 100 5166.251 52.188 MethodHandlesLoop.Invoke1.loop 1 34.321 5.277 MethodHandlesLoop.Invoke1.loop 10 430.839 8.481 MethodHandlesLoop.Invoke1.loop 100 4095.302 52.206 MethodHandlesTryFinally.baselineExceptional N/A 3.005 3.002 MethodHandlesTryFinally.baselineMHExceptional N/A 166.316 166.087 MethodHandlesTryFinally.baselineMHNormal N/A 9.337 9.276 MethodHandlesTryFinally.baselineNormal N/A 2.696 2.683 MethodHandlesTryFinally.create N/A 406.255 406.594 MethodHandlesTryFinally.invokeTryFinallyExceptional N/A 154.121 154.692 MethodHandlesTryFinally.invokeTryFinallyNormal N/A 5.350 5.334 MethodHandlesWhileLoop.Create.create N/A 12214.383 14503.515 MethodHandlesWhileLoop.Invoke.baseline 0 3.886 3.888 MethodHandlesWhileLoop.Invoke.baseline 1 5.379 5.377 MethodHandlesWhileLoop.Invoke.baseline 10 16.000 16.201 MethodHandlesWhileLoop.Invoke.baseline 100 142.066 143.338 MethodHandlesWhileLoop.Invoke.baselineMH 0 11.028 11.012 MethodHandlesWhileLoop.Invoke.baselineMH 1 21.269 21.159 MethodHandlesWhileLoop.Invoke.baselineMH 10 97.493 97.656 MethodHandlesWhileLoop.Invoke.baselineMH 100 887.579 886.532 MethodHandlesWhileLoop.Invoke.whileLoop 0 24.829 7.108 MethodHandlesWhileLoop.Invoke.whileLoop 1 46.039 8.573 MethodHandlesWhileLoop.Invoke.whileLoop 10 240.963 21.088 MethodHandlesWhileLoop.Invoke.whileLoop 100 2092.671 159.016 -- <http://www.oracle.com/> Dr. Michael Haupt | Principal Member of Technical Staff Phone: +49 331 200 7277 | Fax: +49 331 200 7561 Oracle Java Platform Group | LangTools Team | Nashorn Oracle Deutschland B.V. & Co. KG | Schiffbauergasse 14 | 14467 Potsdam, Germany ORACLE Deutschland B.V. & Co. KG | Hauptverwaltung: Riesstraße 25, D-80992 München Registergericht: Amtsgericht München, HRA 95603 Komplementärin: ORACLE Deutschland Verwaltung B.V. | Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Nederland, Nr. 30143697 Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher <http://www.oracle.com/commitment> Oracle is committed to developing practices and products that help protect the environment