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