/* * Copyright (c) 2021, 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 8275868 * @library / /test/lib * @summary Testing that ciReplay inlining does not fail with unresolved signature classes. * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.compMode != "Xcomp" & vm.debug == true & vm.compiler2.enabled * @modules java.base/jdk.internal.misc * @run driver compiler.ciReplay.TestInliningProtectionDomain */ package compiler.ciReplay; import jdk.test.lib.Asserts; import java.util.List; public class TestInliningProtectionDomain extends InliningBase { public static void main(String[] args) { new TestInliningProtectionDomain(ProtectionDomainTestCompiledBefore.class, true); new TestInliningProtectionDomain(ProtectionDomainTestNoOtherCompilationPublic.class, false); new TestInliningProtectionDomain(ProtectionDomainTestNoOtherCompilationPrivate.class, false); new TestInliningProtectionDomain(ProtectionDomainTestNoOtherCompilationPrivateString.class, false); } public TestInliningProtectionDomain(Class testClass, boolean compileBar) { super(testClass); if (compileBar) { commandLineNormal.add("-XX:CompileCommand=compileonly," + testClass.getName() + "::bar"); } runTest(); } @Override public void testAction() { positiveTest(commandLineReplay); String entryString = getTestClass() + " " + "test"; boolean inlineFails = testClass == ProtectionDomainTestNoOtherCompilationPrivate.class; int inlineeCount = inlineFails ? 1 : 5; List inlineesNormal = parseLogFile(LOG_FILE_NORMAL, entryString, "compile_id='" + getCompileIdFromFile(getReplayFileName()), inlineeCount); List inlineesReplay = parseLogFile(LOG_FILE_REPLAY, entryString, "test ()V", inlineeCount); verifyLists(inlineesNormal, inlineesReplay, inlineeCount); if (inlineFails) { Asserts.assertTrue(inlineesNormal.get(0).compare("compiler.ciReplay.ProtectionDomainTestNoOtherCompilationPrivate", "bar", inlineesNormal.get(0).isUnloadedSignatureClasses())); Asserts.assertTrue(inlineesReplay.get(0).compare("compiler.ciReplay.ProtectionDomainTestNoOtherCompilationPrivate", "bar", inlineesReplay.get(0).isDisallowedByReplay())); } else { Asserts.assertTrue(inlineesNormal.get(4).compare("compiler.ciReplay.InliningBar", "bar2", inlineesNormal.get(4).isNormalInline())); Asserts.assertTrue(inlineesReplay.get(4).compare("compiler.ciReplay.InliningBar", "bar2", inlineesReplay.get(4).isForcedByReplay() || inlineesReplay.get(4).isForcedIncrementalInlineByReplay())); } } } class ProtectionDomainTestCompiledBefore { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { bar(); // Ensure that bar() was compiled } for (int i = 0; i < 10000; i++) { test(); } } public static void test() { bar(); } // Integer should be resolved for the protection domain of this class because the separate compilation of bar() in // the normal run will resolve all classes in the signature. Inlining succeeds. private static Integer bar() { InliningFoo.foo(); return null; } } class ProtectionDomainTestNoOtherCompilationPublic { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { test(); } } public static void test() { bar(); // Not compiled before separately } // Integer should be resolved for the protection domain of this class because getDeclaredMethods is called in normal run // when validating main() method. In this process, all public methods of this class are visited and its signature classes // are resolved. Inlining of bar() succeeds. public static Integer bar() { InliningFoo.foo(); return null; } } class ProtectionDomainTestNoOtherCompilationPrivate { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { test(); } } public static void test() { bar(); // Not compiled before separately } // Integer should be unresolved for the protection domain of this class even though getDeclaredMethods is called in normal // run when validating main() method. In this process, only public methods of this class are visited and its signature // classes are resolved. Since this method is private, the signature classes are not resolved for this protection domain. // Inlining of bar() should fail in normal run with "unresolved signature classes". Therefore, replay compilation should // also not inline bar(). private static Integer bar() { InliningFoo.foo(); return null; } } class ProtectionDomainTestNoOtherCompilationPrivateString { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { test(); } } public static void test() { bar(); // Not compiled before separately } // Integer should be resovled for the protection domain of this class because getDeclaredMethods is called in normal run // when validating main() method. In this process, public methods of this class are visited and its signature classes // are resolved. bar() is private and not visited in this process (i.e. no resolution of String). But since main() // has String[] as parameter, the String class will be resolved for this protection domain. Inlining of bar() succeeds. private static String bar() { InliningFoo.foo(); return null; } } class InliningFoo { public static void foo() { foo2(); } private static void foo2() { InliningBar.bar(); } } class InliningBar { public static void bar() { bar2(); } private static void bar2() {} }