Fri, 26 Apr 2013 07:21:41 -0700
8012322: Tiered: CompilationPolicy::can_be_compiled(CompLevel_all) mistakenly return false
Reviewed-by: kvn, vlivanov
1 /*
2 * Copyright (c) 2013, 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 */
24 /*
25 * @test MakeMethodNotCompilableTest
26 * @bug 8012322
27 * @library /testlibrary /testlibrary/whitebox
28 * @build MakeMethodNotCompilableTest
29 * @run main ClassFileInstaller sun.hotspot.WhiteBox
30 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
31 * @summary testing of WB::makeMethodNotCompilable()
32 * @author igor.ignatyev@oracle.com
33 */
34 public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
36 public static void main(String[] args) throws Exception {
37 if (args.length == 0) {
38 for (TestCase test : TestCase.values()) {
39 new MakeMethodNotCompilableTest(test).runTest();
40 }
41 } else {
42 for (String name : args) {
43 new MakeMethodNotCompilableTest(
44 TestCase.valueOf(name)).runTest();
45 }
46 }
47 }
49 public MakeMethodNotCompilableTest(TestCase testCase) {
50 super(testCase);
51 // to prevent inlining of #method
52 WHITE_BOX.testSetDontInlineMethod(method, true);
53 }
55 /**
56 * Tests {@code WB::makeMethodNotCompilable()} by calling it before
57 * compilation and checking that method isn't compiled. Also
58 * checks that WB::clearMethodState() clears no-compilable flags. For
59 * tiered, additional checks for all available levels are conducted.
60 *
61 * @throws Exception if one of the checks fails.
62 */
63 @Override
64 protected void test() throws Exception {
65 checkNotCompiled();
66 if (!WHITE_BOX.isMethodCompilable(method)) {
67 throw new RuntimeException(method + " must be compilable");
68 }
70 if (TIERED_COMPILATION) {
71 final int tierLimit = TIERED_STOP_AT_LEVEL + 1;
72 for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
73 testTier(testedTier);
74 }
75 for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
76 WHITE_BOX.makeMethodNotCompilable(method, testedTier);
77 if (WHITE_BOX.isMethodCompilable(method, testedTier)) {
78 throw new RuntimeException(method
79 + " must be not compilable at level" + testedTier);
80 }
81 WHITE_BOX.enqueueMethodForCompilation(method, testedTier);
82 checkNotCompiled();
84 if (!WHITE_BOX.isMethodCompilable(method)) {
85 System.out.println(method
86 + " is not compilable after level " + testedTier);
87 }
88 }
89 } else {
90 compile();
91 checkCompiled();
92 int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
93 WHITE_BOX.deoptimizeMethod(method);
94 WHITE_BOX.makeMethodNotCompilable(method, compLevel);
95 if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
96 throw new RuntimeException(method
97 + " must be not compilable at CompLevel::CompLevel_any,"
98 + " after it is not compilable at " + compLevel);
99 }
100 WHITE_BOX.clearMethodState(method);
102 // nocompilable at opposite level must make no sense
103 int oppositeLevel;
104 if (isC1Compile(compLevel)) {
105 oppositeLevel = COMP_LEVEL_FULL_OPTIMIZATION;
106 } else {
107 oppositeLevel = COMP_LEVEL_SIMPLE;
108 }
109 WHITE_BOX.makeMethodNotCompilable(method, oppositeLevel);
111 if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
112 throw new RuntimeException(method
113 + " must be compilable at CompLevel::CompLevel_any,"
114 + " even it is not compilable at opposite level ["
115 + compLevel + "]");
116 }
118 if (!WHITE_BOX.isMethodCompilable(method, compLevel)) {
119 throw new RuntimeException(method
120 + " must be compilable at level " + compLevel
121 + ", even it is not compilable at opposite level ["
122 + compLevel + "]");
123 }
124 }
126 // clearing after tiered/non-tiered tests
127 // WB.clearMethodState() must reset no-compilable flags
128 WHITE_BOX.clearMethodState(method);
129 if (!WHITE_BOX.isMethodCompilable(method)) {
130 throw new RuntimeException(method
131 + " is not compilable after clearMethodState()");
132 }
134 WHITE_BOX.makeMethodNotCompilable(method);
135 if (WHITE_BOX.isMethodCompilable(method)) {
136 throw new RuntimeException(method + " must be not compilable");
137 }
139 compile();
140 checkNotCompiled();
141 if (WHITE_BOX.isMethodCompilable(method)) {
142 throw new RuntimeException(method + " must be not compilable");
143 }
144 // WB.clearMethodState() must reset no-compilable flags
145 WHITE_BOX.clearMethodState(method);
146 if (!WHITE_BOX.isMethodCompilable(method)) {
147 throw new RuntimeException(method
148 + " is not compilable after clearMethodState()");
149 }
150 compile();
151 checkCompiled();
152 }
154 // separately tests each tier
155 private void testTier(int testedTier) {
156 if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
157 throw new RuntimeException(method
158 + " is not compilable on start");
159 }
160 WHITE_BOX.makeMethodNotCompilable(method, testedTier);
162 // tests for all other tiers
163 for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1;
164 anotherTier < tierLimit; ++anotherTier) {
165 boolean isCompilable = WHITE_BOX.isMethodCompilable(method,
166 anotherTier);
167 if (sameCompile(testedTier, anotherTier)) {
168 if (isCompilable) {
169 throw new RuntimeException(method
170 + " must be not compilable at level " + anotherTier
171 + ", if it is not compilable at " + testedTier);
172 }
173 WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
174 checkNotCompiled();
175 } else {
176 if (!isCompilable) {
177 throw new RuntimeException(method
178 + " must be compilable at level " + anotherTier
179 + ", even if it is not compilable at "
180 + testedTier);
181 }
182 WHITE_BOX.enqueueMethodForCompilation(method, anotherTier);
183 checkCompiled();
184 WHITE_BOX.deoptimizeMethod(method);
185 }
187 if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) {
188 throw new RuntimeException(method
189 + " must be compilable at 'CompLevel::CompLevel_any'"
190 + ", if it is not compilable only at " + testedTier);
191 }
192 }
194 // clear state after test
195 WHITE_BOX.clearMethodState(method);
196 if (!WHITE_BOX.isMethodCompilable(method, testedTier)) {
197 throw new RuntimeException(method
198 + " is not compilable after clearMethodState()");
199 }
200 }
202 private boolean sameCompile(int level1, int level2) {
203 if (level1 == level2) {
204 return true;
205 }
206 if (isC1Compile(level1) && isC1Compile(level2)) {
207 return true;
208 }
209 if (isC2Compile(level1) && isC2Compile(level2)) {
210 return true;
211 }
212 return false;
213 }
214 }