diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp index ec06cbb1b41..567cd5fa8b5 100644 --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -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; diff --git a/src/hotspot/share/c1/c1_Compiler.hpp b/src/hotspot/share/c1/c1_Compiler.hpp index 8f2afa85dba..9095a13297e 100644 --- a/src/hotspot/share/c1/c1_Compiler.hpp +++ b/src/hotspot/share/c1/c1_Compiler.hpp @@ -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(); }; diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp index 64d28617b78..d645a43d9be 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp @@ -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) \ diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index e70f2785426..d61cc269874 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -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); } } diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index ca76d6501f2..345504affb8 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp @@ -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); diff --git a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp index 9bd87009b11..3561093caaa 100644 --- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp +++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp @@ -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;") \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index 54a23890486..398eb80b8cf 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -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: diff --git a/src/hotspot/share/opto/c2compiler.hpp b/src/hotspot/share/opto/c2compiler.hpp index 415688cdad4..bfc335c4869 100644 --- a/src/hotspot/share/opto/c2compiler.hpp +++ b/src/hotspot/share/opto/c2compiler.hpp @@ -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); }; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java index 647779d5794..0ee69f135c9 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java @@ -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); } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java index 2de959151b6..d43c9dcca72 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/VMIntrinsicMethod.java @@ -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); } }