8313372: [JVMCI] Export vmIntrinsics::is_intrinsic_available results to JVMCI compilers.

Reviewed-by: dnsimon, kvn
This commit is contained in:
Yudi Zheng 2023-08-14 08:56:15 +00:00 committed by Doug Simon
parent 049b55f24e
commit 4164693f3b
10 changed files with 74 additions and 17 deletions

@ -104,7 +104,10 @@ bool Compiler::is_intrinsic_supported(const methodHandle& method) {
// C1 does not support intrinsification of synchronized methods.
return false;
}
return Compiler::is_intrinsic_supported(id);
}
bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
switch (id) {
case vmIntrinsics::_compareAndSetLong:
if (!VM_Version::supports_cx8()) return false;

@ -56,6 +56,9 @@ class Compiler: public AbstractCompiler {
// Check if the C1 compiler supports an intrinsic for 'method'.
virtual bool is_intrinsic_supported(const methodHandle& method);
// Return true if the intrinsic `id` is supported by C1
static bool is_intrinsic_supported(vmIntrinsics::ID id);
// Size of the code buffer
static int code_buffer_size();
};

@ -22,6 +22,7 @@
*/
// no precompiled headers
#include "c1/c1_Compiler.hpp"
#include "ci/ciUtilities.hpp"
#include "compiler/compiler_globals.hpp"
#include "compiler/oopMap.hpp"
@ -42,6 +43,7 @@
#include "memory/universe.hpp"
#include "oops/compressedOops.hpp"
#include "oops/klass.inline.hpp"
#include "opto/c2compiler.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
@ -239,7 +241,10 @@ JVMCIObjectArray CompilerToVM::initialize_intrinsics(JVMCI_TRAPS) {
} \
JVMCIObject name_str = VM_SYMBOL_TO_STRING(name); \
JVMCIObject sig_str = VM_SYMBOL_TO_STRING(sig); \
JVMCIObject vmIntrinsicMethod = JVMCIENV->new_VMIntrinsicMethod(kls_str, name_str, sig_str, (jint) vmIntrinsics::id, JVMCI_CHECK_NULL); \
JVMCIObject vmIntrinsicMethod = JVMCIENV->new_VMIntrinsicMethod(kls_str, name_str, sig_str, (jint) vmIntrinsics::id, \
(jboolean) vmIntrinsics::is_intrinsic_available(vmIntrinsics::id), \
(jboolean) Compiler::is_intrinsic_supported(vmIntrinsics::id), \
(jboolean) C2Compiler::is_intrinsic_supported(vmIntrinsics::id), JVMCI_CHECK_NULL); \
JVMCIENV->put_object_at(vmIntrinsics, index++, vmIntrinsicMethod); \
}
@ -286,7 +291,7 @@ JVMCIObjectArray CompilerToVM::initialize_intrinsics(JVMCI_TRAPS) {
do_uintx_flag(TLABWasteIncrement) \
do_intx_flag(TypeProfileWidth) \
do_bool_flag(UseAESIntrinsics) \
X86_ONLY(do_int_flag(UseAVX)) \
X86_ONLY(do_int_flag(UseAVX)) \
do_bool_flag(UseCRC32Intrinsics) \
do_bool_flag(UseAdler32Intrinsics) \
do_bool_flag(UseCompressedClassPointers) \
@ -306,7 +311,7 @@ JVMCIObjectArray CompilerToVM::initialize_intrinsics(JVMCI_TRAPS) {
do_bool_flag(UseSHA1Intrinsics) \
do_bool_flag(UseSHA256Intrinsics) \
do_bool_flag(UseSHA512Intrinsics) \
X86_ONLY(do_int_flag(UseSSE)) \
X86_ONLY(do_int_flag(UseSSE)) \
COMPILER2_PRESENT(do_bool_flag(UseSquareToLenIntrinsic)) \
do_bool_flag(UseTLAB) \
do_bool_flag(VerifyOops) \

@ -1459,7 +1459,7 @@ JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject
}
}
JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {
JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS) {
JavaThread* THREAD = JavaThread::current(); // For exception macros.
if (is_hotspot()) {
HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
@ -1468,12 +1468,15 @@ JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObj
HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
HotSpotJVMCI::VMIntrinsicMethod::set_isAvailable(this, obj, isAvailable);
HotSpotJVMCI::VMIntrinsicMethod::set_c1Supported(this, obj, c1Supported);
HotSpotJVMCI::VMIntrinsicMethod::set_c2Supported(this, obj, c2Supported);
return wrap(obj);
} else {
JNIAccessMark jni(this, THREAD);
jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
JNIJVMCI::VMIntrinsicMethod::constructor(),
get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);
get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id, isAvailable, c1Supported, c2Supported);
return wrap(result);
}
}

@ -406,7 +406,7 @@ public:
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS);
JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS);
JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS);
JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS);
JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS);
JVMCIObject new_HotSpotStackFrameReference(JVMCI_TRAPS);
JVMCIObject new_JVMCIError(JVMCI_TRAPS);
JVMCIObject new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS);

@ -131,7 +131,10 @@
object_field(VMIntrinsicMethod, name, "Ljava/lang/String;") \
object_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;") \
int_field(VMIntrinsicMethod, id) \
jvmci_constructor(VMIntrinsicMethod, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V") \
boolean_field(VMIntrinsicMethod, isAvailable) \
boolean_field(VMIntrinsicMethod, c1Supported) \
boolean_field(VMIntrinsicMethod, c2Supported) \
jvmci_constructor(VMIntrinsicMethod, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZZ)V") \
end_class \
start_class(HotSpotCompilationRequestResult, jdk_vm_ci_hotspot_HotSpotCompilationRequestResult) \
object_field(HotSpotCompilationRequestResult, failureMessage, "Ljava/lang/String;") \

@ -190,6 +190,10 @@ void C2Compiler::print_timers() {
bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
vmIntrinsics::ID id = method->intrinsic_id();
return C2Compiler::is_intrinsic_supported(id);
}
bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
if (id < vmIntrinsics::FIRST_ID || id > vmIntrinsics::LAST_COMPILER_INLINE) {
@ -225,6 +229,21 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
case vmIntrinsics::_copyMemory:
if (StubRoutines::unsafe_arraycopy() == nullptr) return false;
break;
case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
if (StubRoutines::electronicCodeBook_encryptAESCrypt() == nullptr) return false;
break;
case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
if (StubRoutines::electronicCodeBook_decryptAESCrypt() == nullptr) return false;
break;
case vmIntrinsics::_galoisCounterMode_AESCrypt:
if (StubRoutines::galoisCounterMode_AESCrypt() == nullptr) return false;
break;
case vmIntrinsics::_bigIntegerRightShiftWorker:
if (StubRoutines::bigIntegerRightShift() == nullptr) return false;
break;
case vmIntrinsics::_bigIntegerLeftShiftWorker:
if (StubRoutines::bigIntegerLeftShift() == nullptr) return false;
break;
case vmIntrinsics::_encodeAsciiArray:
if (!Matcher::match_rule_supported(Op_EncodeISOArray) || !Matcher::supports_encode_ascii_array) return false;
break;
@ -716,10 +735,7 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
case vmIntrinsics::_aescrypt_decryptBlock:
case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
case vmIntrinsics::_counterMode_AESCrypt:
case vmIntrinsics::_galoisCounterMode_AESCrypt:
case vmIntrinsics::_md5_implCompress:
case vmIntrinsics::_sha_implCompress:
case vmIntrinsics::_sha2_implCompress:
@ -731,8 +747,6 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
case vmIntrinsics::_mulAdd:
case vmIntrinsics::_montgomeryMultiply:
case vmIntrinsics::_montgomerySquare:
case vmIntrinsics::_bigIntegerRightShiftWorker:
case vmIntrinsics::_bigIntegerLeftShiftWorker:
case vmIntrinsics::_vectorizedMismatch:
case vmIntrinsics::_ghash_processBlocks:
case vmIntrinsics::_chacha20Block:
@ -752,7 +766,6 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
case vmIntrinsics::_Preconditions_checkLongIndex:
case vmIntrinsics::_getObjectSize:
break;
case vmIntrinsics::_VectorCompressExpand:
case vmIntrinsics::_VectorUnaryOp:
case vmIntrinsics::_VectorBinaryOp:

@ -63,6 +63,8 @@ public:
// Return false otherwise.
virtual bool is_intrinsic_supported(const methodHandle& method);
// Return true if the intrinsic `id` is supported by C2
static bool is_intrinsic_supported(vmIntrinsics::ID id);
// Initial size of the code buffer (may be increased at runtime)
static int initial_code_buffer_size(int const_size = initial_const_capacity);
};

@ -184,7 +184,8 @@ public final class HotSpotVMConfigStore {
printConfigLine(runtime, "[vmconfig:constant] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue());
}
for (VMIntrinsicMethod e : getIntrinsics()) {
printConfigLine(runtime, "[vmconfig:intrinsic] %d = %s.%s %s%n", e.id, e.declaringClass, e.name, e.descriptor);
printConfigLine(runtime, "[vmconfig:intrinsic] %d = (available:%b c1Supported:%b c2Supported:%b) %s.%s %s%n",
e.id, e.isAvailable, e.c1Supported, e.c2Supported, e.declaringClass, e.name, e.descriptor);
}
}

@ -54,12 +54,32 @@ public final class VMIntrinsicMethod {
*/
public final int id;
/**
* This value reflects the `ControlIntrinsic`, `DisableIntrinsic` and `UseXXXIntrinsic` VM flags
* as well as other factors such as the current CPU.
*/
public final boolean isAvailable;
/**
* True if this intrinsic is supported by C1.
*/
public final boolean c1Supported;
/**
* True if this intrinsic is supported by C2.
*/
public final boolean c2Supported;
@VMEntryPoint
VMIntrinsicMethod(String declaringClass, String name, String descriptor, int id) {
VMIntrinsicMethod(String declaringClass, String name, String descriptor, int id,
boolean isAvailable, boolean c1Supported, boolean c2Supported) {
this.declaringClass = declaringClass;
this.name = name;
this.descriptor = descriptor;
this.id = id;
this.isAvailable = isAvailable;
this.c1Supported = c1Supported;
this.c2Supported = c2Supported;
}
@Override
@ -69,7 +89,10 @@ public final class VMIntrinsicMethod {
if (that.id == this.id) {
assert that.name.equals(this.name) &&
that.declaringClass.equals(this.declaringClass) &&
that.descriptor.equals(this.descriptor);
that.descriptor.equals(this.descriptor) &&
that.isAvailable == this.isAvailable &&
that.c1Supported == this.c1Supported &&
that.c2Supported == this.c2Supported;
return true;
}
}
@ -83,6 +106,7 @@ public final class VMIntrinsicMethod {
@Override
public String toString() {
return String.format("IntrinsicMethod[declaringClass=%s, name=%s, descriptor=%s, id=%d]", declaringClass, name, descriptor, id);
return String.format("IntrinsicMethod[declaringClass=%s, name=%s, descriptor=%s, id=%d, isAvailable=%b, c1Supported=%b, c2Supported=%b]",
declaringClass, name, descriptor, id, isAvailable, c1Supported, c2Supported);
}
}