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

View file

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

View file

@ -56,6 +56,9 @@ class Compiler: public AbstractCompiler {
// Check if the C1 compiler supports an intrinsic for 'method'. // Check if the C1 compiler supports an intrinsic for 'method'.
virtual bool is_intrinsic_supported(const methodHandle& 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 // Size of the code buffer
static int code_buffer_size(); static int code_buffer_size();
}; };

View file

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

View file

@ -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. JavaThread* THREAD = JavaThread::current(); // For exception macros.
if (is_hotspot()) { if (is_hotspot()) {
HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject())); 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_name(this, obj, HotSpotJVMCI::resolve(name));
HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor)); HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id); 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); return wrap(obj);
} else { } else {
JNIAccessMark jni(this, THREAD); JNIAccessMark jni(this, THREAD);
jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(), jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
JNIJVMCI::VMIntrinsicMethod::constructor(), 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); return wrap(result);
} }
} }

View file

@ -406,7 +406,7 @@ public:
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS); 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_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_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_HotSpotStackFrameReference(JVMCI_TRAPS);
JVMCIObject new_JVMCIError(JVMCI_TRAPS); JVMCIObject new_JVMCIError(JVMCI_TRAPS);
JVMCIObject new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS); JVMCIObject new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS);

View file

@ -131,7 +131,10 @@
object_field(VMIntrinsicMethod, name, "Ljava/lang/String;") \ object_field(VMIntrinsicMethod, name, "Ljava/lang/String;") \
object_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;") \ object_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;") \
int_field(VMIntrinsicMethod, id) \ 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 \ end_class \
start_class(HotSpotCompilationRequestResult, jdk_vm_ci_hotspot_HotSpotCompilationRequestResult) \ start_class(HotSpotCompilationRequestResult, jdk_vm_ci_hotspot_HotSpotCompilationRequestResult) \
object_field(HotSpotCompilationRequestResult, failureMessage, "Ljava/lang/String;") \ object_field(HotSpotCompilationRequestResult, failureMessage, "Ljava/lang/String;") \

View file

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

View file

@ -63,6 +63,8 @@ public:
// Return false otherwise. // Return false otherwise.
virtual bool is_intrinsic_supported(const methodHandle& method); 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) // Initial size of the code buffer (may be increased at runtime)
static int initial_code_buffer_size(int const_size = initial_const_capacity); static int initial_code_buffer_size(int const_size = initial_const_capacity);
}; };

View file

@ -184,7 +184,8 @@ public final class HotSpotVMConfigStore {
printConfigLine(runtime, "[vmconfig:constant] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue()); printConfigLine(runtime, "[vmconfig:constant] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue());
} }
for (VMIntrinsicMethod e : getIntrinsics()) { 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);
} }
} }

View file

@ -54,12 +54,32 @@ public final class VMIntrinsicMethod {
*/ */
public final int id; 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 @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.declaringClass = declaringClass;
this.name = name; this.name = name;
this.descriptor = descriptor; this.descriptor = descriptor;
this.id = id; this.id = id;
this.isAvailable = isAvailable;
this.c1Supported = c1Supported;
this.c2Supported = c2Supported;
} }
@Override @Override
@ -69,7 +89,10 @@ public final class VMIntrinsicMethod {
if (that.id == this.id) { if (that.id == this.id) {
assert that.name.equals(this.name) && assert that.name.equals(this.name) &&
that.declaringClass.equals(this.declaringClass) && 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; return true;
} }
} }
@ -83,6 +106,7 @@ public final class VMIntrinsicMethod {
@Override @Override
public String toString() { 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);
} }
} }