8172733: [JVMCI] add ResolvedJavaMethod.hasNeverInlineDirective
Reviewed-by: kvn
This commit is contained in:
parent
f3fcb0ec76
commit
1cd0ad5c34
@ -100,15 +100,19 @@ final class CompilerToVM {
|
||||
native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method);
|
||||
|
||||
/**
|
||||
* Determines if {@code method} can be inlined. A method may not be inlinable for a number of
|
||||
* reasons such as:
|
||||
* <ul>
|
||||
* <li>a CompileOracle directive may prevent inlining or compilation of methods</li>
|
||||
* <li>the method may have a bytecode breakpoint set</li>
|
||||
* <li>the method may have other bytecode features that require special handling by the VM</li>
|
||||
* </ul>
|
||||
* Determines whether {@code method} is currently compilable by the JVMCI compiler being used by
|
||||
* the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a
|
||||
* breakpoint is currently set in {@code method} or {@code method} contains other bytecode
|
||||
* features that require special handling by the VM.
|
||||
*/
|
||||
native boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method);
|
||||
native boolean isCompilable(HotSpotResolvedJavaMethodImpl method);
|
||||
|
||||
/**
|
||||
* Determines if {@code method} is targeted by a VM directive (e.g.,
|
||||
* {@code -XX:CompileCommand=dontinline,<pattern>}) or annotation (e.g.,
|
||||
* {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
|
||||
*/
|
||||
native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method);
|
||||
|
||||
/**
|
||||
* Determines if {@code method} should be inlined at any cost. This could be because:
|
||||
|
@ -49,13 +49,6 @@ public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod {
|
||||
*/
|
||||
boolean isForceInline();
|
||||
|
||||
/**
|
||||
* Returns true if this method has a {@code DontInline} annotation.
|
||||
*
|
||||
* @return true if DontInline annotation present, false otherwise
|
||||
*/
|
||||
boolean isDontInline();
|
||||
|
||||
/**
|
||||
* Returns true if this method has a {@code ReservedStackAccess} annotation.
|
||||
*
|
||||
|
@ -298,15 +298,6 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
||||
return (getFlags() & config().methodFlagsForceInline) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this method has a {@code DontInline} annotation.
|
||||
*
|
||||
* @return true if DontInline annotation present, false otherwise
|
||||
*/
|
||||
public boolean isDontInline() {
|
||||
return (getFlags() & config().methodFlagsDontInline) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this method has a {@code ReservedStackAccess} annotation.
|
||||
*
|
||||
@ -582,10 +573,15 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
||||
|
||||
@Override
|
||||
public boolean canBeInlined() {
|
||||
if (isDontInline()) {
|
||||
if (hasNeverInlineDirective()) {
|
||||
return false;
|
||||
}
|
||||
return compilerToVM().canInlineMethod(this);
|
||||
return compilerToVM().isCompilable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNeverInlineDirective() {
|
||||
return compilerToVM().hasNeverInlineDirective(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -346,6 +346,13 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersP
|
||||
*/
|
||||
boolean canBeInlined();
|
||||
|
||||
/**
|
||||
* Determines if this method is targeted by a VM directive (e.g.,
|
||||
* {@code -XX:CompileCommand=dontinline,<pattern>}) or VM recognized annotation (e.g.,
|
||||
* {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
|
||||
*/
|
||||
boolean hasNeverInlineDirective();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the inlining of this method should be forced.
|
||||
*/
|
||||
|
@ -591,12 +591,16 @@ C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, job
|
||||
return method->is_ignored_by_security_stack_walk();
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
|
||||
C2V_VMENTRY(jboolean, isCompilable,(JNIEnv *, jobject, jobject jvmci_method))
|
||||
methodHandle method = CompilerToVM::asMethod(jvmci_method);
|
||||
// In hosted mode ignore the not_compilable flags since they are never set by
|
||||
// Ignore the not_compilable flags in hosted mode since they are never set by
|
||||
// the JVMCI compiler.
|
||||
bool is_compilable = UseJVMCICompiler ? !method->is_not_compilable(CompLevel_full_optimization) : true;
|
||||
return is_compilable && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
|
||||
return UseJVMCICompiler || !method->is_not_compilable(CompLevel_full_optimization);
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY(jboolean, hasNeverInlineDirective,(JNIEnv *, jobject, jobject jvmci_method))
|
||||
methodHandle method = CompilerToVM::asMethod(jvmci_method);
|
||||
return CompilerOracle::should_not_inline(method) || method->dont_inline();
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
|
||||
@ -1591,7 +1595,8 @@ JNINativeMethod CompilerToVM::methods[] = {
|
||||
{CC "getStackTraceElement", CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)},
|
||||
{CC "methodIsIgnoredBySecurityStackWalk", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)},
|
||||
{CC "doNotInlineOrCompile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(doNotInlineOrCompile)},
|
||||
{CC "canInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(canInlineMethod)},
|
||||
{CC "isCompilable", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(isCompilable)},
|
||||
{CC "hasNeverInlineDirective", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(hasNeverInlineDirective)},
|
||||
{CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)},
|
||||
{CC "lookupType", CC "(" STRING CLASS "Z)" HS_RESOLVED_KLASS, FN_PTR(lookupType)},
|
||||
{CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupNameInPool)},
|
||||
|
@ -48,8 +48,12 @@ public class CompilerToVMHelper {
|
||||
return CTVM.getExceptionTableStart((HotSpotResolvedJavaMethodImpl)method);
|
||||
}
|
||||
|
||||
public static boolean canInlineMethod(HotSpotResolvedJavaMethod method) {
|
||||
return CTVM.canInlineMethod((HotSpotResolvedJavaMethodImpl)method);
|
||||
public static boolean isCompilable(HotSpotResolvedJavaMethod method) {
|
||||
return CTVM.isCompilable((HotSpotResolvedJavaMethodImpl)method);
|
||||
}
|
||||
|
||||
public static boolean hasNeverInlineDirective(HotSpotResolvedJavaMethod method) {
|
||||
return CTVM.hasNeverInlineDirective((HotSpotResolvedJavaMethodImpl)method);
|
||||
}
|
||||
|
||||
public static boolean shouldInlineMethod(HotSpotResolvedJavaMethod method) {
|
||||
|
@ -67,13 +67,13 @@ public class DoNotInlineOrCompileTest {
|
||||
private static void runSanityTest(Executable aMethod) {
|
||||
HotSpotResolvedJavaMethod method = CTVMUtilities
|
||||
.getResolvedMethod(aMethod);
|
||||
boolean canInline = CompilerToVMHelper.canInlineMethod(method);
|
||||
Asserts.assertTrue(canInline, "Unexpected initial " +
|
||||
"value of property 'can inline'");
|
||||
boolean hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
|
||||
Asserts.assertFalse(hasNeverInlineDirective, "Unexpected initial " +
|
||||
"value of property 'hasNeverInlineDirective'");
|
||||
CompilerToVMHelper.doNotInlineOrCompile(method);
|
||||
canInline = CompilerToVMHelper.canInlineMethod(method);
|
||||
Asserts.assertFalse(canInline, aMethod
|
||||
+ " : can be inlined even after doNotInlineOrCompile'");
|
||||
hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
|
||||
Asserts.assertTrue(hasNeverInlineDirective, aMethod
|
||||
+ " : hasNeverInlineDirective is false even after doNotInlineOrCompile'");
|
||||
}
|
||||
|
||||
private static List<Executable> createTestCases() {
|
||||
|
@ -39,7 +39,7 @@
|
||||
* @run main/othervm -Xbootclasspath/a:.
|
||||
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
|
||||
* compiler.jvmci.compilerToVM.CanInlineMethodTest
|
||||
* compiler.jvmci.compilerToVM.HasNeverInlineDirectiveTest
|
||||
*/
|
||||
|
||||
package compiler.jvmci.compilerToVM;
|
||||
@ -55,31 +55,30 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class CanInlineMethodTest {
|
||||
public class HasNeverInlineDirectiveTest {
|
||||
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Executable> testCases = createTestCases();
|
||||
testCases.forEach(CanInlineMethodTest::runSanityTest);
|
||||
testCases.forEach(HasNeverInlineDirectiveTest::runSanityTest);
|
||||
}
|
||||
|
||||
private static void runSanityTest(Executable aMethod) {
|
||||
HotSpotResolvedJavaMethod method = CTVMUtilities
|
||||
.getResolvedMethod(aMethod);
|
||||
boolean canInline = CompilerToVMHelper.canInlineMethod(method);
|
||||
boolean expectedCanInline = !WB.testSetDontInlineMethod(aMethod,
|
||||
true);
|
||||
Asserts.assertEQ(canInline, expectedCanInline, "Unexpected initial " +
|
||||
"value of property 'can inline'");
|
||||
boolean hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
|
||||
boolean expected = WB.testSetDontInlineMethod(aMethod, true);
|
||||
Asserts.assertEQ(hasNeverInlineDirective, expected, "Unexpected initial " +
|
||||
"value of property 'hasNeverInlineDirective'");
|
||||
|
||||
canInline = CompilerToVMHelper.canInlineMethod(method);
|
||||
Asserts.assertFalse(canInline, aMethod + "Unexpected value of " +
|
||||
"property 'can inline' after setting 'do not inline' to true");
|
||||
hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
|
||||
Asserts.assertTrue(hasNeverInlineDirective, aMethod + "Unexpected value of " +
|
||||
"property 'hasNeverInlineDirective' after setting 'do not inline' to true");
|
||||
WB.testSetDontInlineMethod(aMethod, false);
|
||||
canInline = CompilerToVMHelper.canInlineMethod(method);
|
||||
Asserts.assertTrue(canInline, "Unexpected value of " +
|
||||
"property 'can inline' after setting 'do not inline' to false");
|
||||
hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
|
||||
Asserts.assertFalse(hasNeverInlineDirective, "Unexpected value of " +
|
||||
"property 'hasNeverInlineDirective' after setting 'do not inline' to false");
|
||||
}
|
||||
|
||||
private static List<Executable> createTestCases() {
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 8136421
|
||||
* @requires vm.jvmci
|
||||
* @library /test/lib /
|
||||
* @library ../common/patches
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
* java.base/jdk.internal.org.objectweb.asm.tree
|
||||
* jdk.vm.ci/jdk.vm.ci.hotspot
|
||||
* jdk.vm.ci/jdk.vm.ci.code
|
||||
*
|
||||
* @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
|
||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm -Xbootclasspath/a:.
|
||||
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler
|
||||
* compiler.jvmci.compilerToVM.IsCompilableTest
|
||||
* @run main/othervm -Xbootclasspath/a:.
|
||||
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
|
||||
* compiler.jvmci.compilerToVM.IsCompilableTest
|
||||
*/
|
||||
|
||||
package compiler.jvmci.compilerToVM;
|
||||
|
||||
import compiler.jvmci.common.CTVMUtilities;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.vm.ci.hotspot.CompilerToVMHelper;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
import java.lang.reflect.Executable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class IsCompilableTest {
|
||||
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Executable> testCases = createTestCases();
|
||||
testCases.forEach(IsCompilableTest::runSanityTest);
|
||||
}
|
||||
|
||||
private static void runSanityTest(Executable aMethod) {
|
||||
boolean UseJVMCICompiler = (Boolean) WB.getVMFlag("UseJVMCICompiler");
|
||||
HotSpotResolvedJavaMethod method = CTVMUtilities
|
||||
.getResolvedMethod(aMethod);
|
||||
boolean isCompilable = CompilerToVMHelper.isCompilable(method);
|
||||
boolean expected = UseJVMCICompiler || WB.isMethodCompilable(aMethod);
|
||||
Asserts.assertEQ(isCompilable, expected, "Unexpected initial " +
|
||||
"value of property 'compilable'");
|
||||
|
||||
if (!UseJVMCICompiler) {
|
||||
WB.makeMethodNotCompilable(aMethod);
|
||||
isCompilable = CompilerToVMHelper.isCompilable(method);
|
||||
Asserts.assertFalse(isCompilable, aMethod + "Unexpected value of " +
|
||||
"property 'isCompilable' after setting 'compilable' to false");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Executable> createTestCases() {
|
||||
List<Executable> testCases = new ArrayList<>();
|
||||
|
||||
Class<?> aClass = DummyClass.class;
|
||||
testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
|
||||
testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
|
||||
return testCases;
|
||||
}
|
||||
}
|
@ -466,6 +466,7 @@ public class TestResolvedJavaMethod extends MethodUniverse {
|
||||
"getProfilingInfo",
|
||||
"reprofile",
|
||||
"getCompilerStorage",
|
||||
"hasNeverInlineDirective",
|
||||
"canBeInlined",
|
||||
"shouldBeInlined",
|
||||
"getLineNumberTable",
|
||||
|
Loading…
x
Reference in New Issue
Block a user