/* * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 8189439 * @summary Parameters type profiling is not performed from aarch64 interpreter * @requires vm.flavor == "server" & vm.compMode == "Xmixed" & !vm.emulatedClient & !vm.graal.enabled * @library /test/lib / * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement * -XX:CompileThreshold=10000 * -server -XX:-TieredCompilation -XX:TypeProfileLevel=020 * compiler.profiling.TestTypeProfiling * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement * -XX:CompileThreshold=10000 * -server -XX:-TieredCompilation -XX:TypeProfileLevel=200 * compiler.profiling.TestTypeProfiling */ package compiler.profiling; import jdk.test.lib.Platform; import sun.hotspot.WhiteBox; import compiler.whitebox.CompilerWhiteBoxTest; import java.lang.reflect.Method; public class TestTypeProfiling { public static int[] mParamTypeCheck(Object in) { try { return (int[]) in; } catch (ClassCastException cce) { return null; } } static Object x2(Object src) { return src; } public static int[] mRetTypeCheck(Object in) { try { Object out = x2(in); return (int[]) out; } catch (ClassCastException cce) { return null; } } private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int TIERED_STOP_AT_LEVEL = WHITE_BOX.getIntxVMFlag("TieredStopAtLevel").intValue(); static boolean deoptimize(Method method, Object src_obj) throws Exception { for (int i = 0; i < 10; i++) { method.invoke(null, src_obj); if (!WHITE_BOX.isMethodCompiled(method)) { return true; } } return false; } static public void main(String[] args) throws Exception { if (!Platform.isServer() || Platform.isEmulatedClient()) { throw new Error("TESTBUG: Not server mode"); } // Only execute if C2 is available if (TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { throw new RuntimeException("please enable C2"); } Method method; if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 20) { method = TestTypeProfiling.class.getMethod("mRetTypeCheck", Object.class); } else if (WHITE_BOX.getUintxVMFlag("TypeProfileLevel") == 200) { method = TestTypeProfiling.class.getMethod("mParamTypeCheck", Object.class); } else { throw new RuntimeException("please setup method return/params type profilation: -XX:TypeProfileLevel=020/200"); } int[] src = new int[10]; Object src_obj = new Object(); // Warm up & make sure we collect type profiling for (int i = 0; i < 20000; i++) { mParamTypeCheck(src); mRetTypeCheck(src); } // And make sure the method is compiled by C2 WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); if (!WHITE_BOX.isMethodCompiled(method)) { throw new RuntimeException(method.getName() + " is not compiled"); } // should deoptimize for speculative type check // Intepreter will also add actual type check trap information into MDO // when it throw ClassCastException if (!deoptimize(method, src_obj)) { throw new RuntimeException(method.getName() + " is not deoptimized"); } // compile again // c2 will generate throw instead of uncommon trap because // actual type check trap information is present in MDO WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); if (!WHITE_BOX.isMethodCompiled(method)) { throw new RuntimeException(method.getName() + " is not recompiled"); } // this time new parameter type should not force deoptimization if (deoptimize(method, src_obj)) { throw new RuntimeException(method.getName() + " is deoptimized again"); } } }