MakeMethodNotCompilableTest.java revision 10473:ca0cd486254f
1/*
2 * Copyright (c) 2013, 2015, 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
24import compiler.whitebox.CompilerWhiteBoxTest;
25
26/*
27 * @test MakeMethodNotCompilableTest
28 * @bug 8012322 8006683 8007288 8022832
29 * @library /testlibrary /test/lib /
30 * @modules java.management
31 * @build MakeMethodNotCompilableTest
32 * @run main ClassFileInstaller sun.hotspot.WhiteBox
33 *                              sun.hotspot.WhiteBox$WhiteBoxPermission
34 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI  -Xmixed MakeMethodNotCompilableTest
35 * @summary testing of WB::makeMethodNotCompilable()
36 * @author igor.ignatyev@oracle.com
37 */
38public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
39    private int bci;
40    public static void main(String[] args) throws Exception {
41        String directive =
42                "[{ match:\"*SimpleTestCase$Helper.*\", BackgroundCompilation: false }, " +
43                " { match:\"*.*\", inline:\"-*SimpleTestCase$Helper.*\"}]";
44        if (WHITE_BOX.addCompilerDirective(directive) != 2) {
45            throw new RuntimeException("Could not add directive");
46        }
47        try {
48            CompilerWhiteBoxTest.main(MakeMethodNotCompilableTest::new, args);
49        } finally {
50            WHITE_BOX.removeCompilerDirective(2);
51        }
52    }
53
54    private MakeMethodNotCompilableTest(TestCase testCase) {
55        super(testCase);
56        // to prevent inlining of #method
57        WHITE_BOX.testSetDontInlineMethod(method, true);
58    }
59
60    /**
61     * Tests {@code WB::makeMethodNotCompilable()} by calling it before
62     * compilation and checking that method isn't compiled. Also
63     * checks that WB::clearMethodState() clears no-compilable flags. For
64     * tiered, additional checks for all available levels are conducted.
65     *
66     * @throws Exception if one of the checks fails.
67     */
68    @Override
69    protected void test() throws Exception {
70        if (skipXcompOSR()) {
71            return;
72        }
73        checkNotCompiled();
74        if (!isCompilable()) {
75            throw new RuntimeException(method + " must be compilable");
76        }
77
78        bci = getBci();
79
80        if (TIERED_COMPILATION) {
81            final int tierLimit = TIERED_STOP_AT_LEVEL + 1;
82            for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
83                testTier(testedTier);
84            }
85            for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
86                makeNotCompilable(testedTier);
87                if (isCompilable(testedTier)) {
88                    throw new RuntimeException(method
89                            + " must be not compilable at level" + testedTier);
90                }
91                WHITE_BOX.enqueueMethodForCompilation(method, testedTier, bci);
92                checkNotCompiled();
93
94                if (!isCompilable()) {
95                    System.out.println(method
96                            + " is not compilable after level " + testedTier);
97                }
98            }
99        } else {
100            compile();
101            checkCompiled();
102            int compLevel = getCompLevel();
103            deoptimize();
104            makeNotCompilable(compLevel);
105            if (isCompilable(COMP_LEVEL_ANY)) {
106                throw new RuntimeException(method
107                        + " must be not compilable at CompLevel::CompLevel_any,"
108                        + " after it is not compilable at " + compLevel);
109            }
110
111            WHITE_BOX.clearMethodState(method);
112            if (!isCompilable()) {
113                throw new RuntimeException(method
114                        + " is not compilable after clearMethodState()");
115            }
116
117            // nocompilable at opposite level must make no sense
118            int oppositeLevel;
119            if (isC1Compile(compLevel)) {
120              oppositeLevel = COMP_LEVEL_FULL_OPTIMIZATION;
121            } else {
122              oppositeLevel = COMP_LEVEL_SIMPLE;
123            }
124            makeNotCompilable(oppositeLevel);
125
126            if (!isCompilable(COMP_LEVEL_ANY)) {
127                  throw new RuntimeException(method
128                        + " must be compilable at CompLevel::CompLevel_any,"
129                        + " even it is not compilable at opposite level ["
130                        + compLevel + "]");
131            }
132
133            if (!isCompilable(compLevel)) {
134                  throw new RuntimeException(method
135                        + " must be compilable at level " + compLevel
136                        + ", even it is not compilable at opposite level ["
137                        + compLevel + "]");
138            }
139        }
140
141        // clearing after tiered/non-tiered tests
142        // WB.clearMethodState() must reset no-compilable flags
143        WHITE_BOX.clearMethodState(method);
144        if (!isCompilable()) {
145            throw new RuntimeException(method
146                    + " is not compilable after clearMethodState()");
147        }
148        // Make method not (OSR-)compilable (depending on testCase.isOsr())
149        makeNotCompilable();
150        if (isCompilable()) {
151            throw new RuntimeException(method + " must be not compilable");
152        }
153        // Try to (OSR-)compile method
154        compile();
155        // Method should not be (OSR-)compiled
156        checkNotCompiled(testCase.isOsr());
157        if (isCompilable()) {
158            throw new RuntimeException(method + " must be not compilable");
159        }
160        // WB.clearMethodState() must reset no-compilable flags
161        WHITE_BOX.clearMethodState(method);
162        if (!isCompilable()) {
163            throw new RuntimeException(method
164                    + " is not compilable after clearMethodState()");
165        }
166        compile();
167        checkCompiled();
168    }
169
170    // separately tests each tier
171    private void testTier(int testedTier) {
172        if (!isCompilable(testedTier)) {
173            throw new RuntimeException(method
174                    + " is not compilable on start");
175        }
176        makeNotCompilable(testedTier);
177
178        // tests for all other tiers
179        for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1;
180                    anotherTier < tierLimit; ++anotherTier) {
181            boolean isCompilable = isCompilable(anotherTier);
182            if (sameCompile(testedTier, anotherTier)) {
183                if (isCompilable) {
184                    throw new RuntimeException(method
185                            + " must be not compilable at level " + anotherTier
186                            + ", if it is not compilable at " + testedTier);
187                }
188                WHITE_BOX.enqueueMethodForCompilation(method, anotherTier, bci);
189                checkNotCompiled();
190            } else {
191                if (!isCompilable) {
192                    throw new RuntimeException(method
193                            + " must be compilable at level " + anotherTier
194                            + ", even if it is not compilable at "
195                            + testedTier);
196                }
197                WHITE_BOX.enqueueMethodForCompilation(method, anotherTier, bci);
198                checkCompiled();
199                deoptimize();
200            }
201
202            if (!isCompilable(COMP_LEVEL_ANY)) {
203                throw new RuntimeException(method
204                        + " must be compilable at 'CompLevel::CompLevel_any'"
205                        + ", if it is not compilable only at " + testedTier);
206            }
207        }
208
209        // clear state after test
210        WHITE_BOX.clearMethodState(method);
211        if (!isCompilable(testedTier)) {
212            throw new RuntimeException(method
213                    + " is not compilable after clearMethodState()");
214        }
215    }
216
217    private boolean sameCompile(int level1, int level2) {
218        if (level1 == level2) {
219            return true;
220        }
221        if (isC1Compile(level1) && isC1Compile(level2)) {
222            return true;
223        }
224        if (isC2Compile(level1) && isC2Compile(level2)) {
225            return true;
226        }
227        return false;
228    }
229
230    private int getBci() {
231        compile();
232        checkCompiled();
233        int result = WHITE_BOX.getMethodEntryBci(method);
234        deoptimize();
235        WHITE_BOX.clearMethodState(method);
236        return result;
237    }
238}
239