1 /*
2  * Copyright (C) 2016 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 // We make Main extend an unresolved super class. This will lead to an
18 // unresolved access to Foo.field, as we won't know if Main can access
19 // a package private field.
20 public class Main extends MissingSuperClass {
21 
main(String[] args)22   public static void main(String[] args) {
23     instanceFieldTest();
24     staticFieldTest();
25     instanceFieldTest2();
26   }
27 
28   /// CHECK-START: void Main.instanceFieldTest() inliner (before)
29   /// CHECK-NOT:    InstanceFieldSet
30 
31   /// CHECK-START: void Main.instanceFieldTest() inliner (after)
32   /// CHECK:        InstanceFieldSet
33   /// CHECK:        UnresolvedInstanceFieldGet
34 
35   // Load store elimination used to remove the InstanceFieldSet, thinking
36   // that the UnresolvedInstanceFieldGet was not related. However inlining
37   // can put you in a situation where the UnresolvedInstanceFieldGet resolves
38   // to the same field as the one in InstanceFieldSet. So the InstanceFieldSet
39   // must be preserved.
40 
41   /// CHECK-START: void Main.instanceFieldTest() load_store_elimination (after)
42   /// CHECK:        InstanceFieldSet
43   /// CHECK:        UnresolvedInstanceFieldGet
instanceFieldTest()44   public static void instanceFieldTest() {
45     Foo f = new Foo();
46     if (f.iField != 42) {
47       throw new Error("Expected 42, got " + f.iField);
48     }
49   }
50 
51   /// CHECK-START: void Main.instanceFieldTest2() inliner (before)
52   /// CHECK-NOT:    InstanceFieldSet
53   /// CHECK-NOT:    InstanceFieldGet
54 
55   /// CHECK-START: void Main.instanceFieldTest2() inliner (after)
56   /// CHECK:        InstanceFieldSet
57   /// CHECK:        InstanceFieldGet
58   /// CHECK:        UnresolvedInstanceFieldSet
59   /// CHECK:        InstanceFieldGet
60 
61   // Load store elimination will eliminate the first InstanceFieldGet because
62   // it simply follows an InstanceFieldSet. It must however not eliminate the second
63   // InstanceFieldGet, as the UnresolvedInstanceFieldSet might resolve to the same
64   // field.
65 
66   /// CHECK-START: void Main.instanceFieldTest2() load_store_elimination (after)
67   /// CHECK:        InstanceFieldSet
68   /// CHECK-NOT:    InstanceFieldGet
69   /// CHECK:        UnresolvedInstanceFieldSet
70   /// CHECK:        InstanceFieldGet
instanceFieldTest2()71   public static void instanceFieldTest2() {
72     Foo f = new Foo();
73     int a = f.$inline$GetInstanceField();
74     f.iField = 43;
75     a = f.$inline$GetInstanceField();
76     if (a != 43) {
77       throw new Error("Expected 43, got " + a);
78     }
79   }
80 
81   /// CHECK-START: void Main.staticFieldTest() inliner (before)
82   /// CHECK-NOT:    StaticFieldSet
83 
84   /// CHECK-START: void Main.staticFieldTest() inliner (after)
85   /// CHECK:        StaticFieldSet
86   /// CHECK:        StaticFieldSet
87   /// CHECK:        UnresolvedStaticFieldGet
88 
89   /// CHECK-START: void Main.staticFieldTest() load_store_elimination (after)
90   /// CHECK:        StaticFieldSet
91   /// CHECK:        UnresolvedStaticFieldGet
staticFieldTest()92   public static void staticFieldTest() {
93     // Ensure Foo is initialized.
94     Foo f = new Foo();
95     f.$inline$StaticSet42();
96     f.$inline$StaticSet43();
97     if (Foo.sField != 43) {
98       throw new Error("Expected 43, got " + Foo.sField);
99     }
100   }
101 }
102 
103 class Foo {
104   // field needs to be package-private to make the access in Main.main
105   // unresolved.
106   int iField;
107   static int sField;
108 
$inline$StaticSet42()109   public void $inline$StaticSet42() {
110     sField = 42;
111   }
112 
$inline$StaticSet43()113   public void $inline$StaticSet43() {
114     sField = 43;
115   }
116 
$inline$GetInstanceField()117   public int $inline$GetInstanceField() {
118     return iField;
119   }
120 
121   // Constructor needs to be public to get it resolved in Main.main
122   // and therefore inlined.
Foo()123   public Foo() {
124     iField = 42;
125   }
126 }
127