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 /testlibrary/whitebox 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 DeoptimizeFramesTest true 35 * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions 36 * -XX:+WhiteBoxAPI -Xmixed 37 * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method 38 * -XX:-DeoptimizeRandom DeoptimizeFramesTest false 39 * @summary testing of WB::deoptimizeFrames() 40 */ 41 import java.lang.reflect.Executable; 42 import java.util.concurrent.Callable; 43 44 import sun.hotspot.code.NMethod; 45 import com.oracle.java.testlibrary.Asserts; 46 47 public class DeoptimizeFramesTest extends CompilerWhiteBoxTest { 48 private final boolean makeNotEntrant; 49 50 private DeoptimizeFramesTest(boolean makeNotEntrant) { 51 super(new TestCaseImpl()); 52 // to prevent inlining of #method 53 WHITE_BOX.testSetDontInlineMethod(method, true); 54 this.makeNotEntrant = makeNotEntrant; 55 System.out.printf("DeoptimizeFramesTest(makeNotEntrant = %b)%n", 56 makeNotEntrant); 57 } 58 59 public static void main(String[] args) throws Exception { 60 Asserts.assertEQ(args.length, 1, 61 "[TESTBUG] args should contain 1 element"); 62 new DeoptimizeFramesTest(Boolean.valueOf(args[0])).runTest(); 63 } 64 65 @Override 66 protected void test() throws Exception { 67 compile(); 68 checkCompiled(); 69 WHITE_BOX.deoptimizeFrames(makeNotEntrant); 70 checkCompiled(); 71 NMethod nm = NMethod.get(method, testCase.isOsr()); 72 Thread t = new Thread(() -> {while(true) { WHITE_BOX.deoptimizeFrames(makeNotEntrant); }}); 73 t.setDaemon(true); 74 t.start(); 75 for (int i = 0, result = compile(1); result != 0; result = compile(1), ++i) { 76 if (CompilerWhiteBoxTest.IS_VERBOSE && i % 100 == 0) { 77 System.out.printf("[%d] compiler is %d%n", i, result); 78 printInfo(); 79 } 80 } 81 // invoke one more time to recompile not entrant if any 82 compile(1); 83 84 NMethod nm2 = NMethod.get(method, testCase.isOsr()); 85 if (makeNotEntrant) { 86 if (nm2 != null) { 87 Asserts.assertNE(nm.compile_id, nm2.compile_id, 88 String.format("compilation %d can't be available", nm.compile_id)); 89 } 90 } else { 91 Asserts.assertEQ(nm.compile_id, nm2.compile_id, "should be the same nmethod"); 92 } 93 } 94 95 private static class TestCaseImpl implements TestCase { 96 private static final Executable EXECUTABLE; 97 private static final int RECURSION_DEPTH = 100; 98 static { 99 try { 100 EXECUTABLE = TestCaseImpl.class.getDeclaredMethod("method"); 101 } catch (NoSuchMethodException e) { 102 throw new Error("[TESTBUG] method not found", e); 103 } 104 } 105 106 private volatile int i; 107 108 @Override 109 public String name() { 110 return "recursiveMethod"; 111 } 112 113 @Override 114 public Executable getExecutable() { 115 return EXECUTABLE; 116 } 117 118 @Override 119 public Callable<Integer> getCallable() { 120 return () -> { 121 i = 0; 122 return method(); 123 }; 124 } 125 126 @Override 127 public boolean isOsr() { 128 return false; 129 } 130 131 private int method() { 132 ++i; 133 int compiler = sun.misc.Unsafe.getCompiler(); 134 if (i < RECURSION_DEPTH) { 135 return compiler * method(); 136 } 137 return compiler; 138 } 139 } 140 }