1 /*
2  * Copyright (C) 2022 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 // Check that we have only one call before the inliner.
18 
19 /// CHECK-START: boolean BaseClassWrapper.recursiveTwoWrappers() inliner (before)
20 /// CHECK:       InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
21 /// CHECK-NOT:   InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
22 
23 // After the inliner we will have:
24 // if (receiver == BaseClassAnotherWrapper) {
25 //  // At this point we have no way to know that the Invoke was going
26 //  // to be a recursive one, but it cuts at the first iteration.
27 //   if (receiver == BaseClassNoRecursion) {
28 //     return false;
29 //   } else {
30 //     HInvokeVirtual
31 //   }
32 // } else if (receiver == BaseClassNoRecursion) {
33 //   return false;
34 // } else {
35 //   HInvokeVirtual
36 // }
37 
38 // We should see LoadClasses for BaseClassNoRecursion, and BaseClassAnotherWrapper<BaseClassNoRecursion>, in some order.
39 /// CHECK-START: boolean BaseClassWrapper.recursiveTwoWrappers() inliner (after)
40 /// CHECK-DAG:   LoadClass load_kind:BssEntry class_name:BaseClassAnotherWrapper
41 /// CHECK-DAG:   LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
42 /// CHECK-DAG:   LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
43 
44 // We should see the two HInvokeVirtual that appear in the above comment.
45 /// CHECK-START: boolean BaseClassWrapper.recursiveTwoWrappers() inliner (after)
46 /// CHECK:       InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
47 /// CHECK:       InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
48 /// CHECK-NOT:   InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
49 class BaseClassWrapper extends BaseClass {
50   protected final BaseClass mBaseClass;
51 
BaseClassWrapper(BaseClass BaseClass)52   public BaseClassWrapper(BaseClass BaseClass) {
53     mBaseClass = BaseClass;
54   }
55 
recursiveTwoWrappers()56   boolean recursiveTwoWrappers() {
57     return mBaseClass.recursiveTwoWrappers();
58   }
59 }
60 
61 // Same thing here as above but swapping BaseClassWrapper and BaseClassAnotherWrapper.
62 
63 /// CHECK-START: boolean BaseClassAnotherWrapper.recursiveTwoWrappers() inliner (after)
64 /// CHECK-DAG:   LoadClass load_kind:BssEntry class_name:BaseClassWrapper
65 /// CHECK-DAG:   LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
66 /// CHECK-DAG:   LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
67 
68 /// CHECK-START: boolean BaseClassAnotherWrapper.recursiveTwoWrappers() inliner (after)
69 /// CHECK:       InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
70 /// CHECK:       InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
71 /// CHECK-NOT:   InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
72 class BaseClassAnotherWrapper extends BaseClass {
73   protected final BaseClass mBaseClass;
74 
BaseClassAnotherWrapper(BaseClass BaseClass)75   public BaseClassAnotherWrapper(BaseClass BaseClass) {
76     mBaseClass = BaseClass;
77   }
78 
recursiveTwoWrappers()79   boolean recursiveTwoWrappers() {
80     return mBaseClass.recursiveTwoWrappers();
81   }
82 }
83 
84 class BaseClassNoRecursion extends BaseClass {
recursiveTwoWrappers()85   boolean recursiveTwoWrappers() {
86     return false;
87   }
88 }
89 
90 // Check that we have only one call before the inliner.
91 
92 /// CHECK-START: boolean BaseClassShallowWrapper.recursiveShallow() inliner (before)
93 /// CHECK:       InvokeVirtual method_name:BaseClassShallow.recursiveShallow
94 /// CHECK-NOT:   InvokeVirtual method_name:BaseClassShallow.recursiveShallow
95 
96 // After the inliner we will have
97 // if (receiver == BaseClassShallowNoRecursion) {
98 //  return false;
99 // } else {
100 //   HInvokeVirtual
101 // }
102 
103 /// CHECK-START: boolean BaseClassShallowWrapper.recursiveShallow() inliner (after)
104 /// CHECK:       LoadClass load_kind:BssEntry class_name:BaseClassShallowNoRecursion
105 /// CHECK:       InvokeVirtual method_name:BaseClassShallow.recursiveShallow
106 /// CHECK-NOT:   InvokeVirtual method_name:BaseClassShallow.recursiveShallow
107 class BaseClassShallowWrapper extends BaseClassShallow {
108   protected final BaseClassShallow mBaseClassShallow;
109 
BaseClassShallowWrapper(BaseClassShallow BaseClassShallow)110   public BaseClassShallowWrapper(BaseClassShallow BaseClassShallow) {
111     mBaseClassShallow = BaseClassShallow;
112   }
113 
recursiveShallow()114   boolean recursiveShallow() {
115     return mBaseClassShallow.recursiveShallow();
116   }
117 }
118 
119 class BaseClassShallowNoRecursion extends BaseClassShallow {
recursiveShallow()120   boolean recursiveShallow() {
121     return false;
122   }
123 }
124 
125 public class Main {
main(String[] args)126   public static void main(String[] args) {}
127 }