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