1 /* 2 * Copyright (c) 2014, 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 24 import compiler.whitebox.CompilerWhiteBoxTest; 25 26 /* 27 * @test DeoptimizeFramesTest 28 * @bug 8028595 29 * @library /testlibrary /test/lib / 30 * @modules java.base/jdk.internal.misc 31 * @modules java.management 32 * @build DeoptimizeFramesTest 33 * @run driver ClassFileInstaller sun.hotspot.WhiteBox 34 * sun.hotspot.WhiteBox$WhiteBoxPermission 35 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions 36 * -XX:+WhiteBoxAPI -Xmixed -XX:-UseCounterDecay 37 * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method 38 * -XX:+IgnoreUnrecognizedVMOptions -XX:-DeoptimizeRandom -XX:-DeoptimizeALot 39 * DeoptimizeFramesTest true 40 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions 41 * -XX:+WhiteBoxAPI -Xmixed -XX:-UseCounterDecay 42 * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method 43 * -XX:+IgnoreUnrecognizedVMOptions -XX:-DeoptimizeRandom -XX:-DeoptimizeALot 44 * DeoptimizeFramesTest false 45 * @summary testing of WB::deoptimizeFrames() 46 */ 47 import java.lang.reflect.Executable; 48 import java.util.concurrent.Callable; 49 import java.util.concurrent.Phaser; 50 51 import sun.hotspot.code.NMethod; 52 import jdk.test.lib.Asserts; 53 import jdk.test.lib.InfiniteLoop; 54 55 public class DeoptimizeFramesTest extends CompilerWhiteBoxTest { 56 private final boolean makeNotEntrant; 57 private final Phaser phaser; 58 59 private DeoptimizeFramesTest(boolean makeNotEntrant, Phaser phaser) { 60 super(new TestCaseImpl(phaser)); 61 // to prevent inlining of #method 62 WHITE_BOX.testSetDontInlineMethod(method, true); 63 this.makeNotEntrant = makeNotEntrant; 64 this.phaser = phaser; 65 System.out.printf("DeoptimizeFramesTest(makeNotEntrant = %b)%n", 66 makeNotEntrant); 67 } 68 69 public static void main(String[] args) throws Exception { 70 Asserts.assertEQ(args.length, 1, 71 "[TESTBUG] args should contain 1 element"); 72 new DeoptimizeFramesTest(Boolean.valueOf(args[0]), new Phaser()).runTest(); 73 } 74 75 @Override 76 protected void test() throws Exception { 77 compile(); 78 checkCompiled(); 79 NMethod nm = NMethod.get(method, testCase.isOsr()); 80 81 WHITE_BOX.deoptimizeFrames(makeNotEntrant); 82 // #method should still be compiled, since it didn't have frames on stack 83 checkCompiled(); 84 NMethod nm2 = NMethod.get(method, testCase.isOsr()); 85 Asserts.assertEQ(nm.compile_id, nm2.compile_id, 86 "should be the same nmethod"); 87 88 phaser.register(); 89 Thread t = new Thread(() -> compile(1)); 90 t.start(); 91 // pass 1st phase, #method is on stack 92 int p = phaser.arriveAndAwaitAdvance(); 93 WHITE_BOX.deoptimizeFrames(makeNotEntrant); 94 // pass 2nd phase, #method can exit 95 phaser.awaitAdvance(phaser.arriveAndDeregister()); 96 97 try { 98 t.join(); 99 } catch (InterruptedException e) { 100 throw new Error("method '" + method + "' is still executing", e); 101 } 102 103 // invoke one more time to recompile not entrant if any 104 compile(1); 105 106 nm2 = NMethod.get(method, testCase.isOsr()); 107 if (makeNotEntrant) { 108 if (nm2 != null) { 109 Asserts.assertNE(nm.compile_id, nm2.compile_id, 110 String.format("compilation %d can't be available", nm.compile_id)); 111 } 112 } else { 113 Asserts.assertEQ(nm.compile_id, nm2.compile_id, "should be the same nmethod"); 114 } 115 } 116 117 118 private static class TestCaseImpl implements TestCase { 119 private static final Executable EXECUTABLE; 120 static { 121 try { 122 EXECUTABLE = TestCaseImpl.class.getDeclaredMethod("method"); 123 } catch (NoSuchMethodException e) { 124 throw new Error("[TESTBUG] method not found", e); 125 } 126 } 127 128 private final Phaser phaser; 129 130 public TestCaseImpl(Phaser phaser) { 131 this.phaser = phaser; 132 phaser.register(); 133 } 134 135 @Override 136 public String name() { 137 return "2phases"; 138 } 139 140 @Override 141 public Executable getExecutable() { 142 return EXECUTABLE; 143 } 144 145 @Override 146 public Callable<Integer> getCallable() { 147 return () -> { 148 return method(); 149 }; 150 } 151 152 @Override 153 public boolean isOsr() { 154 return false; 155 } 156 157 private int method() { 158 phaser.arriveAndAwaitAdvance(); 159 phaser.arriveAndAwaitAdvance(); 160 return 0; 161 } 162 } 163 }