8229236: CriticalJNINatives: dll handling should be done in native thread state

Temporarily switch thread state from _thread_in_vm to _thread_in_native to execute I/O.

Reviewed-by: dlong, dholmes
This commit is contained in:
Martin Doerr 2019-08-12 10:02:25 +02:00
parent fd4dc1dfd2
commit 50baeb8180
13 changed files with 36 additions and 23 deletions

View file

@ -1248,7 +1248,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
(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;

View file

@ -752,7 +752,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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();

View file

@ -1849,7 +1849,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
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 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
}
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;

View file

@ -1518,7 +1518,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
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 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
///////////////////////////////////////////////////////////////////////
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;

View file

@ -1751,7 +1751,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
(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;

View file

@ -1524,7 +1524,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
(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;

View file

@ -1924,7 +1924,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
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 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
(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;

View file

@ -75,7 +75,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
int compile_id,
BasicType *sig_bt,
VMRegPair *regs,
BasicType ret_type) {
BasicType ret_type,
address critical_entry) {
ShouldNotCallThis();
return NULL;
}

View file

@ -828,11 +828,6 @@ void Method::clear_native_function() {
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();

View file

@ -533,7 +533,6 @@ class Method : public Metadata {
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.

View file

@ -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 @@ address NativeLookup::lookup_entry(const methodHandle& method, bool& in_base_lib
// 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 @@ address NativeLookup::lookup_critical_entry(const methodHandle& method) {
}
}
// 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;

View file

@ -2849,11 +2849,17 @@ bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) {
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 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
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);

View file

@ -485,7 +485,8 @@ class SharedRuntime: AllStatic {
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);