< prev index next >

src/share/vm/runtime/interfaceSupport.hpp

Print this page
rev 13142 : 8183198: Factor out thread state serialization into a proper helper function
Reviewed-by:


  73   static long _fullgc_alot_counter;
  74   static long _number_of_calls;
  75   static long _fullgc_alot_invocation;
  76 
  77   // Helper methods used to implement +ScavengeALot and +FullGCALot
  78   static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
  79   static void gc_alot();
  80 
  81   static void walk_stack_from(vframe* start_vf);
  82   static void walk_stack();
  83 
  84   static void zombieAll();
  85   static void unlinkSymbols();
  86   static void deoptimizeAll();
  87   static void stress_derived_pointers();
  88   static void verify_stack();
  89   static void verify_last_frame();
  90 # endif
  91 
  92  public:
  93   // OS dependent stuff


  94 
  95 #include OS_HEADER(interfaceSupport)



  96 

















  97 };
  98 
  99 
 100 // Basic class for all thread transition classes.
 101 
 102 class ThreadStateTransition : public StackObj {
 103  protected:
 104   JavaThread* _thread;
 105  public:
 106   ThreadStateTransition(JavaThread *thread) {
 107     _thread = thread;
 108     assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
 109   }
 110 
 111   // Change threadstate in a manner, so safepoint can detect changes.
 112   // Time-critical: called on exit from every runtime routine
 113   static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
 114     assert(from != _thread_in_Java, "use transition_from_java");
 115     assert(from != _thread_in_native, "use transition_from_native");
 116     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
 117     assert(thread->thread_state() == from, "coming from wrong thread state");
 118     // Change to transition state
 119     thread->set_thread_state((JavaThreadState)(from + 1));
 120 
 121     // Make sure new state is seen by VM thread
 122     if (os::is_MP()) {
 123       if (UseMembar) {
 124         // Force a fence between the write above and read below
 125         OrderAccess::fence();
 126       } else {
 127         // store to serialize page so VM thread can do pseudo remote membar
 128         os::write_memory_serialize_page(thread);
 129       }
 130     }
 131 
 132     if (SafepointSynchronize::do_call_back()) {
 133       SafepointSynchronize::block(thread);
 134     }
 135     thread->set_thread_state(to);
 136 
 137     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 138   }
 139 
 140   // transition_and_fence must be used on any thread state transition
 141   // where there might not be a Java call stub on the stack, in
 142   // particular on Windows where the Structured Exception Handler is
 143   // set up in the call stub. os::write_memory_serialize_page() can
 144   // fault and we can't recover from it on Windows without a SEH in
 145   // place.
 146   static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
 147     assert(thread->thread_state() == from, "coming from wrong thread state");
 148     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
 149     // Change to transition state
 150     thread->set_thread_state((JavaThreadState)(from + 1));
 151 
 152     // Make sure new state is seen by VM thread
 153     if (os::is_MP()) {
 154       if (UseMembar) {
 155         // Force a fence between the write above and read below
 156         OrderAccess::fence();
 157       } else {
 158         // Must use this rather than serialization page in particular on Windows
 159         InterfaceSupport::serialize_memory(thread);
 160       }
 161     }
 162 
 163     if (SafepointSynchronize::do_call_back()) {
 164       SafepointSynchronize::block(thread);
 165     }
 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     // Make sure new state is seen by GC thread
 186     if (os::is_MP()) {
 187       if (UseMembar) {
 188         // Force a fence between the write above and read below
 189         OrderAccess::fence();
 190       } else {
 191         // Must use this rather than serialization page in particular on Windows
 192         InterfaceSupport::serialize_memory(thread);
 193       }
 194     }
 195 
 196     // We never install asynchronous exceptions when coming (back) in
 197     // to the runtime from native code because the runtime is not set
 198     // up to handle exceptions floating around at arbitrary points.
 199     if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {
 200       JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
 201 
 202       // Clear unhandled oops anywhere where we could block, even if we don't.
 203       CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 204     }
 205 
 206     thread->set_thread_state(to);
 207   }
 208  protected:
 209    void trans(JavaThreadState from, JavaThreadState to)  { transition(_thread, from, to); }
 210    void trans_from_java(JavaThreadState to)              { transition_from_java(_thread, to); }
 211    void trans_from_native(JavaThreadState to)            { transition_from_native(_thread, to); }
 212    void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
 213 };
 214 




  73   static long _fullgc_alot_counter;
  74   static long _number_of_calls;
  75   static long _fullgc_alot_invocation;
  76 
  77   // Helper methods used to implement +ScavengeALot and +FullGCALot
  78   static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
  79   static void gc_alot();
  80 
  81   static void walk_stack_from(vframe* start_vf);
  82   static void walk_stack();
  83 
  84   static void zombieAll();
  85   static void unlinkSymbols();
  86   static void deoptimizeAll();
  87   static void stress_derived_pointers();
  88   static void verify_stack();
  89   static void verify_last_frame();
  90 # endif
  91 
  92  public:
  93   static void serialize_thread_state_with_handler(JavaThread* thread) {
  94     serialize_thread_state_internal(thread, true);
  95   }
  96 
  97   // Should only call this if we know that we have a proper SEH set up.
  98   static void serialize_thread_state(JavaThread* thread) {
  99     serialize_thread_state_internal(thread, false);
 100   }
 101 
 102  private:
 103   static void serialize_thread_state_internal(JavaThread* thread, bool needs_exception_handler) {
 104     // Make sure new state is seen by VM thread
 105     if (os::is_MP()) {
 106       if (UseMembar) {
 107         // Force a fence between the write above and read below
 108         OrderAccess::fence();
 109       } else {
 110         // store to serialize page so VM thread can do pseudo remote membar
 111         if (needs_exception_handler) {
 112           os::write_memory_serialize_page_with_handler(thread);
 113         } else {
 114           os::write_memory_serialize_page(thread);
 115         }
 116       }
 117     }
 118   }
 119 };
 120 
 121 
 122 // Basic class for all thread transition classes.
 123 
 124 class ThreadStateTransition : public StackObj {
 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 


< prev index next >