< prev index next >

src/hotspot/share/runtime/interfaceSupport.hpp

Print this page
rev 47413 : Introduce SafepointMechanism
rev 47415 : Add Thread Local handshakes and thread local polling


  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
  26 #define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
  27 
  28 #include "gc/shared/gcLocker.hpp"
  29 #include "runtime/handles.inline.hpp"
  30 #include "runtime/mutexLocker.hpp"
  31 #include "runtime/orderAccess.hpp"
  32 #include "runtime/os.hpp"
  33 #include "runtime/safepoint.hpp"
  34 #include "runtime/thread.inline.hpp"
  35 #include "runtime/vmThread.hpp"
  36 #include "utilities/globalDefinitions.hpp"
  37 #include "utilities/macros.hpp"
  38 #include "utilities/preserveException.hpp"
  39 
  40 // Wrapper for all entry points to the virtual machine.
  41 // The HandleMarkCleaner is a faster version of HandleMark.
  42 // It relies on the fact that there is a HandleMark further
  43 // down the stack (in JavaCalls::call_helper), and just resets
  44 // to the saved values in that HandleMark.
  45 
  46 class HandleMarkCleaner: public StackObj {
  47  private:
  48   Thread* _thread;
  49  public:
  50   HandleMarkCleaner(Thread* thread) {
  51     _thread = thread;
  52     _thread->last_handle_mark()->push();
  53   }


 125  protected:
 126   JavaThread* _thread;
 127  public:
 128   ThreadStateTransition(JavaThread *thread) {
 129     _thread = thread;
 130     assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
 131   }
 132 
 133   // Change threadstate in a manner, so safepoint can detect changes.
 134   // Time-critical: called on exit from every runtime routine
 135   static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
 136     assert(from != _thread_in_Java, "use transition_from_java");
 137     assert(from != _thread_in_native, "use transition_from_native");
 138     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
 139     assert(thread->thread_state() == from, "coming from wrong thread state");
 140     // Change to transition state
 141     thread->set_thread_state((JavaThreadState)(from + 1));
 142 
 143     InterfaceSupport::serialize_thread_state(thread);
 144 
 145     if (SafepointSynchronize::do_call_back()) {
 146       SafepointSynchronize::block(thread);
 147     }
 148     thread->set_thread_state(to);
 149 
 150     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 151   }
 152 
 153   // transition_and_fence must be used on any thread state transition
 154   // where there might not be a Java call stub on the stack, in
 155   // particular on Windows where the Structured Exception Handler is
 156   // set up in the call stub. os::write_memory_serialize_page() can
 157   // fault and we can't recover from it on Windows without a SEH in
 158   // place.
 159   static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
 160     assert(thread->thread_state() == from, "coming from wrong thread state");
 161     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
 162     // Change to transition state
 163     thread->set_thread_state((JavaThreadState)(from + 1));
 164 
 165     InterfaceSupport::serialize_thread_state_with_handler(thread);
 166 
 167     if (SafepointSynchronize::do_call_back()) {
 168       SafepointSynchronize::block(thread);
 169     }
 170     thread->set_thread_state(to);
 171 
 172     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 173   }
 174 
 175   // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
 176   // never block on entry to the VM. This will break the code, since e.g. preserve arguments
 177   // have not been setup.
 178   static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
 179     assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
 180     thread->set_thread_state(to);
 181   }
 182 
 183   static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
 184     assert((to & 1) == 0, "odd numbers are transitions states");
 185     assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
 186     // Change to transition state
 187     thread->set_thread_state(_thread_in_native_trans);
 188 
 189     InterfaceSupport::serialize_thread_state_with_handler(thread);
 190 
 191     // We never install asynchronous exceptions when coming (back) in
 192     // to the runtime from native code because the runtime is not set
 193     // up to handle exceptions floating around at arbitrary points.
 194     if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {
 195       JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
 196 
 197       // Clear unhandled oops anywhere where we could block, even if we don't.
 198       CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 199     }
 200 
 201     thread->set_thread_state(to);
 202   }
 203  protected:
 204    void trans(JavaThreadState from, JavaThreadState to)  { transition(_thread, from, to); }
 205    void trans_from_java(JavaThreadState to)              { transition_from_java(_thread, to); }
 206    void trans_from_native(JavaThreadState to)            { transition_from_native(_thread, to); }
 207    void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
 208 };
 209 
































 210 
 211 class ThreadInVMfromJava : public ThreadStateTransition {
 212  public:
 213   ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
 214     trans_from_java(_thread_in_vm);
 215   }
 216   ~ThreadInVMfromJava()  {
 217     if (_thread->stack_yellow_reserved_zone_disabled()) {
 218       _thread->enable_stack_yellow_reserved_zone();
 219     }
 220     trans(_thread_in_vm, _thread_in_Java);
 221     // Check for pending. async. exceptions or suspends.
 222     if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
 223   }
 224 };
 225 
 226 
 227 class ThreadInVMfromUnknown {
 228  private:
 229   JavaThread* _thread;




  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
  26 #define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
  27 
  28 #include "gc/shared/gcLocker.hpp"
  29 #include "runtime/handles.inline.hpp"
  30 #include "runtime/mutexLocker.hpp"
  31 #include "runtime/orderAccess.hpp"
  32 #include "runtime/os.hpp"
  33 #include "runtime/safepointMechanism.inline.hpp"
  34 #include "runtime/thread.inline.hpp"
  35 #include "runtime/vmThread.hpp"
  36 #include "utilities/globalDefinitions.hpp"
  37 #include "utilities/macros.hpp"
  38 #include "utilities/preserveException.hpp"
  39 
  40 // Wrapper for all entry points to the virtual machine.
  41 // The HandleMarkCleaner is a faster version of HandleMark.
  42 // It relies on the fact that there is a HandleMark further
  43 // down the stack (in JavaCalls::call_helper), and just resets
  44 // to the saved values in that HandleMark.
  45 
  46 class HandleMarkCleaner: public StackObj {
  47  private:
  48   Thread* _thread;
  49  public:
  50   HandleMarkCleaner(Thread* thread) {
  51     _thread = thread;
  52     _thread->last_handle_mark()->push();
  53   }


 125  protected:
 126   JavaThread* _thread;
 127  public:
 128   ThreadStateTransition(JavaThread *thread) {
 129     _thread = thread;
 130     assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
 131   }
 132 
 133   // Change threadstate in a manner, so safepoint can detect changes.
 134   // Time-critical: called on exit from every runtime routine
 135   static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
 136     assert(from != _thread_in_Java, "use transition_from_java");
 137     assert(from != _thread_in_native, "use transition_from_native");
 138     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
 139     assert(thread->thread_state() == from, "coming from wrong thread state");
 140     // Change to transition state
 141     thread->set_thread_state((JavaThreadState)(from + 1));
 142 
 143     InterfaceSupport::serialize_thread_state(thread);
 144 
 145     SafepointMechanism::block_if_requested(thread);


 146     thread->set_thread_state(to);
 147 
 148     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 149   }
 150 
 151   // transition_and_fence must be used on any thread state transition
 152   // where there might not be a Java call stub on the stack, in
 153   // particular on Windows where the Structured Exception Handler is
 154   // set up in the call stub. os::write_memory_serialize_page() can
 155   // fault and we can't recover from it on Windows without a SEH in
 156   // place.
 157   static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
 158     assert(thread->thread_state() == from, "coming from wrong thread state");
 159     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
 160     // Change to transition state
 161     thread->set_thread_state((JavaThreadState)(from + 1));
 162 
 163     InterfaceSupport::serialize_thread_state_with_handler(thread);
 164 
 165     SafepointMechanism::block_if_requested(thread);


 166     thread->set_thread_state(to);
 167 
 168     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 169   }
 170 
 171   // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
 172   // never block on entry to the VM. This will break the code, since e.g. preserve arguments
 173   // have not been setup.
 174   static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
 175     assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
 176     thread->set_thread_state(to);
 177   }
 178 
 179   static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
 180     assert((to & 1) == 0, "odd numbers are transitions states");
 181     assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
 182     // Change to transition state
 183     thread->set_thread_state(_thread_in_native_trans);
 184 
 185     InterfaceSupport::serialize_thread_state_with_handler(thread);
 186 
 187     // We never install asynchronous exceptions when coming (back) in
 188     // to the runtime from native code because the runtime is not set
 189     // up to handle exceptions floating around at arbitrary points.
 190     if (SafepointMechanism::poll(thread) || thread->is_suspend_after_native()) {
 191       JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
 192 
 193       // Clear unhandled oops anywhere where we could block, even if we don't.
 194       CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 195     }
 196 
 197     thread->set_thread_state(to);
 198   }
 199  protected:
 200    void trans(JavaThreadState from, JavaThreadState to)  { transition(_thread, from, to); }
 201    void trans_from_java(JavaThreadState to)              { transition_from_java(_thread, to); }
 202    void trans_from_native(JavaThreadState to)            { transition_from_native(_thread, to); }
 203    void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
 204 };
 205 
 206 class ThreadInVMForHandshake : public ThreadStateTransition {
 207   const JavaThreadState _original_state;
 208 
 209   void transition_back() {
 210     // This can be invoked from transition states and must return to the original state properly
 211     assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
 212     _thread->set_thread_state(_thread_in_vm_trans);
 213 
 214     InterfaceSupport::serialize_thread_state(_thread);
 215 
 216     SafepointMechanism::block_if_requested(_thread);
 217 
 218     _thread->set_thread_state(_original_state);
 219   }
 220 
 221  public:
 222 
 223   ThreadInVMForHandshake(JavaThread* thread) : ThreadStateTransition(thread),
 224       _original_state(thread->thread_state()) {
 225 
 226     if (thread->has_last_Java_frame()) {
 227       thread->frame_anchor()->make_walkable(thread);
 228     }
 229 
 230     thread->set_thread_state(_thread_in_vm);
 231   }
 232 
 233   ~ThreadInVMForHandshake() {
 234     transition_back();
 235   }
 236 
 237 };
 238 
 239 class ThreadInVMfromJava : public ThreadStateTransition {
 240  public:
 241   ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
 242     trans_from_java(_thread_in_vm);
 243   }
 244   ~ThreadInVMfromJava()  {
 245     if (_thread->stack_yellow_reserved_zone_disabled()) {
 246       _thread->enable_stack_yellow_reserved_zone();
 247     }
 248     trans(_thread_in_vm, _thread_in_Java);
 249     // Check for pending. async. exceptions or suspends.
 250     if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
 251   }
 252 };
 253 
 254 
 255 class ThreadInVMfromUnknown {
 256  private:
 257   JavaThread* _thread;


< prev index next >