8183198: Factor out thread state serialization into a proper helper function
authormgerdin
Mon, 26 Jun 2017 15:25:25 +0200
changeset 46604 d409276ee40c
parent 46603 ec4b3e8ef95b
child 46605 358794f12717
8183198: Factor out thread state serialization into a proper helper function Reviewed-by: tschatzl, eosterlund, coleenp
hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
hotspot/src/os/aix/vm/interfaceSupport_aix.hpp
hotspot/src/os/bsd/vm/interfaceSupport_bsd.hpp
hotspot/src/os/linux/vm/interfaceSupport_linux.hpp
hotspot/src/os/posix/vm/os_posix.hpp
hotspot/src/os/solaris/vm/interfaceSupport_solaris.hpp
hotspot/src/os/windows/vm/interfaceSupport_windows.hpp
hotspot/src/os/windows/vm/os_windows.hpp
hotspot/src/share/vm/runtime/interfaceSupport.hpp
hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Jun 29 19:09:04 2017 +0000
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Jun 26 15:25:25 2017 +0200
@@ -378,14 +378,7 @@
   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.
--- a/hotspot/src/os/aix/vm/interfaceSupport_aix.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/hotspot/src/os/bsd/vm/interfaceSupport_bsd.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/hotspot/src/os/posix/vm/os_posix.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ b/hotspot/src/os/posix/vm/os_posix.hpp	Mon Jun 26 15:25:25 2017 +0200
@@ -107,6 +107,11 @@
   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
--- a/hotspot/src/os/solaris/vm/interfaceSupport_solaris.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/hotspot/src/os/windows/vm/interfaceSupport_windows.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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
--- a/hotspot/src/os/windows/vm/os_windows.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.hpp	Mon Jun 26 15:25:25 2017 +0200
@@ -123,6 +123,21 @@
   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() }
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Thu Jun 29 19:09:04 2017 +0000
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Mon Jun 26 15:25:25 2017 +0200
@@ -90,10 +90,32 @@
 # endif
 
  public:
-  // OS dependent stuff
+  static void serialize_thread_state_with_handler(JavaThread* thread) {
+    serialize_thread_state_internal(thread, true);
+  }
+
+  // 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);
+  }
 
-#include OS_HEADER(interfaceSupport)
-
+ 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 @@
     // 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 @@
     // 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 @@
     // 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
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Jun 29 19:09:04 2017 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Mon Jun 26 15:25:25 2017 +0200
@@ -2398,16 +2398,8 @@
     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()) {