diff a/src/hotspot/share/runtime/javaThread.hpp b/src/hotspot/share/runtime/javaThread.hpp
--- a/src/hotspot/share/runtime/javaThread.hpp
+++ b/src/hotspot/share/runtime/javaThread.hpp
@@ -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
@@ -155,11 +156,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.
@@ -465,10 +482,30 @@
   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 _jvmti_unmount_event_pending;
+  address _preempt_alternate_return; // used when preempting a thread
+  address _preempt_alternate_return_sp;
+
+#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;
@@ -609,18 +646,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;   }
+  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 val) { _preemption_cancelled = val; }
+
+  bool jvmti_unmount_event_pending() { return _jvmti_unmount_event_pending; }
+  void set_jvmti_unmount_event_pending(bool val) { _jvmti_unmount_event_pending = val; }
+
+  void set_preempt_alternate_return(address val) { _preempt_alternate_return = val; }
+  void set_preempt_alternate_return_sp(address val) { _preempt_alternate_return_sp = val; }
  private:
   DEBUG_ONLY(void verify_frame_info();)
 
   // Support for thread handshake operations
   HandshakeState _handshake;
@@ -819,14 +867,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); }
@@ -1240,6 +1293,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
