< prev index next >

src/hotspot/share/runtime/javaThread.hpp

Print this page
*** 39,10 ***
--- 39,11 ---
  #include "runtime/safepointMechanism.hpp"
  #include "runtime/stackWatermarkSet.hpp"
  #include "runtime/stackOverflow.hpp"
  #include "runtime/thread.hpp"
  #include "runtime/threadHeapSampler.hpp"
+ #include "runtime/threadIdentifier.hpp"
  #include "runtime/threadStatisticalInfo.hpp"
  #include "utilities/exceptions.hpp"
  #include "utilities/globalDefinitions.hpp"
  #include "utilities/macros.hpp"
  #if INCLUDE_JFR

*** 156,11 ***
--- 157,27 ---
    JNIHandleBlock* _active_handles;
  
    // One-element thread local free list
    JNIHandleBlock* _free_handle_block;
  
+   // ID used as owner for inflated monitors. Same as the tidĀ field of the current
+   // _vthread object, except during creation of the primordial and JNI attached
+   // thread cases where this field can have a temporal value.
+   int64_t _lock_id;
+ 
   public:
+   bool _on_monitorenter;
+ 
+   bool is_on_monitorenter() { return _on_monitorenter; }
+   void set_on_monitorenter(bool val) { _on_monitorenter = val; }
+ 
+   void set_lock_id(int64_t tid) {
+     assert(tid >= ThreadIdentifier::initial() && tid < ThreadIdentifier::current(), "invalid tid");
+     _lock_id = tid;
+   }
+   int64_t lock_id() const { return _lock_id; }
+ 
    // For tracking the heavyweight monitor the thread is pending on.
    ObjectMonitor* current_pending_monitor() {
      // Use Atomic::load() to prevent data race between concurrent modification and
      // concurrent readers, e.g. ThreadService::get_current_contended_monitor().
      // Especially, reloading pointer from thread after null check must be prevented.

*** 313,10 ***
--- 330,12 ---
    volatile bool         _carrier_thread_suspended;       // Carrier thread is externally suspended
    bool                  _is_in_VTMS_transition;          // thread is in virtual thread mount state transition
    bool                  _is_in_tmp_VTMS_transition;      // thread is in temporary virtual thread mount state transition
    bool                  _is_disable_suspend;             // JVMTI suspend is temporarily disabled; used on current thread only
    bool                  _VTMS_transition_mark;           // used for sync between VTMS transitions and disablers
+   bool                  _pending_jvmti_unmount_event;    // When preempting we post unmount event at unmount end rather than start
+   ObjectMonitor*        _contended_entered_monitor;      // Monitor por pending monitor_contended_entered callback
  #ifdef ASSERT
    bool                  _is_VTMS_transition_disabler;    // thread currently disabled VTMS transitions
  #endif
  #endif
  

*** 461,10 ***
--- 480,29 ---
    int _cont_fastpath_thread_state; // whether global thread state allows continuation fastpath (JVMTI)
  
    // It's signed for error detection.
    intx _held_monitor_count;  // used by continuations for fast lock detection
    intx _jni_monitor_count;
+   bool _preempting;
+   bool _preemption_cancelled;
+   bool _pending_interrupted_exception;
+   address _preempt_alternate_return; // used when preempting a thread
+ 
+ #ifdef ASSERT
+   intx _obj_locker_count;
+ 
+  public:
+   intx obj_locker_count() { return _obj_locker_count; }
+   void inc_obj_locker_count() {
+     assert(_obj_locker_count >= 0, "Must always be greater than 0: " INTX_FORMAT, _obj_locker_count);
+     _obj_locker_count++;
+   }
+   void dec_obj_locker_count() {
+     _obj_locker_count--;
+     assert(_obj_locker_count >= 0, "Must always be greater than 0: " INTX_FORMAT, _obj_locker_count);
+   }
+ #endif // ASSERT
  
  private:
  
    friend class VMThread;
    friend class ThreadWaitTransition;

*** 607,18 ***
    bool cont_fastpath() const                   { return _cont_fastpath == nullptr && _cont_fastpath_thread_state != 0; }
    bool cont_fastpath_thread_state() const      { return _cont_fastpath_thread_state != 0; }
  
    void inc_held_monitor_count(intx i = 1, bool jni = false);
    void dec_held_monitor_count(intx i = 1, bool jni = false);
- 
    intx held_monitor_count() { return _held_monitor_count; }
    intx jni_monitor_count()  { return _jni_monitor_count;  }
!   void clear_jni_monitor_count() { _jni_monitor_count = 0;   }
  
    inline bool is_vthread_mounted() const;
    inline const ContinuationEntry* vthread_continuation() const;
  
   private:
    DEBUG_ONLY(void verify_frame_info();)
  
    // Support for thread handshake operations
    HandshakeState _handshake;
--- 645,29 ---
    bool cont_fastpath() const                   { return _cont_fastpath == nullptr && _cont_fastpath_thread_state != 0; }
    bool cont_fastpath_thread_state() const      { return _cont_fastpath_thread_state != 0; }
  
    void inc_held_monitor_count(intx i = 1, bool jni = false);
    void dec_held_monitor_count(intx i = 1, bool jni = false);
    intx held_monitor_count() { return _held_monitor_count; }
+ 
    intx jni_monitor_count()  { return _jni_monitor_count;  }
!   void clear_jni_monitor_count() { _jni_monitor_count = 0; }
  
    inline bool is_vthread_mounted() const;
    inline const ContinuationEntry* vthread_continuation() const;
  
+   bool preempting()           { return _preempting; }
+   void set_preempting(bool b) { _preempting = b; }
+ 
+   bool preemption_cancelled()           { return _preemption_cancelled; }
+   void set_preemption_cancelled(bool b) { _preemption_cancelled = b; }
+ 
+   bool pending_interrupted_exception()           { return _pending_interrupted_exception; }
+   void set_pending_interrupted_exception(bool b) { _pending_interrupted_exception = b; }
+ 
+   void set_preempt_alternate_return(address val) { _preempt_alternate_return = val; }
+ 
   private:
    DEBUG_ONLY(void verify_frame_info();)
  
    // Support for thread handshake operations
    HandshakeState _handshake;

*** 663,16 ***
--- 712,23 ---
    void toggle_is_disable_suspend()               { _is_disable_suspend = !_is_disable_suspend; };
  
    bool VTMS_transition_mark() const              { return Atomic::load(&_VTMS_transition_mark); }
    void set_VTMS_transition_mark(bool val)        { Atomic::store(&_VTMS_transition_mark, val); }
  
+   bool pending_jvmti_unmount_event()             { return _pending_jvmti_unmount_event; }
+   void set_pending_jvmti_unmount_event(bool val) { _pending_jvmti_unmount_event = val; }
+ 
+   bool pending_contended_entered_event()         { return _contended_entered_monitor != nullptr; }
+   ObjectMonitor* contended_entered_monitor()     { return _contended_entered_monitor; }
  #ifdef ASSERT
    bool is_VTMS_transition_disabler() const       { return _is_VTMS_transition_disabler; }
    void set_is_VTMS_transition_disabler(bool val);
  #endif
  #endif
  
+   void set_contended_entered_monitor(ObjectMonitor* val) NOT_JVMTI_RETURN JVMTI_ONLY({ _contended_entered_monitor = val; })
+ 
    // Support for object deoptimization and JFR suspension
    void handle_special_runtime_exit_condition();
    bool has_special_runtime_exit_condition() {
      return (_suspend_flags & (_obj_deopt JFR_ONLY(| _trace_flag))) != 0;
    }

*** 821,14 ***
--- 877,19 ---
      return byte_offset_of(JavaThread, _should_post_on_exceptions_flag);
    }
    static ByteSize doing_unsafe_access_offset() { return byte_offset_of(JavaThread, _doing_unsafe_access); }
    NOT_PRODUCT(static ByteSize requires_cross_modify_fence_offset()  { return byte_offset_of(JavaThread, _requires_cross_modify_fence); })
  
+   static ByteSize lock_id_offset()            { return byte_offset_of(JavaThread, _lock_id); }
+ 
    static ByteSize cont_entry_offset()         { return byte_offset_of(JavaThread, _cont_entry); }
    static ByteSize cont_fastpath_offset()      { return byte_offset_of(JavaThread, _cont_fastpath); }
    static ByteSize held_monitor_count_offset() { return byte_offset_of(JavaThread, _held_monitor_count); }
    static ByteSize jni_monitor_count_offset()  { return byte_offset_of(JavaThread, _jni_monitor_count); }
+   static ByteSize preempting_offset()         { return byte_offset_of(JavaThread, _preempting); }
+   static ByteSize preemption_cancelled_offset()  { return byte_offset_of(JavaThread, _preemption_cancelled); }
+   static ByteSize preempt_alternate_return_offset() { return byte_offset_of(JavaThread, _preempt_alternate_return); }
  
  #if INCLUDE_JVMTI
    static ByteSize is_in_VTMS_transition_offset()     { return byte_offset_of(JavaThread, _is_in_VTMS_transition); }
    static ByteSize is_in_tmp_VTMS_transition_offset() { return byte_offset_of(JavaThread, _is_in_tmp_VTMS_transition); }
    static ByteSize is_disable_suspend_offset()        { return byte_offset_of(JavaThread, _is_disable_suspend); }

*** 1236,6 ***
--- 1297,15 ---
      thread->push_jni_handle_block();
    }
    ~JNIHandleMark() { _thread->pop_jni_handle_block(); }
  };
  
+ class ThreadOnMonitorEnter {
+   JavaThread* _thread;
+  public:
+   ThreadOnMonitorEnter(JavaThread* thread) : _thread(thread) {
+     _thread->set_on_monitorenter(true);
+   }
+   ~ThreadOnMonitorEnter() { _thread->set_on_monitorenter(false); }
+ };
+ 
  #endif // SHARE_RUNTIME_JAVATHREAD_HPP
< prev index next >