1 /*
2 * Copyright Amazon.com Inc. 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 /*
26 * @test id=C1
27 * @bug 8316694
28 * @requires vm.debug == true
29 * @summary test that relocated nmethod is correctly deoptimized
30 * @library /test/lib /
31 * @modules java.base/jdk.internal.misc java.management
32 *
33 * @build jdk.test.whitebox.WhiteBox
34 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
35 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=1
36 * -XX:+SegmentedCodeCache -XX:-DeoptimizeRandom -XX:+DeoptimizeALot -XX:+UnlockExperimentalVMOptions -XX:+NMethodRelocation
37 * compiler.whitebox.RelocateNMethodMultiplePaths
38 */
39
40 /*
41 * @test id=C2
42 * @bug 8316694
43 * @requires vm.debug == true
44 * @summary test that relocated nmethod is correctly deoptimized
45 * @library /test/lib /
46 * @modules java.base/jdk.internal.misc java.management
47 *
48 * @build jdk.test.whitebox.WhiteBox
49 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
50 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch -XX:+TieredCompilation
51 * -XX:+SegmentedCodeCache -XX:-DeoptimizeRandom -XX:+DeoptimizeALot -XX:+UnlockExperimentalVMOptions -XX:+NMethodRelocation
52 * compiler.whitebox.RelocateNMethodMultiplePaths
53 */
54
55 package compiler.whitebox;
56
57 import compiler.whitebox.CompilerWhiteBoxTest;
58 import java.lang.reflect.Method;
59 import jdk.test.whitebox.WhiteBox;
60 import jdk.test.whitebox.code.BlobType;
61 import jdk.test.whitebox.code.NMethod;
62
63 public class RelocateNMethodMultiplePaths {
64
65 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
66
67 private static final int PATH_ONE_RESULT = 1;
68 private static final int PATH_TWO_RESULT = 2;
69
70 public static void main(String [] args) throws Exception {
71 // Get method that will be relocated
72 Method method = RelocateNMethodMultiplePaths.class.getMethod("function", boolean.class);
73 WHITE_BOX.testSetDontInlineMethod(method, true);
74
75 // Verify not initially compiled
76 CompilerWhiteBoxTest.checkNotCompiled(method, false);
77
78 // Call function enough to compile
79 callFunction(true);
80
81 // Verify now compiled
82 CompilerWhiteBoxTest.checkCompiled(method, false);
83
84 // Get newly created nmethod
85 NMethod origNmethod = NMethod.get(method, false);
86
87 // Relocate nmethod and mark old for cleanup
88 WHITE_BOX.relocateNMethodFromMethod(method, BlobType.MethodNonProfiled.id);
89
90 // Trigger GC to clean up old nmethod
91 WHITE_BOX.fullGC();
92
93 // Verify function still compiled after old was cleaned up
94 CompilerWhiteBoxTest.checkCompiled(method, false);
95
96 // Get new nmethod and verify it's actually new
97 NMethod newNmethod = NMethod.get(method, false);
98 if (origNmethod.entry_point == newNmethod.entry_point) {
99 throw new RuntimeException("Did not create new nmethod");
100 }
101
102 // Verify function still produces correct result
103 if (function(true) != PATH_ONE_RESULT) {
104 throw new RuntimeException("Relocated function produced incorrect result in path one");
105 }
106
107 // Call function again with different path and verify result
108 if (function(false) != PATH_TWO_RESULT) {
109 throw new RuntimeException("Relocated function produced incorrect result in path two");
110 }
111
112 // Verify function can be correctly deoptimized
113 WHITE_BOX.deoptimizeMethod(method);
114 CompilerWhiteBoxTest.checkNotCompiled(method, false);
115 }
116
117 // Call function multiple times to trigger compilation
118 private static void callFunction(boolean pathOne) {
119 for (int i = 0; i < CompilerWhiteBoxTest.THRESHOLD; i++) {
120 function(pathOne);
121 }
122 }
123
124 public static int function(boolean pathOne) {
125 if (pathOne) {
126 return PATH_ONE_RESULT;
127 } else {
128 return PATH_TWO_RESULT;
129 }
130 }
131 }