237 } 238 }; 239 240 241 class ThreadBlockInVM : public ThreadStateTransition { 242 public: 243 ThreadBlockInVM(JavaThread *thread) 244 : ThreadStateTransition(thread) { 245 // Once we are blocked vm expects stack to be walkable 246 thread->frame_anchor()->make_walkable(thread); 247 trans(_thread_in_vm, _thread_blocked); 248 } 249 ~ThreadBlockInVM() { 250 trans(_thread_blocked, _thread_in_vm); 251 OrderAccess::cross_modify_fence(); 252 // We don't need to clear_walkable because it will happen automagically when we return to java 253 } 254 }; 255 256 // Unlike ThreadBlockInVM, this class is designed to avoid certain deadlock scenarios while making 257 // transitions inside class Monitor in cases where we need to block for a safepoint or handshake. It 258 // receives an extra argument compared to ThreadBlockInVM, the address of a pointer to the monitor we 259 // are trying to acquire. This will be used to access and release the monitor if needed to avoid 260 // said deadlocks. 261 // It works like ThreadBlockInVM but differs from it in two ways: 262 // - When transitioning in (constructor), it checks for safepoints without blocking, i.e., calls 263 // back if needed to allow a pending safepoint to continue but does not block in it. 264 // - When transitioning back (destructor), if there is a pending safepoint or handshake it releases 265 // the monitor that is only partially acquired. 266 class ThreadBlockInVMWithDeadlockCheck : public ThreadStateTransition { 267 private: 268 Monitor** _in_flight_monitor_adr; 269 270 void release_monitor() { 271 assert(_in_flight_monitor_adr != NULL, "_in_flight_monitor_adr should have been set on constructor"); 272 Monitor* in_flight_monitor = *_in_flight_monitor_adr; 273 if (in_flight_monitor != NULL) { 274 in_flight_monitor->release_for_safepoint(); 275 *_in_flight_monitor_adr = NULL; 276 } 277 } 278 public: 279 ThreadBlockInVMWithDeadlockCheck(JavaThread* thread, Monitor** in_flight_monitor_adr) 280 : ThreadStateTransition(thread), _in_flight_monitor_adr(in_flight_monitor_adr) { 281 // Once we are blocked vm expects stack to be walkable 282 thread->frame_anchor()->make_walkable(thread); 283 284 // All unsafe states are treated the same by the VMThread 285 // so we can skip the _thread_in_vm_trans state here. Since 286 // we don't read poll, it's enough to order the stores. 287 OrderAccess::storestore(); 288 289 thread->set_thread_state(_thread_blocked); 290 } 291 ~ThreadBlockInVMWithDeadlockCheck() { 292 // Change to transition state and ensure it is seen by the VM thread. 293 _thread->set_thread_state_fence((JavaThreadState)(_thread_blocked_trans)); 294 295 if (SafepointMechanism::should_block(_thread)) { 296 release_monitor(); 297 SafepointMechanism::block_if_requested(_thread); 298 } 299 300 _thread->set_thread_state(_thread_in_vm); | 237 } 238 }; 239 240 241 class ThreadBlockInVM : public ThreadStateTransition { 242 public: 243 ThreadBlockInVM(JavaThread *thread) 244 : ThreadStateTransition(thread) { 245 // Once we are blocked vm expects stack to be walkable 246 thread->frame_anchor()->make_walkable(thread); 247 trans(_thread_in_vm, _thread_blocked); 248 } 249 ~ThreadBlockInVM() { 250 trans(_thread_blocked, _thread_in_vm); 251 OrderAccess::cross_modify_fence(); 252 // We don't need to clear_walkable because it will happen automagically when we return to java 253 } 254 }; 255 256 // Unlike ThreadBlockInVM, this class is designed to avoid certain deadlock scenarios while making 257 // transitions inside class Mutex in cases where we need to block for a safepoint or handshake. It 258 // receives an extra argument compared to ThreadBlockInVM, the address of a pointer to the monitor we 259 // are trying to acquire. This will be used to access and release the mutex if needed to avoid 260 // said deadlocks. 261 // It works like ThreadBlockInVM but differs from it in two ways: 262 // - When transitioning in (constructor), it checks for safepoints without blocking, i.e., calls 263 // back if needed to allow a pending safepoint to continue but does not block in it. 264 // - When transitioning back (destructor), if there is a pending safepoint or handshake it releases 265 // the monitor that is only partially acquired. 266 class ThreadBlockInVMWithDeadlockCheck : public ThreadStateTransition { 267 private: 268 Mutex** _in_flight_mutex_addr; 269 270 void release_monitor() { 271 assert(_in_flight_mutex_addr != NULL, "_in_flight_mutex_addr should have been set on constructor"); 272 Mutex* in_flight_mutex = *_in_flight_mutex_addr; 273 if (in_flight_mutex != NULL) { 274 in_flight_mutex->release_for_safepoint(); 275 *_in_flight_mutex_addr = NULL; 276 } 277 } 278 public: 279 ThreadBlockInVMWithDeadlockCheck(JavaThread* thread, Mutex** in_flight_mutex_addr) 280 : ThreadStateTransition(thread), _in_flight_mutex_addr(in_flight_mutex_addr) { 281 // Once we are blocked vm expects stack to be walkable 282 thread->frame_anchor()->make_walkable(thread); 283 284 // All unsafe states are treated the same by the VMThread 285 // so we can skip the _thread_in_vm_trans state here. Since 286 // we don't read poll, it's enough to order the stores. 287 OrderAccess::storestore(); 288 289 thread->set_thread_state(_thread_blocked); 290 } 291 ~ThreadBlockInVMWithDeadlockCheck() { 292 // Change to transition state and ensure it is seen by the VM thread. 293 _thread->set_thread_state_fence((JavaThreadState)(_thread_blocked_trans)); 294 295 if (SafepointMechanism::should_block(_thread)) { 296 release_monitor(); 297 SafepointMechanism::block_if_requested(_thread); 298 } 299 300 _thread->set_thread_state(_thread_in_vm); |