< prev index next >

src/hotspot/share/prims/jvmtiThreadState.inline.hpp

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

@@ -23,13 +23,16 @@
   */
  
  #ifndef SHARE_PRIMS_JVMTITHREADSTATE_INLINE_HPP
  #define SHARE_PRIMS_JVMTITHREADSTATE_INLINE_HPP
  
+ #include "classfile/javaClasses.hpp"
  #include "prims/jvmtiEnvThreadState.hpp"
  
  #include "prims/jvmtiThreadState.hpp"
+ #include "runtime/handles.inline.hpp"
+ #include "runtime/safepointVerifiers.hpp"
  #include "runtime/thread.inline.hpp"
  
  // JvmtiEnvThreadStateIterator implementation
  
  inline JvmtiEnvThreadStateIterator::JvmtiEnvThreadStateIterator(JvmtiThreadState* thread_state) {

@@ -67,35 +70,92 @@
  
  void JvmtiThreadState::set_head_env_thread_state(JvmtiEnvThreadState* ets) {
    _head_env_thread_state = ets;
  }
  
- inline JvmtiThreadState* JvmtiThreadState::state_for_while_locked(JavaThread *thread) {
+ inline JvmtiThreadState* JvmtiThreadState::state_for_while_locked(JavaThread *thread, oop thread_oop) {
    assert(JvmtiThreadState_lock->is_locked(), "sanity check");
+   assert(thread != NULL || thread_oop != NULL, "sanity check");
  
-   JvmtiThreadState *state = thread->jvmti_thread_state();
-   if (state == NULL) {
-     if (thread->is_exiting()) {
-       // don't add a JvmtiThreadState to a thread that is exiting
-       return NULL;
-     }
+   NoSafepointVerifier nsv;  // oop is safe to use.
+ 
+   if (thread_oop == NULL) { // then thread should not be NULL (see assert above)
+     thread_oop = thread->mounted_vthread() != NULL ? thread->mounted_vthread() : thread->threadObj();
+   }
+ 
+   // in a case of unmounted virtual thread the thread can be NULL
+   JvmtiThreadState *state = thread == NULL ? NULL : thread->jvmti_thread_state();
+   const char* action = "FOUND";
  
-     state = new JvmtiThreadState(thread);
+   if (state == NULL && thread != NULL && thread->is_exiting()) {
+     // don't add a JvmtiThreadState to a thread that is exiting
+     return NULL;
+   }
+   if (state == NULL || state->get_thread_oop() != thread_oop) {
+     // check if java_lang_Thread already has a link to the JvmtiThreadState
+     if (thread_oop != NULL) { // thread_oop can be NULL at early VMStart
+       state = java_lang_Thread::jvmti_thread_state(thread_oop);
+     }
+     if (state == NULL) { // need to create state
+       state = new JvmtiThreadState(thread, thread_oop);
+       if (thread_oop != NULL) { // thread_oop can be NULL at early VMStart
+         java_lang_Thread::set_jvmti_thread_state(thread_oop, state);
+       }
+       action = "CREATED";
+     }
    }
    return state;
  }
  
- inline JvmtiThreadState* JvmtiThreadState::state_for(JavaThread *thread) {
-   JvmtiThreadState *state = thread->jvmti_thread_state();
+ inline JvmtiThreadState* JvmtiThreadState::state_for(JavaThread *thread, Handle thread_handle) {
+   // in a case of unmounted virtual thread the thread can be NULL
+   JvmtiThreadState* state = thread_handle == NULL ? thread->jvmti_thread_state() :
+                                                 java_lang_Thread::jvmti_thread_state(thread_handle());
    if (state == NULL) {
      MutexLocker mu(JvmtiThreadState_lock);
      // check again with the lock held
-     state = state_for_while_locked(thread);
+     state = state_for_while_locked(thread, thread_handle());
    } else {
      // Check possible safepoint even if state is non-null.
      // (Note: the thread argument isn't the current thread)
      DEBUG_ONLY(JavaThread::current()->check_possible_safepoint());
    }
    return state;
  }
  
+ inline JavaThread* JvmtiThreadState::get_thread_or_saved() {
+   // Use _thread_saved if cthread is detached from JavaThread (_thread == NULL).
+   return (_thread == NULL && !is_virtual()) ? _thread_saved : _thread;
+ }
+ 
+ inline void JvmtiThreadState::set_should_post_on_exceptions(bool val) {
+   get_thread_or_saved()->set_should_post_on_exceptions_flag(val ? JNI_TRUE : JNI_FALSE);
+ }
+ 
+ inline void JvmtiThreadState::unbind_from(JavaThread* thread) {
+   if (this == NULL) {
+     return;
+   }
+   // save interp_only_mode
+   _saved_interp_only_mode = thread->get_interp_only_mode();
+   set_thread(NULL); // it is to make sure stale _thread value is never used
+ }
+ 
+ inline void JvmtiThreadState::bind_to(JavaThread* thread) {
+   // restore thread interp_only_mode
+   thread->set_interp_only_mode(this == NULL ? 0 : _saved_interp_only_mode);
+ 
+   // make continuation to notice the interp_only_mode change
+   Continuation::set_cont_fastpath_thread_state(thread);
+ 
+   // bind JavaThread to JvmtiThreadState
+   thread->set_jvmti_thread_state(this);
+ 
+   // TBD: This is hacky and may need a better solution.
+   JvmtiEventController::thread_started(thread);
+ 
+   if (this != NULL) {
+     // bind to JavaThread
+     set_thread(thread);
+   }
+ }
  #endif // SHARE_PRIMS_JVMTITHREADSTATE_INLINE_HPP
< prev index next >