Skip to content
This repository has been archived by the owner before Nov 9, 2022. It is now read-only.
Permalink
Browse files
8257020: [JVMCI] enable a JVMCICompiler to specify which GCs it supports
Reviewed-by: stefank, kvn
  • Loading branch information
Doug Simon committed Dec 3, 2020
1 parent 129c377 commit fa58671f9f8a8230d907c0a6289685f8455bce1f
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 41 deletions.
@@ -457,7 +457,7 @@ void CompilerConfig::ergo_initialize() {
#endif

#if INCLUDE_JVMCI
// Check that JVMCI compiler supports selested GC.
// Check that JVMCI supports selected GC.
// Should be done after GCConfig::initialize() was called.
JVMCIGlobals::check_jvmci_supported_gc();

@@ -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,
jlong compile_state, int id) {
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
@@ -310,6 +310,8 @@ class JVMCIEnv : public ResourceObj {
JVMCIObject call_JavaConstant_forFloat(float 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);

#define DO_THROW(name) \
@@ -348,6 +348,7 @@
start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \
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, 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, decodeThrowable, decodeThrowable_signature, (JVMCIObject encodedThrowable)) \
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \
@@ -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,
@@ -25,6 +25,7 @@
#define SHARE_JVMCI_JVMCIRUNTIME_HPP

#include "code/nmethod.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciExceptions.hpp"
#include "jvmci/jvmciObject.hpp"
@@ -279,6 +280,9 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
// Compiles `target` with the JVMCI compiler.
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.
JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV,
const methodHandle& target,
@@ -200,11 +200,15 @@ bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin) {
return true;
}

bool JVMCIGlobals::gc_supports_jvmci() {
return UseSerialGC || UseParallelGC || UseG1GC;
}

void JVMCIGlobals::check_jvmci_supported_gc() {
if (EnableJVMCI) {
// Check if selected GC is supported by JVMCI and Java compiler
if (!(UseSerialGC || UseParallelGC || UseG1GC)) {
vm_exit_during_initialization("JVMCI Compiler does not support selected GC", GCConfig::hs_err_name());
if (!gc_supports_jvmci()) {
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(UseJVMCICompiler, false);
}
@@ -155,7 +155,10 @@ class JVMCIGlobals {
// Convert JVMCI experimental flags to product
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 fileStream* get_jni_config_file() { return _jni_config_file; }
@@ -482,6 +482,14 @@
declare_constant(CodeInstaller::VERIFY_OOP_MASK) \
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::LAST_MH_SIG_POLY) \
declare_constant(vmIntrinsics::_invokeGeneric) \
@@ -103,6 +103,7 @@
template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \
template(compileMethod_name, "compileMethod") \
template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
template(isGCSupported_name, "isGCSupported") \
template(encodeThrowable_name, "encodeThrowable") \
template(encodeThrowable_signature, "(Ljava/lang/Throwable;)Ljava/lang/String;") \
template(decodeThrowable_name, "decodeThrowable") \
@@ -94,6 +94,7 @@
LOG_TAG(jfr) \
LOG_TAG(jit) \
LOG_TAG(jni) \
LOG_TAG(jvmci) \
LOG_TAG(jvmti) \
LOG_TAG(lambda) \
LOG_TAG(library) \
@@ -108,6 +108,10 @@
#include "services/memTracker.hpp"
#include "utilities/nativeCallStack.hpp"
#endif // INCLUDE_NMT
#if INCLUDE_JVMCI
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
#endif
#if INCLUDE_AOT
#include "aot/aotLoader.hpp"
#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);
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))
return GCConfig::is_gc_selected((CollectedHeap::Name)name);
WB_END
@@ -1945,6 +1959,14 @@ WB_ENTRY(jboolean, WB_isC2OrJVMCIIncludedInVmBuild(JNIEnv* env))
#endif
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))
return HeapShared::is_heap_object_archiving_allowed();
WB_END
@@ -2508,6 +2530,7 @@ static JNINativeMethod methods[] = {
{CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild },
{CC"isJFRIncludedInVmBuild", CC"()Z", (void*)&WB_IsJFRIncludedInVmBuild },
{CC"isC2OrJVMCIIncludedInVmBuild", CC"()Z", (void*)&WB_isC2OrJVMCIIncludedInVmBuild },
{CC"isJVMCISupportedByGC", CC"()Z", (void*)&WB_IsJVMCISupportedByGC},
{CC"isJavaHeapArchiveSupported", CC"()Z", (void*)&WB_IsJavaHeapArchiveSupported },
{CC"cdsMemoryMappingFailed", CC"()Z", (void*)&WB_CDSMemoryMappingFailed },

@@ -2520,6 +2543,7 @@ static JNINativeMethod methods[] = {
(void*)&WB_AddCompilerDirective },
{CC"removeCompilerDirective", CC"(I)V", (void*)&WB_RemoveCompilerDirective },
{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"isGCSelectedErgonomically", CC"()Z", (void*)&WB_IsGCSelectedErgonomically},
{CC"supportsConcurrentGCBreakpoints", CC"()Z", (void*)&WB_SupportsConcurrentGCBreakpoints},
@@ -69,6 +69,11 @@ public String getCompilerName() {
public JVMCICompiler createCompiler(JVMCIRuntime rt) {
return this;
}

@Override
public boolean isGCSupported(int gcIdentifier) {
return false;
}
}

/**
@@ -712,6 +712,11 @@ static class ErrorCreatingCompiler implements JVMCICompiler {
public CompilationRequestResult compileMethod(CompilationRequest request) {
throw t;
}

@Override
public boolean isGCSupported(int gcIdentifier) {
return false;
}
}

@Override
@@ -814,6 +819,12 @@ private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod
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.
*/
@@ -33,4 +33,15 @@ public interface JVMCICompiler {
* install it in the code cache if the compilation is successful.
*/
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;
}
}
@@ -43,6 +43,7 @@
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugOptions;
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.phases.OnStackReplacementPhase;
import org.graalvm.compiler.java.GraphBuilderPhase;
@@ -323,4 +324,13 @@ public void formatTo(Formatter buf, int flags, int width, int precision) {
}
};
}

@Override
public boolean isGCSupported(int gcIdentifier) {
HotSpotGC gc = HotSpotGC.forName(gcIdentifier, graalRuntime.getVMConfig());
if (gc != null) {
return gc.supported;
}
return false;
}
}
@@ -247,38 +247,59 @@ public GlobalMetrics getMetricValues() {
}

/**
* 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 {
// Supported GCs
Serial(true, "UseSerialGC", true),
Parallel(true, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10),
CMS(true, "UseConcMarkSweepGC", JDK < 14),
G1(true, "UseG1GC", true),
Serial(true, JDK >= 11, "UseSerialGC", true),
Parallel(true, JDK >= 11, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10),
CMS(true, JDK >= 11 && JDK <= 14, "UseConcMarkSweepGC", JDK < 14),
G1(true, JDK >= 11, "UseG1GC", true),

// Unsupported GCs
Epsilon(false, "UseEpsilonGC", JDK >= 11),
Z(false, "UseZGC", JDK >= 11);
Epsilon(false, JDK >= 11, "UseEpsilonGC", 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 flag2, boolean expectFlagPresent2,
String flag3, boolean expectFlagPresent3) {
this.supported = supported;
this.expectNamePresent = expectNamePresent;
this.expectFlagsPresent = new boolean[]{expectFlagPresent1, expectFlagPresent2, expectFlagPresent3};
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.expectNamePresent = expectNamePresent;
this.expectFlagsPresent = new boolean[]{expectFlagPresent};
this.flags = new String[]{flag};
}

/**
* Specifies if this GC supported by Graal.
*/
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;

/**
* Specifies which {@link #flags} are expected to be present in the VM.
*/
final boolean[] expectFlagsPresent;

public boolean isSelected(GraalHotSpotVMConfig config) {
boolean selected = false;
for (int i = 0; i < flags.length; i++) {
@@ -293,6 +314,20 @@ public boolean isSelected(GraalHotSpotVMConfig config) {
}
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 {

0 comments on commit fa58671

Please sign in to comment.