8257020: [JVMCI] enable a JVMCICompiler to specify which GCs it supports

Reviewed-by: stefank, kvn
This commit is contained in:
Doug Simon 2020-12-03 13:42:50 +00:00
parent 129c37700f
commit fa58671f9f
21 changed files with 197 additions and 41 deletions

View File

@ -457,7 +457,7 @@ void CompilerConfig::ergo_initialize() {
#endif #endif
#if INCLUDE_JVMCI #if INCLUDE_JVMCI
// Check that JVMCI compiler supports selested GC. // Check that JVMCI supports selected GC.
// Should be done after GCConfig::initialize() was called. // Should be done after GCConfig::initialize() was called.
JVMCIGlobals::check_jvmci_supported_gc(); JVMCIGlobals::check_jvmci_supported_gc();

View File

@ -635,6 +635,31 @@ void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...)
} }
} }
jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) {
JavaThread* THREAD = JavaThread::current();
if (is_hotspot()) {
JavaCallArguments jargs;
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
jargs.push_int(gcIdentifier);
JavaValue result(T_BOOLEAN);
JavaCalls::call_special(&result,
HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
vmSymbols::isGCSupported_name(),
vmSymbols::int_bool_signature(), &jargs, CHECK_0);
return result.get_jboolean();
} else {
JNIAccessMark jni(this, THREAD);
jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(),
JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(),
gcIdentifier);
if (jni()->ExceptionCheck()) {
return false;
}
return result;
}
}
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci, JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
jlong compile_state, int id) { jlong compile_state, int id) {
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());

View File

@ -310,6 +310,8 @@ public:
JVMCIObject call_JavaConstant_forFloat(float value, JVMCI_TRAPS); JVMCIObject call_JavaConstant_forFloat(float value, JVMCI_TRAPS);
JVMCIObject call_JavaConstant_forDouble(double value, JVMCI_TRAPS); JVMCIObject call_JavaConstant_forDouble(double value, JVMCI_TRAPS);
jboolean call_HotSpotJVMCIRuntime_isGCSupported(JVMCIObject runtime, jint gcIdentifier);
BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS); BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS);
#define DO_THROW(name) \ #define DO_THROW(name) \

View File

@ -348,6 +348,7 @@
start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \ start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \
objectarray_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \ objectarray_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, compileMethod, compileMethod_signature, (JVMCIObject runtime, JVMCIObject method, int entry_bci, jlong env, int id)) \ jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, compileMethod, compileMethod_signature, (JVMCIObject runtime, JVMCIObject method, int entry_bci, jlong env, int id)) \
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, isGCSupported, int_bool_signature, (JVMCIObject runtime, int gcIdentifier)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, encodeThrowable, encodeThrowable_signature, (JVMCIObject throwable)) \ jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, encodeThrowable, encodeThrowable_signature, (JVMCIObject throwable)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, decodeThrowable, decodeThrowable_signature, (JVMCIObject encodedThrowable)) \ jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, decodeThrowable, decodeThrowable_signature, (JVMCIObject encodedThrowable)) \
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \ jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \

View File

@ -1516,6 +1516,15 @@ void JVMCIRuntime::compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, c
} }
} }
bool JVMCIRuntime::is_gc_supported(JVMCIEnv* JVMCIENV, CollectedHeap::Name name) {
JVMCI_EXCEPTION_CONTEXT
JVMCIObject receiver = get_HotSpotJVMCIRuntime(JVMCIENV);
if (JVMCIENV->has_pending_exception()) {
fatal_exception(JVMCIENV, "Exception during HotSpotJVMCIRuntime initialization");
}
return JVMCIENV->call_HotSpotJVMCIRuntime_isGCSupported(receiver, (int) name);
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV, JVMCI::CodeInstallResult JVMCIRuntime::register_method(JVMCIEnv* JVMCIENV,

View File

@ -25,6 +25,7 @@
#define SHARE_JVMCI_JVMCIRUNTIME_HPP #define SHARE_JVMCI_JVMCIRUNTIME_HPP
#include "code/nmethod.hpp" #include "code/nmethod.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "jvmci/jvmci.hpp" #include "jvmci/jvmci.hpp"
#include "jvmci/jvmciExceptions.hpp" #include "jvmci/jvmciExceptions.hpp"
#include "jvmci/jvmciObject.hpp" #include "jvmci/jvmciObject.hpp"
@ -279,6 +280,9 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
// Compiles `target` with the JVMCI compiler. // Compiles `target` with the JVMCI compiler.
void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci); void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci);
// Determines if the GC identified by `name` is supported by the JVMCI compiler.
bool is_gc_supported(JVMCIEnv* JVMCIENV, CollectedHeap::Name name);
// Register the result of a compilation. // Register the result of a compilation.
JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV, JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV,
const methodHandle& target, const methodHandle& target,

View File

@ -200,11 +200,15 @@ bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin) {
return true; return true;
} }
bool JVMCIGlobals::gc_supports_jvmci() {
return UseSerialGC || UseParallelGC || UseG1GC;
}
void JVMCIGlobals::check_jvmci_supported_gc() { void JVMCIGlobals::check_jvmci_supported_gc() {
if (EnableJVMCI) { if (EnableJVMCI) {
// Check if selected GC is supported by JVMCI and Java compiler // Check if selected GC is supported by JVMCI and Java compiler
if (!(UseSerialGC || UseParallelGC || UseG1GC)) { if (!gc_supports_jvmci()) {
vm_exit_during_initialization("JVMCI Compiler does not support selected GC", GCConfig::hs_err_name()); log_warning(gc, jvmci)("Setting EnableJVMCI to false as selected GC does not support JVMCI: %s", GCConfig::hs_err_name());
FLAG_SET_DEFAULT(EnableJVMCI, false); FLAG_SET_DEFAULT(EnableJVMCI, false);
FLAG_SET_DEFAULT(UseJVMCICompiler, false); FLAG_SET_DEFAULT(UseJVMCICompiler, false);
} }

View File

@ -155,7 +155,10 @@ class JVMCIGlobals {
// Convert JVMCI experimental flags to product // Convert JVMCI experimental flags to product
static bool enable_jvmci_product_mode(JVMFlagOrigin); static bool enable_jvmci_product_mode(JVMFlagOrigin);
// Check and exit VM with error if selected GC is not supported by JVMCI. // Returns true iff the GC fully supports JVMCI.
static bool gc_supports_jvmci();
// Check and turn off EnableJVMCI if selected GC does not support JVMCI.
static void check_jvmci_supported_gc(); static void check_jvmci_supported_gc();
static fileStream* get_jni_config_file() { return _jni_config_file; } static fileStream* get_jni_config_file() { return _jni_config_file; }

View File

@ -482,6 +482,14 @@
declare_constant(CodeInstaller::VERIFY_OOP_MASK) \ declare_constant(CodeInstaller::VERIFY_OOP_MASK) \
declare_constant(CodeInstaller::INVOKE_INVALID) \ declare_constant(CodeInstaller::INVOKE_INVALID) \
\ \
declare_constant(CollectedHeap::None) \
declare_constant(CollectedHeap::Serial) \
declare_constant(CollectedHeap::Parallel) \
declare_constant(CollectedHeap::G1) \
declare_constant(CollectedHeap::Epsilon) \
declare_constant(CollectedHeap::Z) \
declare_constant(CollectedHeap::Shenandoah) \
\
declare_constant(vmIntrinsics::FIRST_MH_SIG_POLY) \ declare_constant(vmIntrinsics::FIRST_MH_SIG_POLY) \
declare_constant(vmIntrinsics::LAST_MH_SIG_POLY) \ declare_constant(vmIntrinsics::LAST_MH_SIG_POLY) \
declare_constant(vmIntrinsics::_invokeGeneric) \ declare_constant(vmIntrinsics::_invokeGeneric) \

View File

@ -103,6 +103,7 @@
template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \ template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \
template(compileMethod_name, "compileMethod") \ template(compileMethod_name, "compileMethod") \
template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \ template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
template(isGCSupported_name, "isGCSupported") \
template(encodeThrowable_name, "encodeThrowable") \ template(encodeThrowable_name, "encodeThrowable") \
template(encodeThrowable_signature, "(Ljava/lang/Throwable;)Ljava/lang/String;") \ template(encodeThrowable_signature, "(Ljava/lang/Throwable;)Ljava/lang/String;") \
template(decodeThrowable_name, "decodeThrowable") \ template(decodeThrowable_name, "decodeThrowable") \

View File

@ -94,6 +94,7 @@
LOG_TAG(jfr) \ LOG_TAG(jfr) \
LOG_TAG(jit) \ LOG_TAG(jit) \
LOG_TAG(jni) \ LOG_TAG(jni) \
LOG_TAG(jvmci) \
LOG_TAG(jvmti) \ LOG_TAG(jvmti) \
LOG_TAG(lambda) \ LOG_TAG(lambda) \
LOG_TAG(library) \ LOG_TAG(library) \

View File

@ -108,6 +108,10 @@
#include "services/memTracker.hpp" #include "services/memTracker.hpp"
#include "utilities/nativeCallStack.hpp" #include "utilities/nativeCallStack.hpp"
#endif // INCLUDE_NMT #endif // INCLUDE_NMT
#if INCLUDE_JVMCI
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
#endif
#if INCLUDE_AOT #if INCLUDE_AOT
#include "aot/aotLoader.hpp" #include "aot/aotLoader.hpp"
#endif // INCLUDE_AOT #endif // INCLUDE_AOT
@ -354,6 +358,16 @@ WB_ENTRY(jboolean, WB_IsGCSupported(JNIEnv* env, jobject o, jint name))
return GCConfig::is_gc_supported((CollectedHeap::Name)name); return GCConfig::is_gc_supported((CollectedHeap::Name)name);
WB_END WB_END
WB_ENTRY(jboolean, WB_IsGCSupportedByJVMCICompiler(JNIEnv* env, jobject o, jint name))
#if INCLUDE_JVMCI
if (EnableJVMCI) {
JVMCIEnv jvmciEnv(thread, env, __FILE__, __LINE__);
return jvmciEnv.runtime()->is_gc_supported(&jvmciEnv, (CollectedHeap::Name)name);
}
#endif
return false;
WB_END
WB_ENTRY(jboolean, WB_IsGCSelected(JNIEnv* env, jobject o, jint name)) WB_ENTRY(jboolean, WB_IsGCSelected(JNIEnv* env, jobject o, jint name))
return GCConfig::is_gc_selected((CollectedHeap::Name)name); return GCConfig::is_gc_selected((CollectedHeap::Name)name);
WB_END WB_END
@ -1945,6 +1959,14 @@ WB_ENTRY(jboolean, WB_isC2OrJVMCIIncludedInVmBuild(JNIEnv* env))
#endif #endif
WB_END WB_END
WB_ENTRY(jboolean, WB_IsJVMCISupportedByGC(JNIEnv* env))
#if INCLUDE_JVMCI
return JVMCIGlobals::gc_supports_jvmci();
#else
return false;
#endif
WB_END
WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env)) WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env))
return HeapShared::is_heap_object_archiving_allowed(); return HeapShared::is_heap_object_archiving_allowed();
WB_END WB_END
@ -2508,6 +2530,7 @@ static JNINativeMethod methods[] = {
{CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild }, {CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild },
{CC"isJFRIncludedInVmBuild", CC"()Z", (void*)&WB_IsJFRIncludedInVmBuild }, {CC"isJFRIncludedInVmBuild", CC"()Z", (void*)&WB_IsJFRIncludedInVmBuild },
{CC"isC2OrJVMCIIncludedInVmBuild", CC"()Z", (void*)&WB_isC2OrJVMCIIncludedInVmBuild }, {CC"isC2OrJVMCIIncludedInVmBuild", CC"()Z", (void*)&WB_isC2OrJVMCIIncludedInVmBuild },
{CC"isJVMCISupportedByGC", CC"()Z", (void*)&WB_IsJVMCISupportedByGC},
{CC"isJavaHeapArchiveSupported", CC"()Z", (void*)&WB_IsJavaHeapArchiveSupported }, {CC"isJavaHeapArchiveSupported", CC"()Z", (void*)&WB_IsJavaHeapArchiveSupported },
{CC"cdsMemoryMappingFailed", CC"()Z", (void*)&WB_CDSMemoryMappingFailed }, {CC"cdsMemoryMappingFailed", CC"()Z", (void*)&WB_CDSMemoryMappingFailed },
@ -2520,6 +2543,7 @@ static JNINativeMethod methods[] = {
(void*)&WB_AddCompilerDirective }, (void*)&WB_AddCompilerDirective },
{CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective }, {CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective },
{CC"isGCSupported", CC"(I)Z", (void*)&WB_IsGCSupported}, {CC"isGCSupported", CC"(I)Z", (void*)&WB_IsGCSupported},
{CC"isGCSupportedByJVMCICompiler", CC"(I)Z", (void*)&WB_IsGCSupportedByJVMCICompiler},
{CC"isGCSelected", CC"(I)Z", (void*)&WB_IsGCSelected}, {CC"isGCSelected", CC"(I)Z", (void*)&WB_IsGCSelected},
{CC"isGCSelectedErgonomically", CC"()Z", (void*)&WB_IsGCSelectedErgonomically}, {CC"isGCSelectedErgonomically", CC"()Z", (void*)&WB_IsGCSelectedErgonomically},
{CC"supportsConcurrentGCBreakpoints", CC"()Z", (void*)&WB_SupportsConcurrentGCBreakpoints}, {CC"supportsConcurrentGCBreakpoints", CC"()Z", (void*)&WB_SupportsConcurrentGCBreakpoints},

View File

@ -69,6 +69,11 @@ final class HotSpotJVMCICompilerConfig {
public JVMCICompiler createCompiler(JVMCIRuntime rt) { public JVMCICompiler createCompiler(JVMCIRuntime rt) {
return this; return this;
} }
@Override
public boolean isGCSupported(int gcIdentifier) {
return false;
}
} }
/** /**

View File

@ -712,6 +712,11 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
public CompilationRequestResult compileMethod(CompilationRequest request) { public CompilationRequestResult compileMethod(CompilationRequest request) {
throw t; throw t;
} }
@Override
public boolean isGCSupported(int gcIdentifier) {
return false;
}
} }
@Override @Override
@ -814,6 +819,12 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
return hsResult; return hsResult;
} }
@SuppressWarnings("try")
@VMEntryPoint
private boolean isGCSupported(int gcIdentifier) {
return getCompiler().isGCSupported(gcIdentifier);
}
/** /**
* Guard to ensure shut down actions are performed at most once. * Guard to ensure shut down actions are performed at most once.
*/ */

View File

@ -33,4 +33,15 @@ public interface JVMCICompiler {
* install it in the code cache if the compilation is successful. * install it in the code cache if the compilation is successful.
*/ */
CompilationRequestResult compileMethod(CompilationRequest request); CompilationRequestResult compileMethod(CompilationRequest request);
/**
* Determines if this compiler supports the {@code gcIdentifier} garbage collector. The default
* implementation of this method returns true as that is the effective answer given by a
* {@link JVMCICompiler} before this method was added.
*
* @param gcIdentifier a VM dependent GC identifier
*/
default boolean isGCSupported(int gcIdentifier) {
return true;
}
} }

View File

@ -43,6 +43,7 @@ import org.graalvm.compiler.debug.DebugContext.Activation;
import org.graalvm.compiler.debug.DebugHandlersFactory; import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugOptions; import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.hotspot.CompilationCounters.Options; import org.graalvm.compiler.hotspot.CompilationCounters.Options;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase; import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
import org.graalvm.compiler.java.GraphBuilderPhase; import org.graalvm.compiler.java.GraphBuilderPhase;
@ -323,4 +324,13 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable {
} }
}; };
} }
@Override
public boolean isGCSupported(int gcIdentifier) {
HotSpotGC gc = HotSpotGC.forName(gcIdentifier, graalRuntime.getVMConfig());
if (gc != null) {
return gc.supported;
}
return false;
}
} }

View File

@ -247,38 +247,59 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
} }
/** /**
* Constants denoting the GC algorithms available in HotSpot. * Constants denoting the GC algorithms available in HotSpot. The names of the constants match
* the constants in the {@code CollectedHeap::Name} C++ enum.
*/ */
public enum HotSpotGC { public enum HotSpotGC {
// Supported GCs // Supported GCs
Serial(true, "UseSerialGC", true), Serial(true, JDK >= 11, "UseSerialGC", true),
Parallel(true, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10), Parallel(true, JDK >= 11, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10),
CMS(true, "UseConcMarkSweepGC", JDK < 14), CMS(true, JDK >= 11 && JDK <= 14, "UseConcMarkSweepGC", JDK < 14),
G1(true, "UseG1GC", true), G1(true, JDK >= 11, "UseG1GC", true),
// Unsupported GCs // Unsupported GCs
Epsilon(false, "UseEpsilonGC", JDK >= 11), Epsilon(false, JDK >= 11, "UseEpsilonGC", JDK >= 11),
Z(false, "UseZGC", JDK >= 11); Z(false, JDK >= 11, "UseZGC", JDK >= 11),
Shenandoah(false, JDK >= 12, "UseShenandoahGC", JDK >= 12);
HotSpotGC(boolean supported, HotSpotGC(boolean supported, boolean expectNamePresent,
String flag1, boolean expectFlagPresent1, String flag1, boolean expectFlagPresent1,
String flag2, boolean expectFlagPresent2, String flag2, boolean expectFlagPresent2,
String flag3, boolean expectFlagPresent3) { String flag3, boolean expectFlagPresent3) {
this.supported = supported; this.supported = supported;
this.expectNamePresent = expectNamePresent;
this.expectFlagsPresent = new boolean[]{expectFlagPresent1, expectFlagPresent2, expectFlagPresent3}; this.expectFlagsPresent = new boolean[]{expectFlagPresent1, expectFlagPresent2, expectFlagPresent3};
this.flags = new String[]{flag1, flag2, flag3}; this.flags = new String[]{flag1, flag2, flag3};
} }
HotSpotGC(boolean supported, String flag, boolean expectFlagPresent) { HotSpotGC(boolean supported, boolean expectNamePresent, String flag, boolean expectFlagPresent) {
this.supported = supported; this.supported = supported;
this.expectNamePresent = expectNamePresent;
this.expectFlagsPresent = new boolean[]{expectFlagPresent}; this.expectFlagsPresent = new boolean[]{expectFlagPresent};
this.flags = new String[]{flag}; this.flags = new String[]{flag};
} }
/**
* Specifies if this GC supported by Graal.
*/
final boolean supported; final boolean supported;
final boolean[] expectFlagsPresent;
/**
* Specifies if {@link #name()} is expected to be present in the {@code CollectedHeap::Name}
* C++ enum.
*/
final boolean expectNamePresent;
/**
* The VM flags that will select this GC.
*/
private final String[] flags; private final String[] flags;
/**
* Specifies which {@link #flags} are expected to be present in the VM.
*/
final boolean[] expectFlagsPresent;
public boolean isSelected(GraalHotSpotVMConfig config) { public boolean isSelected(GraalHotSpotVMConfig config) {
boolean selected = false; boolean selected = false;
for (int i = 0; i < flags.length; i++) { for (int i = 0; i < flags.length; i++) {
@ -293,6 +314,20 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
} }
return selected; return selected;
} }
/**
* Gets the GC matching {@code name}.
*
* @param name the ordinal of a {@code CollectedHeap::Name} value
*/
static HotSpotGC forName(int name, GraalHotSpotVMConfig config) {
for (HotSpotGC gc : HotSpotGC.values()) {
if (config.getConstant("CollectedHeap::" + gc.name(), Integer.class, -1, gc.expectNamePresent) == name) {
return gc;
}
}
return null;
}
} }
private HotSpotGC getSelectedGC() throws GraalError { private HotSpotGC getSelectedGC() throws GraalError {

View File

@ -239,18 +239,12 @@ public class VMProps implements Callable<Map<String, String>> {
return "false"; return "false";
} }
switch (GC.selected()) { // Not all GCs have full JVMCI support
case Serial: if (!WB.isJVMCISupportedByGC()) {
case Parallel: return "false";
case G1:
// These GCs are supported with JVMCI
return "true";
default:
break;
} }
// Every other GC is not supported return "true";
return "false";
} }
/** /**
@ -271,21 +265,6 @@ public class VMProps implements Callable<Map<String, String>> {
return CPUInfo.getFeatures().toString(); return CPUInfo.getFeatures().toString();
} }
private boolean isGcSupportedByGraal(GC gc) {
switch (gc) {
case Serial:
case Parallel:
case G1:
return true;
case Epsilon:
case Z:
case Shenandoah:
return false;
default:
throw new IllegalStateException("Unknown GC " + gc.name());
}
}
/** /**
* For all existing GC sets vm.gc.X property. * For all existing GC sets vm.gc.X property.
* Example vm.gc.G1=true means: * Example vm.gc.G1=true means:
@ -296,11 +275,11 @@ public class VMProps implements Callable<Map<String, String>> {
* @param map - property-value pairs * @param map - property-value pairs
*/ */
protected void vmGC(SafeMap map) { protected void vmGC(SafeMap map) {
var isGraalEnabled = Compiler.isGraalEnabled(); var isJVMCIEnabled = Compiler.isJVMCIEnabled();
for (GC gc: GC.values()) { for (GC gc: GC.values()) {
map.put("vm.gc." + gc.name(), map.put("vm.gc." + gc.name(),
() -> "" + (gc.isSupported() () -> "" + (gc.isSupported()
&& (!isGraalEnabled || isGcSupportedByGraal(gc)) && (!isJVMCIEnabled || gc.isSupportedByJVMCICompiler())
&& (gc.isSelected() || GC.isSelectedErgonomically()))); && (gc.isSelected() || GC.isSelectedErgonomically())));
} }
} }

View File

@ -232,6 +232,7 @@ public class WhiteBox {
// Compiler // Compiler
public native boolean isC2OrJVMCIIncludedInVmBuild(); public native boolean isC2OrJVMCIIncludedInVmBuild();
public native boolean isJVMCISupportedByGC();
public native int matchesMethod(Executable method, String pattern); public native int matchesMethod(Executable method, String pattern);
public native int matchesInline(Executable method, String pattern); public native int matchesInline(Executable method, String pattern);
@ -415,6 +416,7 @@ public class WhiteBox {
// Don't use these methods directly // Don't use these methods directly
// Use sun.hotspot.gc.GC class instead. // Use sun.hotspot.gc.GC class instead.
public native boolean isGCSupported(int name); public native boolean isGCSupported(int name);
public native boolean isGCSupportedByJVMCICompiler(int name);
public native boolean isGCSelected(int name); public native boolean isGCSelected(int name);
public native boolean isGCSelectedErgonomically(); public native boolean isGCSelectedErgonomically();

View File

@ -43,6 +43,20 @@ public class Compiler {
return WB.isC2OrJVMCIIncludedInVmBuild(); return WB.isC2OrJVMCIIncludedInVmBuild();
} }
/**
* Check if JVMCI is enabled.
*
* @return true if JVMCI is enabled
*/
public static boolean isJVMCIEnabled() {
Boolean enableJvmci = WB.getBooleanVMFlag("EnableJVMCI");
if (enableJvmci == null || !enableJvmci) {
return false;
}
return true;
}
/** /**
* Check if Graal is used as JIT compiler. * Check if Graal is used as JIT compiler.
* *

View File

@ -55,6 +55,13 @@ public enum GC {
return WB.isGCSupported(name); return WB.isGCSupported(name);
} }
/**
* @return true if this GC is supported by the JVMCI compiler
*/
public boolean isSupportedByJVMCICompiler() {
return WB.isGCSupportedByJVMCICompiler(name);
}
/** /**
* @return true if this GC is currently selected/used * @return true if this GC is currently selected/used
*/ */