1 /* 2 * Copyright (c) 2018, 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 26 * @bug 8189439 27 * @summary Parameters type profiling is not performed from aarch64 interpreter 28 * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled 29 * @library /test/lib / 30 * @build sun.hotspot.WhiteBox 31 * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission 32 * @run main/othervm -Xbootclasspath/a:. -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseOnStackReplacement 33 * -server -XX:-TieredCompilation -XX:TypeProfileLevel=020 34 * compiler.profiling.TestTypeProfiling 35 * @run main/othervm -Xbootclasspath/a:. -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseOnStackReplacement 36 * -server -XX:-TieredCompilation -XX:TypeProfileLevel=200 37 * compiler.profiling.TestTypeProfiling 38 */ 39 40 package compiler.profiling; 41 42 import jdk.test.lib.Platform; 43 import sun.hotspot.WhiteBox; 44 import compiler.whitebox.CompilerWhiteBoxTest; 45 import java.lang.reflect.Method; 46 47 public class TestTypeProfiling { 48 49 public static int[] mParamTypeCheck(Object in) { 50 try { 51 return (int[]) in; 52 } catch (ClassCastException cce) { 53 return null; 54 } 55 } 56 57 static Object x2(Object src) { 58 return src; 59 } 60 61 public static int[] mRetTypeCheck(Object in) { 62 try { 63 Object out = x2(in); 64 return (int[]) out; 65 } catch (ClassCastException cce) { 66 return null; 67 } 68 } 69 70 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 71 private static final int TIERED_STOP_AT_LEVEL = WHITE_BOX.getIntxVMFlag("TieredStopAtLevel").intValue(); 72 73 static boolean deoptimize(Method method, Object src_obj) throws Exception { 74 for (int i = 0; i < 10; i++) { 75 method.invoke(null, src_obj); 76 if (!WHITE_BOX.isMethodCompiled(method)) { 77 return true; 78 } 79 } 80 return false; 81 } 82 83 static public void main(String[] args) throws Exception { 84 if (!Platform.isServer() || Platform.isEmulatedClient()) { 85 throw new Error("TESTBUG: Not server mode"); 86 } 87 // Only execute if C2 is available 88 if (TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { 89 throw new RuntimeException("please enable C2"); 90 } 91 92 Method method; 93 if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 20) { 94 method = TestTypeProfiling.class.getMethod("mRetTypeCheck", Object.class); 95 } else 96 if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 200) { 97 method = TestTypeProfiling.class.getMethod("mParamTypeCheck", Object.class); 98 } else { 99 throw new RuntimeException("please setup method return/params type profilation: -XX:TypeProfileLevel=020/200"); 100 } 101 102 int[] src = new int[10]; 103 Object src_obj = new Object(); 104 105 // Warm up & make sure we collect type profiling 106 for (int i = 0; i < 20000; i++) { 107 mParamTypeCheck(src); 108 mRetTypeCheck(src); 109 } 110 111 // And make sure the method is compiled by C2 112 WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 113 if (!WHITE_BOX.isMethodCompiled(method)) { 114 throw new RuntimeException(method.getName() + " is not compiled"); 115 } 116 117 // should deoptimize for speculative type check 118 if (!deoptimize(method, src_obj)) { 119 throw new RuntimeException(method.getName() + " is not deoptimized"); 120 } 121 122 // compile again 123 WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 124 if (!WHITE_BOX.isMethodCompiled(method)) { 125 throw new RuntimeException(method.getName() + " is not recompiled"); 126 } 127 128 // should deoptimize for actual type check 129 if (!deoptimize(method, src_obj)) { 130 throw new RuntimeException(method.getName() + " is not deoptimized (should deoptimize for actual type check)"); 131 } 132 133 // compile once again 134 WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 135 if (!WHITE_BOX.isMethodCompiled(method)) { 136 throw new RuntimeException(method.getName() + " is not recompiled"); 137 } 138 139 // this time new parameter type should not force deoptimization 140 if (deoptimize(method, src_obj)) { 141 throw new RuntimeException(method.getName() + " is deoptimized again"); 142 } 143 } 144 }