summaryrefslogtreecommitdiff
path: root/test/2238-checker-polymorphic-recursive-inlining/src/Main.java
diff options
context:
space:
mode:
Diffstat (limited to 'test/2238-checker-polymorphic-recursive-inlining/src/Main.java')
-rw-r--r--test/2238-checker-polymorphic-recursive-inlining/src/Main.java127
1 files changed, 127 insertions, 0 deletions
diff --git a/test/2238-checker-polymorphic-recursive-inlining/src/Main.java b/test/2238-checker-polymorphic-recursive-inlining/src/Main.java
new file mode 100644
index 0000000000..adf6e2a248
--- /dev/null
+++ b/test/2238-checker-polymorphic-recursive-inlining/src/Main.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Check that we have only one call before the inliner.
+
+/// CHECK-START: boolean BaseClassWrapper.recursiveTwoWrappers() inliner (before)
+/// CHECK: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+/// CHECK-NOT: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+
+// After the inliner we will have:
+// if (receiver == BaseClassAnotherWrapper) {
+// // At this point we have no way to know that the Invoke was going
+// // to be a recursive one, but it cuts at the first iteration.
+// if (receiver == BaseClassNoRecursion) {
+// return false;
+// } else {
+// HInvokeVirtual
+// }
+// } else if (receiver == BaseClassNoRecursion) {
+// return false;
+// } else {
+// HInvokeVirtual
+// }
+
+// We should see LoadClasses for BaseClassNoRecursion, and BaseClassAnotherWrapper<BaseClassNoRecursion>, in some order.
+/// CHECK-START: boolean BaseClassWrapper.recursiveTwoWrappers() inliner (after)
+/// CHECK-DAG: LoadClass load_kind:BssEntry class_name:BaseClassAnotherWrapper
+/// CHECK-DAG: LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
+/// CHECK-DAG: LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
+
+// We should see the two HInvokeVirtual that appear in the above comment.
+/// CHECK-START: boolean BaseClassWrapper.recursiveTwoWrappers() inliner (after)
+/// CHECK: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+/// CHECK: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+/// CHECK-NOT: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+class BaseClassWrapper extends BaseClass {
+ protected final BaseClass mBaseClass;
+
+ public BaseClassWrapper(BaseClass BaseClass) {
+ mBaseClass = BaseClass;
+ }
+
+ boolean recursiveTwoWrappers() {
+ return mBaseClass.recursiveTwoWrappers();
+ }
+}
+
+// Same thing here as above but swapping BaseClassWrapper and BaseClassAnotherWrapper.
+
+/// CHECK-START: boolean BaseClassAnotherWrapper.recursiveTwoWrappers() inliner (after)
+/// CHECK-DAG: LoadClass load_kind:BssEntry class_name:BaseClassWrapper
+/// CHECK-DAG: LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
+/// CHECK-DAG: LoadClass load_kind:BssEntry class_name:BaseClassNoRecursion
+
+/// CHECK-START: boolean BaseClassAnotherWrapper.recursiveTwoWrappers() inliner (after)
+/// CHECK: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+/// CHECK: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+/// CHECK-NOT: InvokeVirtual method_name:BaseClass.recursiveTwoWrappers
+class BaseClassAnotherWrapper extends BaseClass {
+ protected final BaseClass mBaseClass;
+
+ public BaseClassAnotherWrapper(BaseClass BaseClass) {
+ mBaseClass = BaseClass;
+ }
+
+ boolean recursiveTwoWrappers() {
+ return mBaseClass.recursiveTwoWrappers();
+ }
+}
+
+class BaseClassNoRecursion extends BaseClass {
+ boolean recursiveTwoWrappers() {
+ return false;
+ }
+}
+
+// Check that we have only one call before the inliner.
+
+/// CHECK-START: boolean BaseClassShallowWrapper.recursiveShallow() inliner (before)
+/// CHECK: InvokeVirtual method_name:BaseClassShallow.recursiveShallow
+/// CHECK-NOT: InvokeVirtual method_name:BaseClassShallow.recursiveShallow
+
+// After the inliner we will have
+// if (receiver == BaseClassShallowNoRecursion) {
+// return false;
+// } else {
+// HInvokeVirtual
+// }
+
+/// CHECK-START: boolean BaseClassShallowWrapper.recursiveShallow() inliner (after)
+/// CHECK: LoadClass load_kind:BssEntry class_name:BaseClassShallowNoRecursion
+/// CHECK: InvokeVirtual method_name:BaseClassShallow.recursiveShallow
+/// CHECK-NOT: InvokeVirtual method_name:BaseClassShallow.recursiveShallow
+class BaseClassShallowWrapper extends BaseClassShallow {
+ protected final BaseClassShallow mBaseClassShallow;
+
+ public BaseClassShallowWrapper(BaseClassShallow BaseClassShallow) {
+ mBaseClassShallow = BaseClassShallow;
+ }
+
+ boolean recursiveShallow() {
+ return mBaseClassShallow.recursiveShallow();
+ }
+}
+
+class BaseClassShallowNoRecursion extends BaseClassShallow {
+ boolean recursiveShallow() {
+ return false;
+ }
+}
+
+public class Main {
+ public static void main(String[] args) {}
+} \ No newline at end of file