1 /*
2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.core.test;
26 
27 import org.graalvm.compiler.api.directives.GraalDirectives;
28 import org.graalvm.compiler.core.common.type.StampFactory;
29 import org.graalvm.compiler.core.common.type.StampPair;
30 import org.graalvm.compiler.core.common.type.TypeReference;
31 import org.graalvm.compiler.nodes.ParameterNode;
32 import org.graalvm.compiler.nodes.PiNode;
33 import org.graalvm.compiler.nodes.StructuredGraph;
34 import org.junit.Before;
35 import org.junit.Test;
36 
37 import jdk.vm.ci.meta.ResolvedJavaMethod;
38 
39 /**
40  * Check that multiple bounds checks are correctly grouped together.
41  */
42 public class ConditionalEliminationTest16 extends ConditionalEliminationTestBase {
43 
44     @Before
resetType()45     public void resetType() {
46         parameterType = null;
47     }
48 
49     Class<?> parameterType;
50 
testCastExactInstance(Object object)51     public static int testCastExactInstance(Object object) {
52         if (object.getClass() == Integer.class) {
53             return ((Integer) object).intValue();
54         }
55         GraalDirectives.deoptimizeAndInvalidate();
56         return -1;
57     }
58 
59     @Override
checkHighTierGraph(StructuredGraph graph)60     protected void checkHighTierGraph(StructuredGraph graph) {
61         if (parameterType != null) {
62             for (ParameterNode param : graph.getNodes().filter(ParameterNode.class)) {
63                 if (param.index() == 0) {
64                     ParameterNode newParam = new ParameterNode(0, StampPair.createSingle(StampFactory.object(TypeReference.createExactTrusted(getMetaAccess().lookupJavaType(parameterType)))));
65                     graph.addWithoutUnique(newParam);
66                     param.replaceAtUsages(newParam);
67                     param.safeDelete();
68                     break;
69                 }
70             }
71             this.createCanonicalizerPhase().apply(graph, getDefaultHighTierContext());
72         }
73         super.checkHighTierGraph(graph);
74     }
75 
76     @Override
checkMidTierGraph(StructuredGraph graph)77     protected void checkMidTierGraph(StructuredGraph graph) {
78         int count = 0;
79         for (PiNode node : graph.getNodes().filter(PiNode.class)) {
80             assertTrue(node.getGuard() != null, "must have guarding node");
81             count++;
82         }
83         assertTrue(count > 0, "expected at least one Pi");
84         super.checkMidTierGraph(graph);
85     }
86 
87     @Test
test1()88     public void test1() {
89         parameterType = Integer.class;
90         ResolvedJavaMethod method = getResolvedJavaMethod("testCastExactInstance");
91         StructuredGraph graph = parseForCompile(method);
92         compile(method, graph);
93     }
94 
95     static class Base {
getValue1()96         int getValue1() {
97             return 0;
98         }
99 
getBase()100         Base getBase() {
101             return this;
102         }
103     }
104 
105     static class Box extends Base {
106         int value1;
107 
108         @Override
getValue1()109         int getValue1() {
110             return value1;
111         }
112     }
113 
114     static class BiggerBox extends Box {
115         int value2;
116 
getValue2()117         int getValue2() {
118             return value2;
119         }
120     }
121 
testCastExactTwiceInstance(Base base, boolean b)122     public static int testCastExactTwiceInstance(Base base, boolean b) {
123         if (!(base instanceof Box)) {
124             GraalDirectives.deoptimizeAndInvalidate();
125             return -1;
126         }
127         int total = 0;
128         if (base instanceof Box) {
129             Box box = (Box) base;
130             total += box.value1;
131             if (b) {
132                 total += System.identityHashCode(base);
133             }
134             total += ((BiggerBox) base).getValue2();
135         }
136         return total;
137     }
138 
139     @Test
test2()140     public void test2() {
141         BiggerBox box = new BiggerBox();
142         ResolvedJavaMethod method = getResolvedJavaMethod("testCastExactTwiceInstance");
143         StructuredGraph graph = parseForCompile(method);
144         compile(method, graph);
145         test("testCastExactTwiceInstance", box, false);
146     }
147 }
148