< prev index next >

src/hotspot/share/prims/jvmtiExport.cpp

Print this page
@@ -221,29 +221,46 @@
      _jt = (jthread)(to_jobject(thread->threadObj()));
    };
   jthread jni_thread() { return _jt; }
  };
  
- class JvmtiClassEventMark : public JvmtiThreadEventMark {
+ class JvmtiVirtualThreadEventMark : public JvmtiEventMark {
+ private:
+   jthread _jt;
+ 
+ public:
+   JvmtiVirtualThreadEventMark(JavaThread *thread) :
+     JvmtiEventMark(thread) {
+     JvmtiThreadState* state = thread->jvmti_thread_state();
+     if (state != NULL && state->is_virtual()) {
+       _jt = (jthread)(to_jobject(thread->vthread()));
+     } else {
+       _jt = (jthread)(to_jobject(thread->threadObj()));
+     }
+   };
+   jthread jni_thread() { return _jt; }
+ };
+ 
+ class JvmtiClassEventMark : public JvmtiVirtualThreadEventMark {
  private:
    jclass _jc;
  
  public:
    JvmtiClassEventMark(JavaThread *thread, Klass* klass) :
-     JvmtiThreadEventMark(thread) {
+     JvmtiVirtualThreadEventMark(thread) {
      _jc = to_jclass(klass);
    };
    jclass jni_class() { return _jc; }
  };
  
- class JvmtiMethodEventMark : public JvmtiThreadEventMark {
+ class JvmtiMethodEventMark : public JvmtiVirtualThreadEventMark {
  private:
    jmethodID _mid;
  
  public:
    JvmtiMethodEventMark(JavaThread *thread, const methodHandle& method) :
-     JvmtiThreadEventMark(thread),
+     JvmtiVirtualThreadEventMark(thread),
      _mid(to_jmethodID(method)) {};
    jmethodID jni_methodID() { return _mid; }
  };
  
  class JvmtiLocationEventMark : public JvmtiMethodEventMark {

@@ -786,10 +803,13 @@
    }
    // Looks like an oop at this point.
  
    if (!thread_oop->is_a(vmClasses::Thread_klass())) {
      // The oop is not a java.lang.Thread.
+     if (thread_oop_p != NULL) {
+       *thread_oop_p = NULL;
+     }
      return JVMTI_ERROR_INVALID_THREAD;
    }
    // Looks like a java.lang.Thread oop at this point.
  
    if (thread_oop_p != NULL) {

@@ -798,10 +818,13 @@
      *thread_oop_p = thread_oop;
    }
  
    JavaThread * java_thread = java_lang_Thread::thread(thread_oop);
    if (java_thread == NULL) {
+     if (java_lang_VirtualThread::is_instance(thread_oop)) {
+       return JVMTI_ERROR_INVALID_THREAD;
+     }
      // The java.lang.Thread does not contain a JavaThread * so it has
      // not yet run or it has died.
      return JVMTI_ERROR_THREAD_NOT_ALIVE;
    }
    // Looks like a live JavaThread at this point.

@@ -1123,16 +1146,16 @@
    const void *compile_info() { return _compile_info; }
  };
  
  
  
- class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
+ class JvmtiMonitorEventMark : public JvmtiVirtualThreadEventMark {
  private:
    jobject _jobj;
  public:
    JvmtiMonitorEventMark(JavaThread *thread, oop object)
-           : JvmtiThreadEventMark(thread){
+           : JvmtiVirtualThreadEventMark(thread){
       _jobj = to_jobject(object);
    }
    jobject jni_object() { return _jobj; }
  };
  

@@ -1185,10 +1208,14 @@
  
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("[%s] Trg Breakpoint triggered",
                        JvmtiTrace::safe_get_thread_name(thread)));
    JvmtiEnvThreadStateIterator it(state);
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
      ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);

@@ -1225,12 +1252,14 @@
  bool              JvmtiExport::_can_post_breakpoint                       = false;
  bool              JvmtiExport::_can_post_field_access                     = false;
  bool              JvmtiExport::_can_post_field_modification               = false;
  bool              JvmtiExport::_can_post_method_entry                     = false;
  bool              JvmtiExport::_can_post_method_exit                      = false;
+ bool              JvmtiExport::_can_post_frame_pop                        = false;
  bool              JvmtiExport::_can_pop_frame                             = false;
  bool              JvmtiExport::_can_force_early_return                    = false;
+ bool              JvmtiExport::_can_support_virtual_threads               = false;
  bool              JvmtiExport::_can_get_owned_monitor_info                = false;
  
  bool              JvmtiExport::_early_vmstart_recorded                    = false;
  
  bool              JvmtiExport::_should_post_single_step                   = false;

@@ -1255,14 +1284,47 @@
  bool              JvmtiExport::_should_post_object_free                   = false;
  bool              JvmtiExport::_should_post_resource_exhausted            = false;
  bool              JvmtiExport::_should_post_vm_object_alloc               = false;
  bool              JvmtiExport::_should_post_sampled_object_alloc          = false;
  bool              JvmtiExport::_should_post_on_exceptions                 = false;
+ bool              JvmtiExport::_should_post_vthread_start                 = false;
+ bool              JvmtiExport::_should_post_vthread_end                   = false;
+ bool              JvmtiExport::_should_post_vthread_mount                 = false;
+ bool              JvmtiExport::_should_post_vthread_unmount               = false;
  
  ////////////////////////////////////////////////////////////////////////////////////////////////
  
  
+ void JvmtiExport::check_suspend_at_safepoint(JavaThread *thread) {
+   oop vt = thread->mounted_vthread();
+ 
+   if (vt != NULL && java_lang_VirtualThread::is_instance(vt)) {
+     HandleMark hm(thread);
+     Handle vth = Handle(thread, vt);
+ 
+     ThreadBlockInVM tbivm(thread);
+     MonitorLocker ml(JvmtiVTMT_lock, Mutex::_no_safepoint_check_flag);
+ 
+ #ifdef DBG // TMP
+     JvmtiThreadState* state = thread->jvmti_thread_state();
+ 
+     if (state != NULL) {
+       printf("DBG: JvmtiExport::check_suspend_at_safepoint: state: %p virt: %d jt: %p vt-susp: %d ct-susp: %d\n",
+              (void*)state, state->is_virtual(), (void*)thread,
+              JvmtiVTSuspender::is_vthread_suspended(vt),
+              thread->is_thread_suspended()
+             );
+       fflush(0);
+     }
+ #endif
+     // block while vthread is externally suspended
+     while (JvmtiVTSuspender::is_vthread_suspended(vth())) {
+       ml.wait();
+     }
+   }
+ }
+ 
  //
  // JVMTI single step management
  //
  void JvmtiExport::at_single_stepping_point(JavaThread *thread, Method* method, address location) {
    assert(JvmtiExport::should_post_single_step(), "must be single stepping");

@@ -1317,10 +1379,13 @@
                        JvmtiTrace::safe_get_thread_name(thread)));
    JvmtiThreadState* state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
    JvmtiEnvThreadStateIterator it(state);
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
      if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {
        JvmtiEnv *env = ets->get_env();
        if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {

@@ -1350,10 +1415,13 @@
                        JvmtiTrace::safe_get_thread_name(thread)));
    JvmtiThreadState* state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
    JvmtiEnvThreadStateIterator it(state);
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
      if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {
        JvmtiEnv *env = ets->get_env();
        if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {

@@ -1439,11 +1507,11 @@
        }
        if (env->is_enabled(JVMTI_EVENT_THREAD_START)) {
          EVT_TRACE(JVMTI_EVENT_THREAD_START, ("[%s] Evt Thread Start event sent",
                       JvmtiTrace::safe_get_thread_name(thread) ));
  
-         JvmtiThreadEventMark jem(thread);
+         JvmtiVirtualThreadEventMark jem(thread);
          JvmtiJavaThreadEventTransition jet(thread);
          jvmtiEventThreadStart callback = env->callbacks()->ThreadStart;
          if (callback != NULL) {
            (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
          }

@@ -1477,21 +1545,194 @@
            continue;
          }
          EVT_TRACE(JVMTI_EVENT_THREAD_END, ("[%s] Evt Thread End event sent",
                       JvmtiTrace::safe_get_thread_name(thread) ));
  
-         JvmtiThreadEventMark jem(thread);
+         JvmtiVirtualThreadEventMark jem(thread);
          JvmtiJavaThreadEventTransition jet(thread);
          jvmtiEventThreadEnd callback = env->callbacks()->ThreadEnd;
          if (callback != NULL) {
            (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
          }
        }
      }
    }
  }
  
+ 
+ void JvmtiExport::post_vthread_start(jobject vthread) {
+   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
+     return;
+   }
+   EVT_TRIG_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_START, ("[%p] Trg Virtual Thread Start event triggered", vthread));
+ 
+   JavaThread *cur_thread = JavaThread::current();
+   JvmtiThreadState *state = cur_thread->jvmti_thread_state();
+   if (state == NULL) {
+     return;
+   }
+ 
+   if (state->is_enabled(JVMTI_EVENT_VIRTUAL_THREAD_START)) {
+     JvmtiEnvThreadStateIterator it(state);
+ 
+     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
+       JvmtiEnv *env = ets->get_env();
+       if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
+         continue;
+       }
+       if (ets->is_enabled(JVMTI_EVENT_VIRTUAL_THREAD_START)) {
+         EVT_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_START, ("[%p] Evt Virtual Thread Start event sent", vthread));
+ 
+         JvmtiVirtualThreadEventMark jem(cur_thread);
+         JvmtiJavaThreadEventTransition jet(cur_thread);
+         jvmtiEventVirtualThreadStart callback = env->callbacks()->VirtualThreadStart;
+         if (callback != NULL) {
+           (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
+         }
+       }
+     }
+   }
+ }
+ 
+ void JvmtiExport::post_vthread_end(jobject vthread) {
+   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
+     return;
+   }
+   EVT_TRIG_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_END, ("[%p] Trg Virtual Thread End event triggered", vthread));
+ 
+   JavaThread *cur_thread = JavaThread::current();
+   JvmtiThreadState *state = cur_thread->jvmti_thread_state();
+   if (state == NULL) {
+     return;
+   }
+ 
+   if (state->is_enabled(JVMTI_EVENT_VIRTUAL_THREAD_END)) {
+     JvmtiEnvThreadStateIterator it(state);
+ 
+     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
+       JvmtiEnv *env = ets->get_env();
+       if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
+         continue;
+       }
+       if (ets->is_enabled(JVMTI_EVENT_VIRTUAL_THREAD_END)) {
+         EVT_TRACE(JVMTI_EVENT_VIRTUAL_THREAD_END, ("[%p] Evt Virtual Thread End event sent", vthread));
+ 
+         JvmtiVirtualThreadEventMark jem(cur_thread);
+         JvmtiJavaThreadEventTransition jet(cur_thread);
+         jvmtiEventVirtualThreadEnd callback = env->callbacks()->VirtualThreadEnd;
+         if (callback != NULL) {
+           (*callback)(env->jvmti_external(), jem.jni_env(), vthread);
+         }
+       }
+     }
+   }
+ }
+ 
+ void JvmtiExport::post_vthread_mount(jobject vthread) {
+   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
+     return;
+   }
+   JavaThread *thread = JavaThread::current();
+   HandleMark hm(thread);
+   EVT_TRIG_TRACE(EXT_EVENT_VIRTUAL_THREAD_MOUNT, ("[%p] Trg Virtual Thread Mount event triggered", vthread));
+ 
+   JvmtiThreadState *state = thread->jvmti_thread_state();
+   if (state == NULL) {
+     return;
+   }
+ 
+   if (state->is_enabled((jvmtiEvent)EXT_EVENT_VIRTUAL_THREAD_MOUNT)) {
+     JvmtiEnvThreadStateIterator it(state);
+ 
+     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
+       JvmtiEnv *env = ets->get_env();
+       if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
+         continue;
+       }
+       if (ets->is_enabled((jvmtiEvent)EXT_EVENT_VIRTUAL_THREAD_MOUNT)) {
+         EVT_TRACE(EXT_EVENT_VIRTUAL_THREAD_MOUNT, ("[%p] Evt Virtual Thread Mount event sent", vthread));
+ 
+         JvmtiVirtualThreadEventMark jem(thread);
+         JvmtiJavaThreadEventTransition jet(thread);
+         jvmtiExtensionEvent callback = env->ext_callbacks()->VirtualThreadMount;
+         if (callback != NULL) {
+           (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
+         }
+       }
+     }
+   }
+ }
+ 
+ void JvmtiExport::post_vthread_unmount(jobject vthread) {
+   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
+     return;
+   }
+   JavaThread *thread = JavaThread::current();
+   HandleMark hm(thread);
+   EVT_TRIG_TRACE(EXT_EVENT_VIRTUAL_THREAD_UNMOUNT, ("[%p] Trg Virtual Thread Unmount event triggered", vthread));
+ 
+   JvmtiThreadState *state = thread->jvmti_thread_state();
+   if (state == NULL) {
+     return;
+   }
+ 
+   if (state->is_enabled((jvmtiEvent)EXT_EVENT_VIRTUAL_THREAD_UNMOUNT)) {
+     JvmtiEnvThreadStateIterator it(state);
+ 
+     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
+       JvmtiEnv *env = ets->get_env();
+       if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
+         continue;
+       }
+       if (ets->is_enabled((jvmtiEvent)EXT_EVENT_VIRTUAL_THREAD_UNMOUNT)) {
+         EVT_TRACE(EXT_EVENT_VIRTUAL_THREAD_UNMOUNT, ("[%p] Evt Virtual Thread Unmount event sent", vthread));
+ 
+         JvmtiVirtualThreadEventMark jem(thread);
+         JvmtiJavaThreadEventTransition jet(thread);
+         jvmtiExtensionEvent callback = env->ext_callbacks()->VirtualThreadUnmount;
+         if (callback != NULL) {
+           (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
+         }
+       }
+     }
+   }
+ }
+ 
+ void JvmtiExport::continuation_yield_cleanup(JavaThread* thread, jint continuation_frame_count) {
+   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
+     return;
+   }
+ 
+   assert (thread == JavaThread::current(), "must be");
+   JvmtiThreadState *state = thread->jvmti_thread_state();
+   if (state == NULL) {
+     return;
+   }
+   state->invalidate_cur_stack_depth();
+ 
+   // Clear frame_pop requests in frames popped by yield
+   if (can_post_frame_pop()) {
+     JvmtiEnvThreadStateIterator it(state);
+     int top_frame_num = state->cur_stack_depth() + continuation_frame_count;
+ 
+     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
+       if (!ets->has_frame_pops()) {
+         continue;
+       }
+       for (int frame_idx = 0; frame_idx < continuation_frame_count; frame_idx++) {
+         int frame_num = top_frame_num - frame_idx;
+ 
+         if (!state->is_virtual() && ets->is_frame_pop(frame_num)) {
+           // remove the frame's entry
+           MutexLocker mu(JvmtiThreadState_lock);
+           ets->clear_frame_pop(frame_num);
+         }
+       } 
+     }
+   }
+ }
+ 
  void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) {
    assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking");
  
    EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("[?] Trg Object Free triggered" ));
    EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("[?] Evt Object Free sent"));

@@ -1548,10 +1789,13 @@
    JvmtiThreadState* state = thread->jvmti_thread_state();
    if (state == NULL || !state->is_interp_only_mode()) {
      // for any thread that actually wants method entry, interp_only_mode is set
      return;
    }
+   if (mh->jvmti_mount_transition() || thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    state->incr_cur_stack_depth();
  
    if (state->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {
      JvmtiEnvThreadStateIterator it(state);

@@ -1582,10 +1826,13 @@
  
    if (state == NULL || !state->is_interp_only_mode()) {
      // for any thread that actually wants method exit, interp_only_mode is set
      return;
    }
+   if (mh->jvmti_mount_transition() || thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    // return a flag when a method terminates by throwing an exception
    // i.e. if an exception is thrown and it's not caught by the current method
    bool exception_exit = state->is_exception_detected() && !state->is_exception_caught();
    Handle result;

@@ -1685,10 +1932,11 @@
        }
      }
    }
  
    state->decr_cur_stack_depth();
+ 
  }
  
  
  // Todo: inline this for optimization
  void JvmtiExport::post_single_step(JavaThread *thread, Method* method, address location) {

@@ -1697,10 +1945,14 @@
  
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (mh->jvmti_mount_transition() || thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    JvmtiEnvThreadStateIterator it(state);
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
      ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP);
      if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
        EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("[%s] Evt Single Step sent %s.%s @ " INTX_FORMAT,

@@ -1730,10 +1982,13 @@
  
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("[%s] Trg Exception thrown triggered",
                        JvmtiTrace::safe_get_thread_name(thread)));
    if (!state->is_exception_detected()) {
      state->set_exception_detected();

@@ -1892,10 +2147,14 @@
    // We must be called with a Java context in order to provide reasonable
    // values for the klazz, method, and location fields. The callers of this
    // function don't make the call unless there is a Java context.
    assert(thread->has_last_Java_frame(), "must be called with a Java context");
  
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    ResourceMark rm;
    fieldDescriptor fd;
    // if get_field_descriptor finds fieldID to be invalid, then we just bail
    bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
    assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID");

@@ -1924,10 +2183,14 @@
  
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Trg Field Access event triggered",
                        JvmtiTrace::safe_get_thread_name(thread)));
    JvmtiEnvThreadStateIterator it(state);
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
      if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {

@@ -1970,10 +2233,14 @@
    // We must be called with a Java context in order to provide reasonable
    // values for the klazz, method, and location fields. The callers of this
    // function don't make the call unless there is a Java context.
    assert(thread->has_last_Java_frame(), "must be called with Java context");
  
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }                   
+ 
    ResourceMark rm;
    fieldDescriptor fd;
    // if get_field_descriptor finds fieldID to be invalid, then we just bail
    bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
    assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID");

@@ -1997,10 +2264,14 @@
  
  void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method,
    address location, Klass* field_klass, Handle object, jfieldID field,
    char sig_type, jvalue *value) {
  
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    if (sig_type == JVM_SIGNATURE_INT || sig_type == JVM_SIGNATURE_BOOLEAN ||
        sig_type == JVM_SIGNATURE_BYTE || sig_type == JVM_SIGNATURE_CHAR ||
        sig_type == JVM_SIGNATURE_SHORT) {
      // 'I' instructions are used for byte, char, short and int.
      // determine which it really is, and convert

@@ -2068,10 +2339,14 @@
  
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
                       ("[%s] Trg Field Modification event triggered",
                        JvmtiTrace::safe_get_thread_name(thread)));
  
    JvmtiEnvThreadStateIterator it(state);

@@ -2107,10 +2382,14 @@
    methodHandle mh(thread, method);
  
    EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Trg Native Method Bind event triggered",
                        JvmtiTrace::safe_get_thread_name(thread)));
  
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
+ 
    if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
      JvmtiEnvIterator it;
      for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
        if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
          EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Evt Native Method Bind event sent",

@@ -2413,10 +2692,13 @@
    oop object = obj_mntr->object();
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    HandleMark hm(thread);
    Handle h(thread, object);
  
    EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,

@@ -2444,10 +2726,13 @@
    oop object = obj_mntr->object();
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    HandleMark hm(thread);
    Handle h(thread, object);
  
    EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,

@@ -2475,10 +2760,13 @@
                                            jlong timeout) {
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    HandleMark hm(thread);
    Handle h(thread, object);
  
    EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT,

@@ -2507,10 +2795,13 @@
    oop object = obj_mntr->object();
    JvmtiThreadState *state = thread->jvmti_thread_state();
    if (state == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
  
    HandleMark hm(thread);
    Handle h(thread, object);
  
    EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED,

@@ -2539,10 +2830,13 @@
    EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("[%s] Trg vm object alloc triggered",
                        JvmtiTrace::safe_get_thread_name(thread)));
    if (object == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
    HandleMark hm(thread);
    Handle h(thread, object);
    JvmtiEnvIterator it;
    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
      if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {

@@ -2571,10 +2865,13 @@
                   ("[%s] Trg sampled object alloc triggered",
                    JvmtiTrace::safe_get_thread_name(thread)));
    if (object == NULL) {
      return;
    }
+   if (thread->is_in_VTMT()) {
+     return; // no events should be posted if thread is in a VTMT transition
+   }
    HandleMark hm(thread);
    Handle h(thread, object);
  
    JvmtiEnvThreadStateIterator it(state);
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
< prev index next >