8183198: Factor out thread state serialization into a proper helper function

Reviewed-by: tschatzl, eosterlund, coleenp
This commit is contained in:
Mikael Gerdin 2017-06-26 15:25:25 +02:00
parent cf0d8c433e
commit d39a34d689
10 changed files with 50 additions and 233 deletions

View file

@ -378,14 +378,7 @@ int CppInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
thread->set_thread_state(_thread_in_native_trans);
// Make sure new state is visible in the GC thread
if (os::is_MP()) {
if (UseMembar) {
OrderAccess::fence();
}
else {
InterfaceSupport::serialize_memory(thread);
}
}
InterfaceSupport::serialize_thread_state(thread);
// Handle safepoint operations, pending suspend requests,
// and pending asynchronous exceptions.

View file

@ -1,35 +0,0 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_AIX_VM_INTERFACESUPPORT_AIX_HPP
#define OS_AIX_VM_INTERFACESUPPORT_AIX_HPP
// Contains inlined functions for class InterfaceSupport
static inline void serialize_memory(JavaThread *thread) {
os::write_memory_serialize_page(thread);
}
#endif // OS_AIX_VM_INTERFACESUPPORT_AIX_HPP

View file

@ -1,34 +0,0 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_BSD_VM_INTERFACESUPPORT_BSD_HPP
#define OS_BSD_VM_INTERFACESUPPORT_BSD_HPP
// Contains inlined functions for class InterfaceSupport
static inline void serialize_memory(JavaThread *thread) {
os::write_memory_serialize_page(thread);
}
#endif // OS_BSD_VM_INTERFACESUPPORT_BSD_HPP

View file

@ -1,34 +0,0 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP
#define OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP
// Contains inlined functions for class InterfaceSupport
static inline void serialize_memory(JavaThread *thread) {
os::write_memory_serialize_page(thread);
}
#endif // OS_LINUX_VM_INTERFACESUPPORT_LINUX_HPP

View file

@ -107,6 +107,11 @@ public:
static char* realpath(const char* filename, char* outbuf, size_t outbuflen);
};
// On POSIX platforms the signal handler is global so we just do the write.
static void write_memory_serialize_page_with_handler(JavaThread* thread) {
write_memory_serialize_page(thread);
}
/*
* Crash protection for the watcher thread. Wrap the callback
* with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp

View file

@ -1,34 +0,0 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_SOLARIS_VM_INTERFACESUPPORT_SOLARIS_HPP
#define OS_SOLARIS_VM_INTERFACESUPPORT_SOLARIS_HPP
// Contains inlined functions for class InterfaceSupport
static inline void serialize_memory(JavaThread *thread) {
os::write_memory_serialize_page(thread);
}
#endif // OS_SOLARIS_VM_INTERFACESUPPORT_SOLARIS_HPP

View file

@ -1,46 +0,0 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_WINDOWS_VM_INTERFACESUPPORT_WINDOWS_HPP
#define OS_WINDOWS_VM_INTERFACESUPPORT_WINDOWS_HPP
// Contains inlined functions for class InterfaceSupport
static inline void serialize_memory(JavaThread *thread) {
// due to chained nature of SEH handlers we have to be sure
// that our handler is always last handler before an attempt to write
// into serialization page - it can fault if we access this page
// right in the middle of protect/unprotect sequence by remote
// membar logic.
// __try/__except are very lightweight operations (only several
// instructions not affecting control flow directly on x86)
// so we can use it here, on very time critical path
__try {
os::write_memory_serialize_page(thread);
} __except (os::win32::
serialize_fault_filter((_EXCEPTION_POINTERS*)_exception_info()))
{}
}
#endif // OS_WINDOWS_VM_INTERFACESUPPORT_WINDOWS_HPP

View file

@ -123,6 +123,21 @@ public:
static inline int get_thread_ptr_offset() { return _thread_ptr_offset; }
};
static void write_memory_serialize_page_with_handler(JavaThread* thread) {
// Due to chained nature of SEH handlers we have to be sure
// that our handler is always last handler before an attempt to write
// into serialization page - it can fault if we access this page
// right in the middle of protect/unprotect sequence by remote
// membar logic.
// __try/__except are very lightweight operations (only several
// instructions not affecting control flow directly on x86)
// so we can use it here, on very time critical path
__try {
write_memory_serialize_page(thread);
} __except (win32::serialize_fault_filter((_EXCEPTION_POINTERS*)_exception_info()))
{}
}
/*
* Crash protection for the watcher thread. Wrap the callback
* with a __try { call() }

View file

@ -90,10 +90,32 @@ class InterfaceSupport: AllStatic {
# endif
public:
// OS dependent stuff
static void serialize_thread_state_with_handler(JavaThread* thread) {
serialize_thread_state_internal(thread, true);
}
#include OS_HEADER(interfaceSupport)
// Should only call this if we know that we have a proper SEH set up.
static void serialize_thread_state(JavaThread* thread) {
serialize_thread_state_internal(thread, false);
}
private:
static void serialize_thread_state_internal(JavaThread* thread, bool needs_exception_handler) {
// Make sure new state is seen by VM thread
if (os::is_MP()) {
if (UseMembar) {
// Force a fence between the write above and read below
OrderAccess::fence();
} else {
// store to serialize page so VM thread can do pseudo remote membar
if (needs_exception_handler) {
os::write_memory_serialize_page_with_handler(thread);
} else {
os::write_memory_serialize_page(thread);
}
}
}
}
};
@ -118,16 +140,7 @@ class ThreadStateTransition : public StackObj {
// Change to transition state
thread->set_thread_state((JavaThreadState)(from + 1));
// Make sure new state is seen by VM thread
if (os::is_MP()) {
if (UseMembar) {
// Force a fence between the write above and read below
OrderAccess::fence();
} else {
// store to serialize page so VM thread can do pseudo remote membar
os::write_memory_serialize_page(thread);
}
}
InterfaceSupport::serialize_thread_state(thread);
if (SafepointSynchronize::do_call_back()) {
SafepointSynchronize::block(thread);
@ -149,16 +162,7 @@ class ThreadStateTransition : public StackObj {
// Change to transition state
thread->set_thread_state((JavaThreadState)(from + 1));
// Make sure new state is seen by VM thread
if (os::is_MP()) {
if (UseMembar) {
// Force a fence between the write above and read below
OrderAccess::fence();
} else {
// Must use this rather than serialization page in particular on Windows
InterfaceSupport::serialize_memory(thread);
}
}
InterfaceSupport::serialize_thread_state_with_handler(thread);
if (SafepointSynchronize::do_call_back()) {
SafepointSynchronize::block(thread);
@ -182,16 +186,7 @@ class ThreadStateTransition : public StackObj {
// Change to transition state
thread->set_thread_state(_thread_in_native_trans);
// Make sure new state is seen by GC thread
if (os::is_MP()) {
if (UseMembar) {
// Force a fence between the write above and read below
OrderAccess::fence();
} else {
// Must use this rather than serialization page in particular on Windows
InterfaceSupport::serialize_memory(thread);
}
}
InterfaceSupport::serialize_thread_state_with_handler(thread);
// We never install asynchronous exceptions when coming (back) in
// to the runtime from native code because the runtime is not set

View file

@ -2398,16 +2398,8 @@ void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread
thread->set_thread_state(_thread_blocked);
thread->java_suspend_self();
thread->set_thread_state(state);
// Make sure new state is seen by VM thread
if (os::is_MP()) {
if (UseMembar) {
// Force a fence between the write above and read below
OrderAccess::fence();
} else {
// Must use this rather than serialization page in particular on Windows
InterfaceSupport::serialize_memory(thread);
}
}
InterfaceSupport::serialize_thread_state_with_handler(thread);
}
if (SafepointSynchronize::do_call_back()) {