Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 // TODO: Add more tests after we can inline functions with calls.
     18 
     19 class ClassWithoutFinals {
     20   /// CHECK-START: void ClassWithoutFinals.<init>() inliner (after)
     21   /// CHECK-NOT: ConstructorFence
     22   public ClassWithoutFinals() {}
     23 }
     24 
     25 class ClassWithFinals {
     26   public final int x;
     27   public ClassWithFinals obj;
     28   public static boolean doThrow = false;
     29 
     30   public ClassWithFinals(boolean cond) {
     31     x = 1;
     32     throw new RuntimeException();
     33     // should not inline this constructor
     34   }
     35 
     36   /// CHECK-START: void ClassWithFinals.<init>() inliner (after)
     37   /// CHECK:      ConstructorFence
     38   /// CHECK-NOT:  ConstructorFence
     39 
     40   /*
     41    * Check that the correct assembly instructions are selected for a Store/Store fence.
     42    *
     43    * - ARM variants:   DMB ISHST (store-store fence for inner shareable domain)
     44    * - Intel variants: no-op (store-store does not need a fence).
     45    */
     46 
     47   /// CHECK-START-ARM64: void ClassWithFinals.<init>() disassembly (after)
     48   /// CHECK:      ConstructorFence
     49   /// CHECK-NEXT: dmb ishst
     50 
     51   /// CHECK-START-ARM: void ClassWithFinals.<init>() disassembly (after)
     52   /// CHECK:      ConstructorFence
     53   /// CHECK-NEXT: dmb ishst
     54 
     55   /// CHECK-START-X86_64: void ClassWithFinals.<init>() disassembly (after)
     56   /// CHECK:      ConstructorFence
     57   /// CHECK-NOT:  {{[slm]}}fence
     58 
     59   /// CHECK-START-X86: void ClassWithFinals.<init>() disassembly (after)
     60   /// CHECK:      ConstructorFence
     61   /// CHECK-NOT:  {{[slm]}}fence
     62   public ClassWithFinals() {
     63     // Exactly one constructor barrier.
     64     x = 0;
     65   }
     66 
     67   /// CHECK-START: void ClassWithFinals.<init>(int) inliner (after)
     68   /// CHECK: <<This:l\d+>>            ParameterValue
     69   /// CHECK: <<NewInstance:l\d+>>     NewInstance
     70   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
     71   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
     72   /// CHECK-DAG:                      ConstructorFence [<<This>>]
     73   /// CHECK-NOT:                      ConstructorFence
     74   public ClassWithFinals(int x) {
     75     // This should have exactly three barriers:
     76     //   - one for the new-instance
     77     //   - one for the constructor
     78     //   - one for the `new` which should be inlined.
     79     obj = new ClassWithFinals();
     80     this.x = x;
     81   }
     82 }
     83 
     84 class InheritFromClassWithFinals extends ClassWithFinals {
     85   /// CHECK-START: void InheritFromClassWithFinals.<init>() inliner (after)
     86   /// CHECK: <<This:l\d+>>            ParameterValue
     87   /// CHECK:                          ConstructorFence [<<This>>]
     88   /// CHECK-NOT:                      ConstructorFence
     89 
     90   /// CHECK-START: void InheritFromClassWithFinals.<init>() inliner (after)
     91   /// CHECK-NOT:  InvokeStaticOrDirect
     92   public InheritFromClassWithFinals() {
     93     // Should inline the super constructor.
     94     //
     95     // Exactly one constructor barrier here.
     96   }
     97 
     98   /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) inliner (after)
     99   /// CHECK:      InvokeStaticOrDirect
    100 
    101   /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) inliner (after)
    102   /// CHECK-NOT:  ConstructorFence
    103   public InheritFromClassWithFinals(boolean cond) {
    104     super(cond);
    105     // should not inline the super constructor
    106   }
    107 
    108   /// CHECK-START: void InheritFromClassWithFinals.<init>(int) inliner (after)
    109   /// CHECK: <<This:l\d+>>            ParameterValue
    110   /// CHECK-DAG: <<NewHere:l\d+>>     NewInstance klass:InheritFromClassWithFinals
    111   /// CHECK-DAG:                      ConstructorFence [<<This>>]
    112   /// CHECK-DAG:                      ConstructorFence [<<NewHere>>]
    113   /// CHECK-DAG:                      ConstructorFence [<<NewHere>>]
    114   /// CHECK-NOT:                      ConstructorFence
    115 
    116   /// CHECK-START: void InheritFromClassWithFinals.<init>(int) inliner (after)
    117   /// CHECK-NOT:  InvokeStaticOrDirect
    118   public InheritFromClassWithFinals(int unused) {
    119     // super();  // implicitly the first invoke in this constructor.
    120     //   Should inline the super constructor and insert a constructor fence there.
    121 
    122     // Should inline the new instance call (barrier); and add another one
    123     // because the superclass has finals.
    124     new InheritFromClassWithFinals();
    125   }
    126 }
    127 
    128 class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals {
    129   final int y;
    130 
    131   /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() inliner (after)
    132   /// CHECK: <<This:l\d+>>            ParameterValue
    133   /// CHECK:                          ConstructorFence [<<This>>]
    134   /// CHECK:                          ConstructorFence [<<This>>]
    135   /// CHECK-NOT:                      ConstructorFence
    136 
    137   /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() inliner (after)
    138   /// CHECK-NOT: InvokeStaticOrDirect
    139   public HaveFinalsAndInheritFromClassWithFinals() {
    140     // Should inline the super constructor and keep the memory barrier.
    141     y = 0;
    142   }
    143 
    144   /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) inliner (after)
    145   /// CHECK: <<This:l\d+>>            ParameterValue
    146   /// CHECK:                          InvokeStaticOrDirect
    147   /// CHECK:                          ConstructorFence [<<This>>]
    148   /// CHECK-NOT:                      ConstructorFence
    149   public HaveFinalsAndInheritFromClassWithFinals(boolean cond) {
    150     super(cond);
    151     // should not inline the super constructor
    152     y = 0;
    153   }
    154 
    155   /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) inliner (after)
    156   /// CHECK: <<This:l\d+>>            ParameterValue
    157   /// CHECK-DAG: <<NewHF:l\d+>>       NewInstance klass:HaveFinalsAndInheritFromClassWithFinals
    158   /// CHECK-DAG: <<NewIF:l\d+>>       NewInstance klass:InheritFromClassWithFinals
    159   /// CHECK-DAG:                      ConstructorFence [<<This>>]
    160   /// CHECK-DAG:                      ConstructorFence [<<NewHF>>]
    161   /// CHECK-DAG:                      ConstructorFence [<<NewHF>>]
    162   /// CHECK-DAG:                      ConstructorFence [<<NewHF>>]
    163   /// CHECK-DAG:                      ConstructorFence [<<NewIF>>]
    164   /// CHECK-DAG:                      ConstructorFence [<<NewIF>>]
    165   /// CHECK-DAG:                      ConstructorFence [<<This>>]
    166   /// CHECK-NOT:                      ConstructorFence
    167 
    168   /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) inliner (after)
    169   /// CHECK-NOT:  InvokeStaticOrDirect
    170   public HaveFinalsAndInheritFromClassWithFinals(int unused) {
    171     // super()
    172     // -- Inlined super constructor, insert memory barrier here.
    173     y = 0;
    174 
    175     // Should inline new instance and keep both memory barriers.
    176     // One more memory barrier for new-instance.
    177     // (3 total for this new-instance #1)
    178     new HaveFinalsAndInheritFromClassWithFinals();
    179     // Should inline new instance and have exactly one barrier.
    180     // One more barrier for new-instance.
    181     // (2 total for this new-instance #2)
    182     new InheritFromClassWithFinals();
    183 
    184     // -- End of constructor, insert memory barrier here to freeze 'y'.
    185   }
    186 }
    187 
    188 public class Main {
    189 
    190   /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() inliner (after)
    191   /// CHECK:      InvokeStaticOrDirect
    192 
    193   /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() inliner (after)
    194   /// CHECK: <<NewInstance:l\d+>>     NewInstance
    195   /// CHECK:                          ConstructorFence [<<NewInstance>>]
    196   /// CHECK-NOT:                      ConstructorFence
    197   public static ClassWithFinals noInlineNoConstructorBarrier() {
    198     // Exactly one barrier for the new-instance.
    199     return new ClassWithFinals(false);
    200     // should not inline the constructor
    201   }
    202 
    203   /// CHECK-START: void Main.inlineNew() inliner (after)
    204   /// CHECK: <<NewInstance:l\d+>>     NewInstance
    205   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    206   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    207   /// CHECK-NOT:                      ConstructorFence
    208 
    209   /// CHECK-START: void Main.inlineNew() inliner (after)
    210   /// CHECK-NOT:  InvokeStaticOrDirect
    211   public static void inlineNew() {
    212     // Exactly 2 barriers. One for new-instance, one for constructor with finals.
    213     new ClassWithFinals();
    214   }
    215 
    216   /// CHECK-START: void Main.inlineNew1() inliner (after)
    217   /// CHECK: <<NewInstance:l\d+>>     NewInstance
    218   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    219   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    220   /// CHECK-NOT:                      ConstructorFence
    221 
    222   /// CHECK-START: void Main.inlineNew1() inliner (after)
    223   /// CHECK-NOT:  InvokeStaticOrDirect
    224   public static void inlineNew1() {
    225     new InheritFromClassWithFinals();
    226   }
    227 
    228   /// CHECK-START: void Main.inlineNew2() inliner (after)
    229   /// CHECK: <<NewInstance:l\d+>>     NewInstance
    230   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    231   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    232   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    233   /// CHECK-NOT:                      ConstructorFence
    234 
    235   /// CHECK-START: void Main.inlineNew2() inliner (after)
    236   /// CHECK-NOT:  InvokeStaticOrDirect
    237   public static void inlineNew2() {
    238     new HaveFinalsAndInheritFromClassWithFinals();
    239   }
    240 
    241   /// CHECK-START: void Main.inlineNew3() inliner (after)
    242   /// CHECK: <<NewInstance:l\d+>>     NewInstance
    243   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    244   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    245   /// CHECK-DAG:                      ConstructorFence [<<NewInstance>>]
    246   /// CHECK-NOT:                      ConstructorFence
    247   /// CHECK: <<NewInstance2:l\d+>>    NewInstance
    248   /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
    249   /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
    250   /// CHECK-DAG:                      ConstructorFence [<<NewInstance2>>]
    251   /// CHECK-NOT:                      ConstructorFence
    252 
    253   /// CHECK-START: void Main.inlineNew3() inliner (after)
    254   /// CHECK-NOT:  InvokeStaticOrDirect
    255   public static void inlineNew3() {
    256     new HaveFinalsAndInheritFromClassWithFinals();
    257     new HaveFinalsAndInheritFromClassWithFinals();
    258   }
    259 
    260   static int[] mCodePointsEmpty = new int[0];
    261 
    262   /// CHECK-START: void Main.testNewString() inliner (after)
    263   /// CHECK-NOT:  ConstructorFence
    264   /// CHECK:      InvokeStaticOrDirect method_load_kind:StringInit
    265   /// CHECK-NOT:  ConstructorFence
    266   /// CHECK-NOT:  InvokeStaticOrDirect
    267   public static void testNewString() {
    268     // Strings are special because of StringFactory hackeries.
    269     //
    270     // Assume they handle their own fencing internally in the StringFactory.
    271     int[] codePoints = null;
    272     String some_new_string = new String(mCodePointsEmpty, 0, 0);
    273   }
    274 
    275   public static void main(String[] args) {}
    276 }
    277