8229236: CriticalJNINatives: dll handling should be done in native thread state
Summary: Temporarily switch thread state from _thread_in_vm to _thread_in_native to execute I/O.
Reviewed-by: dlong, dholmes
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -1248,7 +1248,8 @@
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
if (method->is_method_handle_intrinsic()) {
vmIntrinsics::ID iid = method->intrinsic_id();
intptr_t start = (intptr_t)__ pc();
@@ -1274,7 +1275,7 @@
(OopMapSet*)NULL);
}
bool is_critical_native = true;
- address native_func = method->critical_native_function();
+ address native_func = critical_entry;
if (native_func == NULL) {
native_func = method->native_function();
is_critical_native = false;
--- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -752,7 +752,8 @@
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
if (method->is_method_handle_intrinsic()) {
vmIntrinsics::ID iid = method->intrinsic_id();
intptr_t start = (intptr_t)__ pc();
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -1849,7 +1849,8 @@
int compile_id,
BasicType *in_sig_bt,
VMRegPair *in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
#ifdef COMPILER2
if (method->is_method_handle_intrinsic()) {
vmIntrinsics::ID iid = method->intrinsic_id();
@@ -1874,7 +1875,7 @@
}
bool is_critical_native = true;
- address native_func = method->critical_native_function();
+ address native_func = critical_entry;
if (native_func == NULL) {
native_func = method->native_function();
is_critical_native = false;
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -1518,7 +1518,8 @@
int compile_id,
BasicType *in_sig_bt,
VMRegPair *in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
#ifdef COMPILER2
int total_in_args = method->size_of_parameters();
if (method->is_method_handle_intrinsic()) {
@@ -1554,7 +1555,7 @@
///////////////////////////////////////////////////////////////////////
bool is_critical_native = true;
- address native_func = method->critical_native_function();
+ address native_func = critical_entry;
if (native_func == NULL) {
native_func = method->native_function();
is_critical_native = false;
--- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -1751,7 +1751,8 @@
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
if (method->is_method_handle_intrinsic()) {
vmIntrinsics::ID iid = method->intrinsic_id();
intptr_t start = (intptr_t)__ pc();
@@ -1774,7 +1775,7 @@
(OopMapSet*)NULL);
}
bool is_critical_native = true;
- address native_func = method->critical_native_function();
+ address native_func = critical_entry;
if (native_func == NULL) {
native_func = method->native_function();
is_critical_native = false;
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -1524,7 +1524,8 @@
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
if (method->is_method_handle_intrinsic()) {
vmIntrinsics::ID iid = method->intrinsic_id();
intptr_t start = (intptr_t)__ pc();
@@ -1547,7 +1548,7 @@
(OopMapSet*)NULL);
}
bool is_critical_native = true;
- address native_func = method->critical_native_function();
+ address native_func = critical_entry;
if (native_func == NULL) {
native_func = method->native_function();
is_critical_native = false;
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -1924,7 +1924,8 @@
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
if (method->is_method_handle_intrinsic()) {
vmIntrinsics::ID iid = method->intrinsic_id();
intptr_t start = (intptr_t)__ pc();
@@ -1947,7 +1948,7 @@
(OopMapSet*)NULL);
}
bool is_critical_native = true;
- address native_func = method->critical_native_function();
+ address native_func = critical_entry;
if (native_func == NULL) {
native_func = method->native_function();
is_critical_native = false;
--- a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -75,7 +75,8 @@
int compile_id,
BasicType *sig_bt,
VMRegPair *regs,
- BasicType ret_type) {
+ BasicType ret_type,
+ address critical_entry) {
ShouldNotCallThis();
return NULL;
}
--- a/src/hotspot/share/oops/method.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/share/oops/method.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -828,11 +828,6 @@
clear_code();
}
-address Method::critical_native_function() {
- methodHandle mh(this);
- return NativeLookup::lookup_critical_entry(mh);
-}
-
void Method::set_signature_handler(address handler) {
address* signature_handler = signature_handler_addr();
--- a/src/hotspot/share/oops/method.hpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/share/oops/method.hpp Mon Aug 12 10:02:25 2019 +0200
@@ -533,7 +533,6 @@
native_bind_event_is_interesting = true
};
address native_function() const { return *(native_function_addr()); }
- address critical_native_function();
// Must specify a real function (not NULL).
// Use clear_native_function() to unregister.
--- a/src/hotspot/share/prims/nativeLookup.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/share/prims/nativeLookup.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -38,6 +38,7 @@
#include "prims/unsafe.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/sharedRuntime.hpp"
@@ -258,7 +259,7 @@
// Check all the formats of native implementation name to see if there is one
// for the specified method.
address NativeLookup::lookup_critical_entry(const methodHandle& method) {
- if (!CriticalJNINatives) return NULL;
+ assert(CriticalJNINatives, "or should not be here");
if (method->is_synchronized() ||
!method->is_static()) {
@@ -284,6 +285,9 @@
}
}
+ // dll handling requires I/O. Don't do that while in _thread_in_vm (safepoint may get requested).
+ ThreadToNativeFromVM thread_in_native(JavaThread::current());
+
void* dll = dll_load(method);
address entry = NULL;
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Mon Aug 12 10:02:25 2019 +0200
@@ -2849,11 +2849,17 @@
void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
ResourceMark rm;
nmethod* nm = NULL;
+ address critical_entry = NULL;
assert(method->is_native(), "must be native");
assert(method->is_method_handle_intrinsic() ||
method->has_native_function(), "must have something valid to call!");
+ if (CriticalJNINatives && !method->is_method_handle_intrinsic()) {
+ // We perform the I/O with transition to native before acquiring AdapterHandlerLibrary_lock.
+ critical_entry = NativeLookup::lookup_critical_entry(method);
+ }
+
{
// Perform the work while holding the lock, but perform any printing outside the lock
MutexLocker mu(AdapterHandlerLibrary_lock);
@@ -2898,7 +2904,7 @@
int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
// Generate the compiled-to-native wrapper code
- nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type);
+ nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type, critical_entry);
if (nm != NULL) {
method->set_code(method, nm);
--- a/src/hotspot/share/runtime/sharedRuntime.hpp Mon Aug 12 08:48:47 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.hpp Mon Aug 12 10:02:25 2019 +0200
@@ -485,7 +485,8 @@
int compile_id,
BasicType* sig_bt,
VMRegPair* regs,
- BasicType ret_type);
+ BasicType ret_type,
+ address critical_entry);
// Block before entering a JNI critical method
static void block_for_jni_critical(JavaThread* thread);