Looks even better :-) Reviewed.

Best regards,
Vladimir Ivanov

On 9/22/16 10:23 AM, Michael Haupt wrote:
Hi John,

thanks for your review, and thanks Vladimir! I've had another go at the 
implementation to use a dedicated loop clause holder class with a stable array; 
performance is roughly on par with that of the BMHs-as-arrays approach (see 
below).

The new webrev is at http://cr.openjdk.java.net/~mhaupt/8161211/webrev.01/; 
please review.

Thanks,

Michael




Benchmark        (iterations)     unpatched        patched
CntL.Cr.cr3      N/A              16039.108        15821.583
CntL.Cr.cr4      N/A              15621.959        15869.730
CntL.Inv.bl3     0                2.858            2.835
CntL.Inv.bl3     1                5.125            5.179
CntL.Inv.bl3     10               11.887           12.005
CntL.Inv.bl3     100              67.441           67.279
CntL.Inv.bl4     0                2.855            2.858
CntL.Inv.bl4     1                5.120            5.210
CntL.Inv.bl4     10               11.875           12.012
CntL.Inv.bl4     100              67.607           67.296
CntL.Inv.blMH3   0                9.734            9.722
CntL.Inv.blMH3   1                15.689           15.865
CntL.Inv.blMH3   10               68.912           69.098
CntL.Inv.blMH3   100              605.666          605.526
CntL.Inv.blMH4   0                14.561           13.274
CntL.Inv.blMH4   1                19.543           19.709
CntL.Inv.blMH4   10               71.977           72.446
CntL.Inv.blMH4   100              596.842          598.271
CntL.Inv.cntL3   0                49.339           6.311
CntL.Inv.cntL3   1                95.444           7.333
CntL.Inv.cntL3   10               508.746          20.930
CntL.Inv.cntL3   100              4701.808         147.383
CntL.Inv.cntL4   0                49.443           5.780
CntL.Inv.cntL4   1                98.721           7.465
CntL.Inv.cntL4   10               503.825          20.932
CntL.Inv.cntL4   100              4681.803         147.278
DoWhL.Cr.cr      N/A              7628.312         7803.187
DoWhL.Inv.bl     1                3.868            3.869
DoWhL.Inv.bl     10               16.480           16.528
DoWhL.Inv.bl     100              144.260          144.290
DoWhL.Inv.blMH   1                14.434           14.430
DoWhL.Inv.blMH   10               92.542           92.733
DoWhL.Inv.blMH   100              877.480          876.735
DoWhL.Inv.doWhL  1                26.791           7.134
DoWhL.Inv.doWhL  10               158.985          17.004
DoWhL.Inv.doWhL  100              1391.746         133.253
ItrL.Cr.cr       N/A              13547.499        13248.913
ItrL.Inv.bl      0                2.973            2.983
ItrL.Inv.bl      1                6.771            6.705
ItrL.Inv.bl      10               14.955           14.952
ItrL.Inv.bl      100              81.842           82.152
ItrL.Inv.blMH    0                14.893           15.014
ItrL.Inv.blMH    1                20.998           21.459
ItrL.Inv.blMH    10               73.677           73.888
ItrL.Inv.blMH    100              613.913          615.208
ItrL.Inv.itrL    0                33.583           10.842
ItrL.Inv.itrL    1                82.239           13.573
ItrL.Inv.itrL    10               448.356          38.773
ItrL.Inv.itrL    100              4189.034         279.918
L.Cr.cr          N/A              15505.970        15640.994
L.Inv0.bl        1                3.179            3.186
L.Inv0.bl        10               5.952            5.912
L.Inv0.bl        100              50.942           50.964
L.Inv0.lo        1                46.454           5.290
L.Inv0.lo        10               514.230          8.492
L.Inv0.lo        100              5166.251         52.187
L.Inv1.lo        1                34.321           5.291
L.Inv1.lo        10               430.839          8.474
L.Inv1.lo        100              4095.302         52.173
TF.blEx          N/A              3.005            2.986
TF.blMHEx        N/A              166.316          165.856
TF.blMHNor       N/A              9.337            9.290
TF.blNor         N/A              2.696            2.682
TF.cr            N/A              406.255          415.090
TF.invTFEx       N/A              154.121          154.826
TF.invTFNor      N/A              5.350            5.328
WhL.Cr.cr        N/A              12214.383        12112.535
WhL.Inv.bl       0                3.886            3.931
WhL.Inv.bl       1                5.379            5.411
WhL.Inv.bl       10               16.000           16.203
WhL.Inv.bl       100              142.066          142.127
WhL.Inv.blMH     0                11.028           10.915
WhL.Inv.blMH     1                21.269           21.419
WhL.Inv.blMH     10               97.493           98.373
WhL.Inv.blMH     100              887.579          892.955
WhL.Inv.whL      0                24.829           7.082
WhL.Inv.whL      1                46.039           8.598
WhL.Inv.whL      10               240.963          21.108
WhL.Inv.whL      100              2092.671         167.619





Am 20.09.2016 um 21:54 schrieb John Rose <john.r.r...@oracle.com>:

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.iva...@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





Reply via email to