RFR(L): 8161211: better inlining support for loop bytecode intrinsics
John Rose
john.r.rose at oracle.com
Tue Sep 20 19:54:43 UTC 2016
There should also be an assert in the new LF constructor, which ensures that the two
arguments are congruent. Better yet, just supply one argument (the speciesData),
and derive the MT. These new LFs are pretty confusing, and it's best to nail down
unused degrees of freedom.
— John
P.S. I would have expected this problem to be solved by having the MHI.toArray function
return a box object with a single @Stable array field. Did that approach fail?
I.e., this wrapper emulates a frozen array (until that happy day when we have real
frozen arrays):
class ArrayConstant<T> {
private final @Stable T[] values;
public ArrayConstant(T[] values) {
for (T v : values) Objects.requireNonNull(v);
this.values = values.clone();
}
public T get(int i) { return values[i]; }
//public int length() { return values.length; }
}
The JIT should be able to constant fold through ac.get(i) whenever ac and i are constants.
On Sep 20, 2016, at 8:17 AM, Vladimir Ivanov <vladimir.x.ivanov at oracle.com> wrote:
>
> Looks good.
>
> src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java:
> + LambdaForm bmhArrayForm(MethodType type, BoundMethodHandle.SpeciesData speciesData) {
> + int size = type.parameterCount();
> + Transform key = Transform.of(Transform.BMH_AS_ARRAY, size);
> + LambdaForm form = getInCache(key);
> + if (form != null) {
> + return form;
> + }
>
> Please, add an assert to ensure the cached LF has the same constraint as requested (speciesData).
>
> Best regards,
> Vladimir Ivanov
>
> On 9/20/16 3:53 PM, Michael Haupt wrote:
>> 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
>>
>>
>>
More information about the core-libs-dev
mailing list