products/Sources/formale Sprachen/JAVA/openjdk-20-36_src/src/hotspot/share/runtime image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei:   Sprache: C

/*
 * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2021, Azul Systems, Inc. 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.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */


#include "precompiled.hpp"
#include "cds/dynamicArchive.hpp"
#include "ci/ciEnv.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/javaThreadStatus.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/compileTask.hpp"
#include "compiler/compilerThread.hpp"
#include "gc/shared/oopStorage.hpp"
#include "gc/shared/oopStorageSet.hpp"
#include "gc/shared/tlab_globals.hpp"
#include "jfr/jfrEvents.hpp"
#include "jvm.h"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "logging/log.hpp"
#include "logging/logAsyncWriter.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/iterator.hpp"
#include "memory/universe.hpp"
#include "oops/access.inline.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
#include "oops/verifyOopClosure.hpp"
#include "prims/jvm_misc.hpp"
#include "prims/jvmtiDeferredUpdates.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/continuation.hpp"
#include "runtime/continuationEntry.inline.hpp"
#include "runtime/continuationHelper.inline.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/handshake.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/javaThread.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/osThread.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/safepointMechanism.inline.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/serviceThread.hpp"
#include "runtime/stackFrameStream.inline.hpp"
#include "runtime/stackWatermarkSet.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/threadSMR.inline.hpp"
#include "runtime/threadStatisticalInfo.hpp"
#include "runtime/threadWXSetters.inline.hpp"
#include "runtime/timer.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
#include "runtime/vframe_hp.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vmOperations.hpp"
#include "services/threadService.hpp"
#include "utilities/copy.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/spinYield.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciEnv.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif

// Set by os layer.
size_t      JavaThread::_stack_size_at_create = 0;

#ifdef DTRACE_ENABLED

// Only bother with this argument setup if dtrace is available

  #define HOTSPOT_THREAD_PROBE_start HOTSPOT_THREAD_START
  #define HOTSPOT_THREAD_PROBE_stop HOTSPOT_THREAD_STOP

  #define DTRACE_THREAD_PROBE(probe, javathread)                           \
    {                                                                      \
      ResourceMark rm(this);                                               \
      int len = 0;                                                         \
      const char* name = (javathread)->name();                             \
      len = strlen(name);                                                  \
      HOTSPOT_THREAD_PROBE_##probe(/* probe = start, stop */               \
        (char *) name, len,                                                \
        java_lang_Thread::thread_id((javathread)->threadObj()),            \
        (uintptr_t) (javathread)->osthread()->thread_id(),                 \
        java_lang_Thread::is_daemon((javathread)->threadObj()));           \
    }

#else //  ndef DTRACE_ENABLED

  #define DTRACE_THREAD_PROBE(probe, javathread)

#endif // ndef DTRACE_ENABLED

void JavaThread::smr_delete() {
  if (_on_thread_list) {
    ThreadsSMRSupport::smr_delete(this);
  } else {
    delete this;
  }
}

// Initialized by VMThread at vm_global_init
OopStorage* JavaThread::_thread_oop_storage = NULL;

OopStorage* JavaThread::thread_oop_storage() {
  assert(_thread_oop_storage != NULL, "not yet initialized");
  return _thread_oop_storage;
}

void JavaThread::set_threadOopHandles(oop p) {
  assert(_thread_oop_storage != NULL, "not yet initialized");
  _threadObj   = OopHandle(_thread_oop_storage, p);
  _vthread     = OopHandle(_thread_oop_storage, p);
  _jvmti_vthread = OopHandle(_thread_oop_storage, NULL);
  _scopedValueCache = OopHandle(_thread_oop_storage, NULL);
}

oop JavaThread::threadObj() const {
  // Ideally we would verify the current thread is oop_safe when this is called, but as we can
  // be called from a signal handler we would have to use Thread::current_or_null_safe(). That
  // has overhead and also interacts poorly with GetLastError on Windows due to the use of TLS.
  // Instead callers must verify oop safe access.
  return _threadObj.resolve();
}

oop JavaThread::vthread() const {
  return _vthread.resolve();
}

void JavaThread::set_vthread(oop p) {
  assert(_thread_oop_storage != NULL, "not yet initialized");
  _vthread.replace(p);
}

oop JavaThread::jvmti_vthread() const {
  return _jvmti_vthread.resolve();
}

void JavaThread::set_jvmti_vthread(oop p) {
  assert(_thread_oop_storage != NULL, "not yet initialized");
  _jvmti_vthread.replace(p);
}

oop JavaThread::scopedValueCache() const {
  return _scopedValueCache.resolve();
}

void JavaThread::set_scopedValueCache(oop p) {
  if (_scopedValueCache.ptr_raw() != NULL) { // i.e. if the OopHandle has been allocated
    _scopedValueCache.replace(p);
  } else {
    assert(p == NULL, "not yet initialized");
  }
}

void JavaThread::clear_scopedValueBindings() {
  set_scopedValueCache(NULL);
  oop vthread_oop = vthread();
  // vthread may be null here if we get a VM error during startup,
  // before the java.lang.Thread instance has been created.
  if (vthread_oop != NULL) {
    java_lang_Thread::clear_scopedValueBindings(vthread_oop);
  }
}

void JavaThread::allocate_threadObj(Handle thread_group, const char* thread_name,
                                    bool daemon, TRAPS) {
  assert(thread_group.not_null(), "thread group should be specified");
  assert(threadObj() == NULL, "should only create Java thread object once");

  InstanceKlass* ik = vmClasses::Thread_klass();
  assert(ik->is_initialized(), "must be");
  instanceHandle thread_oop = ik->allocate_instance_handle(CHECK);

  // We are called from jni_AttachCurrentThread/jni_AttachCurrentThreadAsDaemon.
  // We cannot use JavaCalls::construct_new_instance because the java.lang.Thread
  // constructor calls Thread.current(), which must be set here.
  java_lang_Thread::set_thread(thread_oop(), this);
  set_threadOopHandles(thread_oop());

  JavaValue result(T_VOID);
  if (thread_name != NULL) {
    Handle name = java_lang_String::create_from_str(thread_name, CHECK);
    // Thread gets assigned specified name and null target
    JavaCalls::call_special(&result,
                            thread_oop,
                            ik,
                            vmSymbols::object_initializer_name(),
                            vmSymbols::threadgroup_string_void_signature(),
                            thread_group,
                            name,
                            THREAD);
  } else {
    // Thread gets assigned name "Thread-nnn" and null target
    // (java.lang.Thread doesn't have a constructor taking only a ThreadGroup argument)
    JavaCalls::call_special(&result,
                            thread_oop,
                            ik,
                            vmSymbols::object_initializer_name(),
                            vmSymbols::threadgroup_runnable_void_signature(),
                            thread_group,
                            Handle(),
                            THREAD);
  }
  os::set_priority(this, NormPriority);

  if (daemon) {
    java_lang_Thread::set_daemon(thread_oop());
  }
}

// ======= JavaThread ========

#if INCLUDE_JVMCI

jlong* JavaThread::_jvmci_old_thread_counters;

bool jvmci_counters_include(JavaThread* thread) {
  return !JVMCICountersExcludeCompiler || !thread->is_Compiler_thread();
}

void JavaThread::collect_counters(jlong* array, int length) {
  assert(length == JVMCICounterSize, "wrong value");
  for (int i = 0; i < length; i++) {
    array[i] = _jvmci_old_thread_counters[i];
  }
  for (JavaThread* tp : ThreadsListHandle()) {
    if (jvmci_counters_include(tp)) {
      for (int i = 0; i < length; i++) {
        array[i] += tp->_jvmci_counters[i];
      }
    }
  }
}

// Attempt to enlarge the array for per thread counters.
jlong* resize_counters_array(jlong* old_counters, int current_size, int new_size) {
  jlong* new_counters = NEW_C_HEAP_ARRAY_RETURN_NULL(jlong, new_size, mtJVMCI);
  if (new_counters == NULL) {
    return NULL;
  }
  if (old_counters == NULL) {
    old_counters = new_counters;
    memset(old_counters, 0, sizeof(jlong) * new_size);
  } else {
    for (int i = 0; i < MIN2((int) current_size, new_size); i++) {
      new_counters[i] = old_counters[i];
    }
    if (new_size > current_size) {
      memset(new_counters + current_size, 0, sizeof(jlong) * (new_size - current_size));
    }
    FREE_C_HEAP_ARRAY(jlong, old_counters);
  }
  return new_counters;
}

// Attempt to enlarge the array for per thread counters.
bool JavaThread::resize_counters(int current_size, int new_size) {
  jlong* new_counters = resize_counters_array(_jvmci_counters, current_size, new_size);
  if (new_counters == NULL) {
    return false;
  } else {
    _jvmci_counters = new_counters;
    return true;
  }
}

class VM_JVMCIResizeCounters : public VM_Operation {
 private:
  int _new_size;
  bool _failed;

 public:
  VM_JVMCIResizeCounters(int new_size) : _new_size(new_size), _failed(false) { }
  VMOp_Type type()                  const        { return VMOp_JVMCIResizeCounters; }
  bool allow_nested_vm_operations() const        { return true; }
  void doit() {
    // Resize the old thread counters array
    jlong* new_counters = resize_counters_array(JavaThread::_jvmci_old_thread_counters, JVMCICounterSize, _new_size);
    if (new_counters == NULL) {
      _failed = true;
      return;
    } else {
      JavaThread::_jvmci_old_thread_counters = new_counters;
    }

    // Now resize each threads array
    for (JavaThread* tp : ThreadsListHandle()) {
      if (!tp->resize_counters(JVMCICounterSize, _new_size)) {
        _failed = true;
        break;
      }
    }
    if (!_failed) {
      JVMCICounterSize = _new_size;
    }
  }

  bool failed() { return _failed; }
};

bool JavaThread::resize_all_jvmci_counters(int new_size) {
  VM_JVMCIResizeCounters op(new_size);
  VMThread::execute(&op);
  return !op.failed();
}

#endif // INCLUDE_JVMCI

#ifdef ASSERT
// Checks safepoint allowed and clears unhandled oops at potential safepoints.
void JavaThread::check_possible_safepoint() {
  if (_no_safepoint_count > 0) {
    print_owned_locks();
    assert(false"Possible safepoint reached by thread that does not allow it");
  }
#ifdef CHECK_UNHANDLED_OOPS
  // Clear unhandled oops in JavaThreads so we get a crash right away.
  clear_unhandled_oops();
#endif // CHECK_UNHANDLED_OOPS

  // Macos/aarch64 should be in the right state for safepoint (e.g.
  // deoptimization needs WXWrite).  Crashes caused by the wrong state rarely
  // happens in practice, making such issues hard to find and reproduce.
#if defined(__APPLE__) && defined(AARCH64)
  if (AssertWXAtThreadSync) {
    assert_wx_state(WXWrite);
  }
#endif
}

void JavaThread::check_for_valid_safepoint_state() {
  // Check NoSafepointVerifier, which is implied by locks taken that can be
  // shared with the VM thread.  This makes sure that no locks with allow_vm_block
  // are held.
  check_possible_safepoint();

  if (thread_state() != _thread_in_vm) {
    fatal("LEAF method calling lock?");
  }

  if (GCALotAtAllSafepoints) {
    // We could enter a safepoint here and thus have a gc
    InterfaceSupport::check_gc_alot();
  }
}
#endif // ASSERT

// A JavaThread is a normal Java thread

JavaThread::JavaThread() :
  // Initialize fields

  _on_thread_list(false),
  DEBUG_ONLY(_java_call_counter(0) COMMA)
  _entry_point(nullptr),
  _deopt_mark(nullptr),
  _deopt_nmethod(nullptr),
  _vframe_array_head(nullptr),
  _vframe_array_last(nullptr),
  _jvmti_deferred_updates(nullptr),
  _callee_target(nullptr),
  _vm_result(nullptr),
  _vm_result_2(nullptr),

  _current_pending_monitor(NULL),
  _current_pending_monitor_is_from_java(true),
  _current_waiting_monitor(NULL),
  _active_handles(NULL),
  _free_handle_block(NULL),
  _Stalled(0),

  _monitor_chunks(nullptr),

  _suspend_flags(0),

  _thread_state(_thread_new),
  _saved_exception_pc(nullptr),
#ifdef ASSERT
  _no_safepoint_count(0),
  _visited_for_critical_count(false),
#endif

  _terminated(_not_terminated),
  _in_deopt_handler(0),
  _doing_unsafe_access(false),
  _do_not_unlock_if_synchronized(false),
#if INCLUDE_JVMTI
  _carrier_thread_suspended(false),
  _is_in_VTMS_transition(false),
  _is_in_tmp_VTMS_transition(false),
#ifdef ASSERT
  _is_VTMS_transition_disabler(false),
#endif
#endif
  _jni_attach_state(_not_attaching_via_jni),
#if INCLUDE_JVMCI
  _pending_deoptimization(-1),
  _pending_monitorenter(false),
  _pending_transfer_to_interpreter(false),
  _in_retryable_allocation(false),
  _pending_failed_speculation(0),
  _jvmci{nullptr},
  _libjvmci_runtime(nullptr),
  _jvmci_counters(nullptr),
  _jvmci_reserved0(0),
  _jvmci_reserved1(0),
  _jvmci_reserved_oop0(nullptr),
#endif // INCLUDE_JVMCI

  _exception_oop(oop()),
  _exception_pc(0),
  _exception_handler_pc(0),
  _is_method_handle_return(0),

  _jni_active_critical(0),
  _pending_jni_exception_check_fn(nullptr),
  _depth_first_number(0),

  // JVMTI PopFrame support
  _popframe_condition(popframe_inactive),
  _frames_to_pop_failed_realloc(0),

  _cont_entry(nullptr),
  _cont_fastpath(0),
  _cont_fastpath_thread_state(1),
  _held_monitor_count(0),
  _jni_monitor_count(0),

  _handshake(this),

  _popframe_preserved_args(nullptr),
  _popframe_preserved_args_size(0),

  _jvmti_thread_state(nullptr),
  _interp_only_mode(0),
  _should_post_on_exceptions_flag(JNI_FALSE),
  _thread_stat(new ThreadStatistics()),

  _parker(),

  _class_to_be_initialized(nullptr),

  _SleepEvent(ParkEvent::Allocate(this))
{
  set_jni_functions(jni_functions());

#if INCLUDE_JVMCI
  assert(_jvmci._implicit_exception_pc == nullptr, "must be");
  if (JVMCICounterSize > 0) {
    resize_counters(0, (int) JVMCICounterSize);
  }
#endif // INCLUDE_JVMCI

  // Setup safepoint state info for this thread
  ThreadSafepointState::create(this);

  SafepointMechanism::initialize_header(this);

  set_requires_cross_modify_fence(false);

  pd_initialize();
  assert(deferred_card_mark().is_empty(), "Default MemRegion ctor");
}

JavaThread::JavaThread(bool is_attaching_via_jni) : JavaThread() {
  if (is_attaching_via_jni) {
    _jni_attach_state = _attaching_via_jni;
  }
}


// interrupt support

void JavaThread::interrupt() {
  // All callers should have 'this' thread protected by a
  // ThreadsListHandle so that it cannot terminate and deallocate
  // itself.
  debug_only(check_for_dangling_thread_pointer(this);)

  // For Windows _interrupt_event
  WINDOWS_ONLY(osthread()->set_interrupted(true);)

  // For Thread.sleep
  _SleepEvent->unpark();

  // For JSR166 LockSupport.park
  parker()->unpark();

  // For ObjectMonitor and JvmtiRawMonitor
  _ParkEvent->unpark();
}


bool JavaThread::is_interrupted(bool clear_interrupted) {
  debug_only(check_for_dangling_thread_pointer(this);)

  if (_threadObj.peek() == NULL) {
    // If there is no j.l.Thread then it is impossible to have
    // been interrupted. We can find NULL during VM initialization
    // or when a JNI thread is still in the process of attaching.
    // In such cases this must be the current thread.
    assert(this == Thread::current(), "invariant");
    return false;
  }

  bool interrupted = java_lang_Thread::interrupted(threadObj());

  // NOTE that since there is no "lock" around the interrupt and
  // is_interrupted operations, there is the possibility that the
  // interrupted flag will be "false" but that the
  // low-level events will be in the signaled state. This is
  // intentional. The effect of this is that Object.wait() and
  // LockSupport.park() will appear to have a spurious wakeup, which
  // is allowed and not harmful, and the possibility is so rare that
  // it is not worth the added complexity to add yet another lock.
  // For the sleep event an explicit reset is performed on entry
  // to JavaThread::sleep, so there is no early return. It has also been
  // recommended not to put the interrupted flag into the "event"
  // structure because it hides the issue.
  // Also, because there is no lock, we must only clear the interrupt
  // state if we are going to report that we were interrupted; otherwise
  // an interrupt that happens just after we read the field would be lost.
  if (interrupted && clear_interrupted) {
    assert(this == Thread::current(), "only the current thread can clear");
    java_lang_Thread::set_interrupted(threadObj(), false);
    WINDOWS_ONLY(osthread()->set_interrupted(false);)
  }

  return interrupted;
}

void JavaThread::block_if_vm_exited() {
  if (_terminated == _vm_exited) {
    // _vm_exited is set at safepoint, and Threads_lock is never released
    // so we will block here forever.
    // Here we can be doing a jump from a safe state to an unsafe state without
    // proper transition, but it happens after the final safepoint has begun so
    // this jump won't cause any safepoint problems.
    set_thread_state(_thread_in_vm);
    Threads_lock->lock();
    ShouldNotReachHere();
  }
}

JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : JavaThread() {
  _jni_attach_state = _not_attaching_via_jni;
  set_entry_point(entry_point);
  // Create the native thread itself.
  // %note runtime_23
  os::ThreadType thr_type = os::java_thread;
  thr_type = entry_point == &CompilerThread::thread_entry ? os::compiler_thread :
                                                            os::java_thread;
  os::create_thread(this, thr_type, stack_sz);
  // The _osthread may be NULL here because we ran out of memory (too many threads active).
  // We need to throw and OutOfMemoryError - however we cannot do this here because the caller
  // may hold a lock and all locks must be unlocked before throwing the exception (throwing
  // the exception consists of creating the exception object & initializing it, initialization
  // will leave the VM via a JavaCall and then all locks must be unlocked).
  //
  // The thread is still suspended when we reach here. Thread must be explicit started
  // by creator! Furthermore, the thread must also explicitly be added to the Threads list
  // by calling Threads:add. The reason why this is not done here, is because the thread
  // object must be fully initialized (take a look at JVM_Start)
}

JavaThread::~JavaThread() {

  // Enqueue OopHandles for release by the service thread.
  add_oop_handles_for_release();

  // Return the sleep event to the free list
  ParkEvent::Release(_SleepEvent);
  _SleepEvent = NULL;

  // Free any remaining  previous UnrollBlock
  vframeArray* old_array = vframe_array_last();

  if (old_array != NULL) {
    Deoptimization::UnrollBlock* old_info = old_array->unroll_block();
    old_array->set_unroll_block(NULL);
    delete old_info;
    delete old_array;
  }

  JvmtiDeferredUpdates* updates = deferred_updates();
  if (updates != NULL) {
    // This can only happen if thread is destroyed before deoptimization occurs.
    assert(updates->count() > 0, "Updates holder not deleted");
    // free deferred updates.
    delete updates;
    set_deferred_updates(NULL);
  }

  // All Java related clean up happens in exit
  ThreadSafepointState::destroy(this);
  if (_thread_stat != NULL) delete _thread_stat;

#if INCLUDE_JVMCI
  if (JVMCICounterSize > 0) {
    FREE_C_HEAP_ARRAY(jlong, _jvmci_counters);
  }
#endif // INCLUDE_JVMCI
}


// First JavaThread specific code executed by a new Java thread.
void JavaThread::pre_run() {
  // empty - see comments in run()
}

// The main routine called by a new Java thread. This isn't overridden
// by subclasses, instead different subclasses define a different "entry_point"
// which defines the actual logic for that kind of thread.
void JavaThread::run() {
  // initialize thread-local alloc buffer related fields
  initialize_tlab();

  _stack_overflow_state.create_stack_guard_pages();

  cache_global_variables();

  // Thread is now sufficiently initialized to be handled by the safepoint code as being
  // in the VM. Change thread state from _thread_new to _thread_in_vm
  assert(this->thread_state() == _thread_new, "wrong thread state");
  set_thread_state(_thread_in_vm);

  // Before a thread is on the threads list it is always safe, so after leaving the
  // _thread_new we should emit a instruction barrier. The distance to modified code
  // from here is probably far enough, but this is consistent and safe.
  OrderAccess::cross_modify_fence();

  assert(JavaThread::current() == this"sanity check");
  assert(!Thread::current()->owns_locks(), "sanity check");

  DTRACE_THREAD_PROBE(start, this);

  // This operation might block. We call that after all safepoint checks for a new thread has
  // been completed.
  set_active_handles(JNIHandleBlock::allocate_block());

  if (JvmtiExport::should_post_thread_life()) {
    JvmtiExport::post_thread_start(this);

  }

  // We call another function to do the rest so we are sure that the stack addresses used
  // from there will be lower than the stack base just computed.
  thread_main_inner();
}

void JavaThread::thread_main_inner() {
  assert(JavaThread::current() == this"sanity check");
  assert(_threadObj.peek() != NULL, "just checking");

  // Execute thread entry point unless this thread has a pending exception.
  // Note: Due to JVMTI StopThread we can have pending exceptions already!
  if (!this->has_pending_exception()) {
    {
      ResourceMark rm(this);
      this->set_native_thread_name(this->name());
    }
    HandleMark hm(this);
    this->entry_point()(thisthis);
  }

  DTRACE_THREAD_PROBE(stop, this);

  // Cleanup is handled in post_run()
}

// Shared teardown for all JavaThreads
void JavaThread::post_run() {
  this->exit(false);
  this->unregister_thread_stack_with_NMT();
  // Defer deletion to here to ensure 'this' is still referenceable in call_run
  // for any shared tear-down.
  this->smr_delete();
}

static void ensure_join(JavaThread* thread) {
  // We do not need to grab the Threads_lock, since we are operating on ourself.
  Handle threadObj(thread, thread->threadObj());
  assert(threadObj.not_null(), "java thread object must exist");
  ObjectLocker lock(threadObj, thread);
  // Thread is exiting. So set thread_status field in  java.lang.Thread class to TERMINATED.
  java_lang_Thread::set_thread_status(threadObj(), JavaThreadStatus::TERMINATED);
  // Clear the native thread instance - this makes isAlive return false and allows the join()
  // to complete once we've done the notify_all below
  java_lang_Thread::set_thread(threadObj(), NULL);
  lock.notify_all(thread);
  // Ignore pending exception, since we are exiting anyway
  thread->clear_pending_exception();
}

static bool is_daemon(oop threadObj) {
  return (threadObj != NULL && java_lang_Thread::is_daemon(threadObj));
}

// For any new cleanup additions, please check to see if they need to be applied to
// cleanup_failed_attach_current_thread as well.
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
  assert(this == JavaThread::current(), "thread consistency check");
  assert(!is_exiting(), "should not be exiting or terminated already");

  elapsedTimer _timer_exit_phase1;
  elapsedTimer _timer_exit_phase2;
  elapsedTimer _timer_exit_phase3;
  elapsedTimer _timer_exit_phase4;

  if (log_is_enabled(Debug, os, thread, timer)) {
    _timer_exit_phase1.start();
  }

  HandleMark hm(this);
  Handle uncaught_exception(this, this->pending_exception());
  this->clear_pending_exception();
  Handle threadObj(this, this->threadObj());
  assert(threadObj.not_null(), "Java thread object should be created");

  if (!destroy_vm) {
    if (uncaught_exception.not_null()) {
      EXCEPTION_MARK;
      // Call method Thread.dispatchUncaughtException().
      Klass* thread_klass = vmClasses::Thread_klass();
      JavaValue result(T_VOID);
      JavaCalls::call_virtual(&result,
                              threadObj, thread_klass,
                              vmSymbols::dispatchUncaughtException_name(),
                              vmSymbols::throwable_void_signature(),
                              uncaught_exception,
                              THREAD);
      if (HAS_PENDING_EXCEPTION) {
        ResourceMark rm(this);
        jio_fprintf(defaultStream::error_stream(),
                    "\nException: %s thrown from the UncaughtExceptionHandler"
                    " in thread \"%s\"\n",
                    pending_exception()->klass()->external_name(),
                    name());
        CLEAR_PENDING_EXCEPTION;
      }
    }

    if (!is_Compiler_thread()) {
      // We have finished executing user-defined Java code and now have to do the
      // implementation specific clean-up by calling Thread.exit(). We prevent any
      // asynchronous exceptions from being delivered while in Thread.exit()
      // to ensure the clean-up is not corrupted.
      NoAsyncExceptionDeliveryMark _no_async(this);

      EXCEPTION_MARK;
      JavaValue result(T_VOID);
      Klass* thread_klass = vmClasses::Thread_klass();
      JavaCalls::call_virtual(&result,
                              threadObj, thread_klass,
                              vmSymbols::exit_method_name(),
                              vmSymbols::void_method_signature(),
                              THREAD);
      CLEAR_PENDING_EXCEPTION;
    }

    // notify JVMTI
    if (JvmtiExport::should_post_thread_life()) {
      JvmtiExport::post_thread_end(this);
    }
  } else {
    // before_exit() has already posted JVMTI THREAD_END events
  }

  // Cleanup any pending async exception now since we cannot access oops after
  // BarrierSet::barrier_set()->on_thread_detach() has been executed.
  if (has_async_exception_condition()) {
    handshake_state()->clean_async_exception_operation();
  }

  // The careful dance between thread suspension and exit is handled here.
  // Since we are in thread_in_vm state and suspension is done with handshakes,
  // we can just put in the exiting state and it will be correctly handled.
  // Also, no more async exceptions will be added to the queue after this point.
  set_terminated(_thread_exiting);
  ThreadService::current_thread_exiting(this, is_daemon(threadObj()));

  if (log_is_enabled(Debug, os, thread, timer)) {
    _timer_exit_phase1.stop();
    _timer_exit_phase2.start();
  }

  // Capture daemon status before the thread is marked as terminated.
  bool daemon = is_daemon(threadObj());

  // Notify waiters on thread object. This has to be done after exit() is called
  // on the thread (if the thread is the last thread in a daemon ThreadGroup the
  // group should have the destroyed bit set before waiters are notified).
  ensure_join(this);
  assert(!this->has_pending_exception(), "ensure_join should have cleared");

  if (log_is_enabled(Debug, os, thread, timer)) {
    _timer_exit_phase2.stop();
    _timer_exit_phase3.start();
  }
  // 6282335 JNI DetachCurrentThread spec states that all Java monitors
  // held by this thread must be released. The spec does not distinguish
  // between JNI-acquired and regular Java monitors. We can only see
  // regular Java monitors here if monitor enter-exit matching is broken.
  //
  // ensure_join() ignores IllegalThreadStateExceptions, and so does
  // ObjectSynchronizer::release_monitors_owned_by_thread().
  if (exit_type == jni_detach) {
    // Sanity check even though JNI DetachCurrentThread() would have
    // returned JNI_ERR if there was a Java frame. JavaThread exit
    // should be done executing Java code by the time we get here.
    assert(!this->has_last_Java_frame(),
           "should not have a Java frame when detaching or exiting");
    ObjectSynchronizer::release_monitors_owned_by_thread(this);
    assert(!this->has_pending_exception(), "release_monitors should have cleared");
  }

  // Since above code may not release JNI monitors and if someone forgot to do an
  // JNI monitorexit, held count should be equal jni count.
  // Consider scan all object monitor for this owner if JNI count > 0 (at least on detach).
  assert(this->held_monitor_count() == this->jni_monitor_count(),
         "held monitor count should be equal to jni: " INT64_FORMAT " != " INT64_FORMAT,
         (int64_t)this->held_monitor_count(), (int64_t)this->jni_monitor_count());
  if (CheckJNICalls && this->jni_monitor_count() > 0) {
    // We would like a fatal here, but due to we never checked this before there
    // is a lot of tests which breaks, even with an error log.
    log_debug(jni)("JavaThread %s (tid: " UINTX_FORMAT ") with Objects still locked by JNI MonitorEnter.",
      exit_type == JavaThread::normal_exit ? "exiting" : "detaching", os::current_thread_id());
  }

  // These things needs to be done while we are still a Java Thread. Make sure that thread
  // is in a consistent state, in case GC happens
  JFR_ONLY(Jfr::on_thread_exit(this);)

  if (active_handles() != NULL) {
    JNIHandleBlock* block = active_handles();
    set_active_handles(NULL);
    JNIHandleBlock::release_block(block);
  }

  if (free_handle_block() != NULL) {
    JNIHandleBlock* block = free_handle_block();
    set_free_handle_block(NULL);
    JNIHandleBlock::release_block(block);
  }

  // These have to be removed while this is still a valid thread.
  _stack_overflow_state.remove_stack_guard_pages();

  if (UseTLAB) {
    tlab().retire();
  }

  if (JvmtiEnv::environments_might_exist()) {
    JvmtiExport::cleanup_thread(this);
  }

  // We need to cache the thread name for logging purposes below as once
  // we have called on_thread_detach this thread must not access any oops.
  char* thread_name = NULL;
  if (log_is_enabled(Debug, os, thread, timer)) {
    ResourceMark rm(this);
    thread_name = os::strdup(name());
  }

  log_info(os, thread)("JavaThread %s (tid: " UINTX_FORMAT ").",
    exit_type == JavaThread::normal_exit ? "exiting" : "detaching",
    os::current_thread_id());

  if (log_is_enabled(Debug, os, thread, timer)) {
    _timer_exit_phase3.stop();
    _timer_exit_phase4.start();
  }

#if INCLUDE_JVMCI
  if (JVMCICounterSize > 0) {
    if (jvmci_counters_include(this)) {
      for (int i = 0; i < JVMCICounterSize; i++) {
        _jvmci_old_thread_counters[i] += _jvmci_counters[i];
      }
    }
  }
#endif // INCLUDE_JVMCI

  // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread.
  // We call BarrierSet::barrier_set()->on_thread_detach() here so no touching of oops after this point.
  Threads::remove(this, daemon);

  if (log_is_enabled(Debug, os, thread, timer)) {
    _timer_exit_phase4.stop();
    log_debug(os, thread, timer)("name='%s'"
                                 ", exit-phase1=" JLONG_FORMAT
                                 ", exit-phase2=" JLONG_FORMAT
                                 ", exit-phase3=" JLONG_FORMAT
                                 ", exit-phase4=" JLONG_FORMAT,
                                 thread_name,
                                 _timer_exit_phase1.milliseconds(),
                                 _timer_exit_phase2.milliseconds(),
                                 _timer_exit_phase3.milliseconds(),
                                 _timer_exit_phase4.milliseconds());
    os::free(thread_name);
  }
}

void JavaThread::cleanup_failed_attach_current_thread(bool is_daemon) {
  if (active_handles() != NULL) {
    JNIHandleBlock* block = active_handles();
    set_active_handles(NULL);
    JNIHandleBlock::release_block(block);
  }

  if (free_handle_block() != NULL) {
    JNIHandleBlock* block = free_handle_block();
    set_free_handle_block(NULL);
    JNIHandleBlock::release_block(block);
  }

  // These have to be removed while this is still a valid thread.
  _stack_overflow_state.remove_stack_guard_pages();

  if (UseTLAB) {
    tlab().retire();
  }

  Threads::remove(this, is_daemon);
  this->smr_delete();
}

JavaThread* JavaThread::active() {
  Thread* thread = Thread::current();
  if (thread->is_Java_thread()) {
    return JavaThread::cast(thread);
  } else {
    assert(thread->is_VM_thread(), "this must be a vm thread");
    VM_Operation* op = ((VMThread*) thread)->vm_operation();
    JavaThread *ret = op == NULL ? NULL : JavaThread::cast(op->calling_thread());
    return ret;
  }
}

bool JavaThread::is_lock_owned(address adr) const {
  if (Thread::is_lock_owned(adr)) return true;

  for (MonitorChunk* chunk = monitor_chunks(); chunk != NULL; chunk = chunk->next()) {
    if (chunk->contains(adr)) return true;
  }

  return false;
}

oop JavaThread::exception_oop() const {
  return Atomic::load(&_exception_oop);
}

void JavaThread::set_exception_oop(oop o) {
  Atomic::store(&_exception_oop, o);
}

void JavaThread::add_monitor_chunk(MonitorChunk* chunk) {
  chunk->set_next(monitor_chunks());
  set_monitor_chunks(chunk);
}

void JavaThread::remove_monitor_chunk(MonitorChunk* chunk) {
  guarantee(monitor_chunks() != NULL, "must be non empty");
  if (monitor_chunks() == chunk) {
    set_monitor_chunks(chunk->next());
  } else {
    MonitorChunk* prev = monitor_chunks();
    while (prev->next() != chunk) prev = prev->next();
    prev->set_next(chunk->next());
  }
}

void JavaThread::handle_special_runtime_exit_condition() {
  if (is_obj_deopt_suspend()) {
    frame_anchor()->make_walkable();
    wait_for_object_deoptimization();
  }
  JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(this);)
}


// Asynchronous exceptions support
//
void JavaThread::handle_async_exception(oop java_throwable) {
  assert(java_throwable != NULL, "should have an _async_exception to throw");
  assert(!is_at_poll_safepoint(), "should have never called this method");

  if (has_last_Java_frame()) {
    frame f = last_frame();
    if (f.is_runtime_frame()) {
      // If the topmost frame is a runtime stub, then we are calling into
      // OptoRuntime from compiled code. Some runtime stubs (new, monitor_exit..)
      // must deoptimize the caller before continuing, as the compiled exception
      // handler table may not be valid.
      RegisterMap reg_map(this,
                          RegisterMap::UpdateMap::skip,
                          RegisterMap::ProcessFrames::include,
                          RegisterMap::WalkContinuation::skip);
      frame compiled_frame = f.sender(®_map);
      if (!StressCompiledExceptionHandlers && compiled_frame.can_be_deoptimized()) {
        Deoptimization::deoptimize(this, compiled_frame);
      }
    }
  }

  // We cannot call Exceptions::_throw(...) here because we cannot block
  set_pending_exception(java_throwable, __FILE__, __LINE__);

  clear_scopedValueBindings();

  LogTarget(Info, exceptions) lt;
  if (lt.is_enabled()) {
    ResourceMark rm;
    LogStream ls(lt);
    ls.print("Async. exception installed at runtime exit (" INTPTR_FORMAT ")", p2i(this));
    if (has_last_Java_frame()) {
      frame f = last_frame();
      ls.print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", p2i(f.pc()), p2i(f.sp()));
    }
    ls.print_cr(" of type: %s", java_throwable->klass()->external_name());
  }
}

void JavaThread::install_async_exception(AsyncExceptionHandshake* aeh) {
  // Do not throw asynchronous exceptions against the compiler thread
  // or if the thread is already exiting.
  if (!can_call_java() || is_exiting()) {
    delete aeh;
    return;
  }

  oop exception = aeh->exception();
  Handshake::execute(aeh, this);  // Install asynchronous handshake

  ResourceMark rm;
  if (log_is_enabled(Info, exceptions)) {
    log_info(exceptions)("Pending Async. exception installed of type: %s",
                         InstanceKlass::cast(exception->klass())->external_name());
  }
  // for AbortVMOnException flag
  Exceptions::debug_check_abort(exception->klass()->external_name());

  // Interrupt thread so it will wake up from a potential wait()/sleep()/park()
  java_lang_Thread::set_interrupted(threadObj(), true);
  this->interrupt();
}

class InstallAsyncExceptionHandshake : public HandshakeClosure {
  AsyncExceptionHandshake* _aeh;
public:
  InstallAsyncExceptionHandshake(AsyncExceptionHandshake* aeh) :
    HandshakeClosure("InstallAsyncException"), _aeh(aeh) {}
  ~InstallAsyncExceptionHandshake() {
    // If InstallAsyncExceptionHandshake was never executed we need to clean up _aeh.
    delete _aeh;
  }
  void do_thread(Thread* thr) {
    JavaThread* target = JavaThread::cast(thr);
    target->install_async_exception(_aeh);
    _aeh = nullptr;
  }
};

void JavaThread::send_async_exception(JavaThread* target, oop java_throwable) {
  OopHandle e(Universe::vm_global(), java_throwable);
  InstallAsyncExceptionHandshake iaeh(new AsyncExceptionHandshake(e));
  Handshake::execute(&iaeh, target);
}

#if INCLUDE_JVMTI
void JavaThread::set_is_in_VTMS_transition(bool val) {
  _is_in_VTMS_transition = val;
}

#ifdef ASSERT
void JavaThread::set_is_VTMS_transition_disabler(bool val) {
  _is_VTMS_transition_disabler = val;
}
#endif
#endif

// External suspension mechanism.
//
// Guarantees on return (for a valid target thread):
//   - Target thread will not execute any new bytecode.
//   - Target thread will not enter any new monitors.
//
bool JavaThread::java_suspend() {
#if INCLUDE_JVMTI
  // Suspending a JavaThread in VTMS transition or disabling VTMS transitions can cause deadlocks.
  assert(!is_in_VTMS_transition(), "no suspend allowed in VTMS transition");
  assert(!is_VTMS_transition_disabler(), "no suspend allowed for VTMS transition disablers");
#endif

  guarantee(Thread::is_JavaThread_protected(/* target */ this),
            "target JavaThread is not protected in calling context.");
  return this->handshake_state()->suspend();
}

bool JavaThread::java_resume() {
  guarantee(Thread::is_JavaThread_protected_by_TLH(/* target */ this),
            "missing ThreadsListHandle in calling context.");
  return this->handshake_state()->resume();
}

// Wait for another thread to perform object reallocation and relocking on behalf of
// this thread. The current thread is required to change to _thread_blocked in order
// to be seen to be safepoint/handshake safe whilst suspended and only after becoming
// handshake safe, the other thread can complete the handshake used to synchronize
// with this thread and then perform the reallocation and relocking.
// See EscapeBarrier::sync_and_suspend_*()

void JavaThread::wait_for_object_deoptimization() {
  assert(!has_last_Java_frame() || frame_anchor()->walkable(), "should have walkable stack");
  assert(this == Thread::current(), "invariant");

  bool spin_wait = os::is_MP();
  do {
    ThreadBlockInVM tbivm(thistrue /* allow_suspend */);
    // Wait for object deoptimization if requested.
    if (spin_wait) {
      // A single deoptimization is typically very short. Microbenchmarks
      // showed 5% better performance when spinning.
      const uint spin_limit = 10 * SpinYield::default_spin_limit;
      SpinYield spin(spin_limit);
      for (uint i = 0; is_obj_deopt_suspend() && i < spin_limit; i++) {
        spin.wait();
      }
      // Spin just once
      spin_wait = false;
    } else {
      MonitorLocker ml(this, EscapeBarrier_lock, Monitor::_no_safepoint_check_flag);
      if (is_obj_deopt_suspend()) {
        ml.wait();
      }
    }
    // A handshake for obj. deoptimization suspend could have been processed so
    // we must check after processing.
  } while (is_obj_deopt_suspend());
}

#ifdef ASSERT
// Verify the JavaThread has not yet been published in the Threads::list, and
// hence doesn't need protection from concurrent access at this stage.
void JavaThread::verify_not_published() {
  // Cannot create a ThreadsListHandle here and check !tlh.includes(this)
  // since an unpublished JavaThread doesn't participate in the
  // Thread-SMR protocol for keeping a ThreadsList alive.
  assert(!on_thread_list(), "JavaThread shouldn't have been published yet!");
}
#endif

// Slow path when the native==>Java barriers detect a safepoint/handshake is
// pending, when _suspend_flags is non-zero or when we need to process a stack
// watermark. Also check for pending async exceptions (except unsafe access error).
// Note only the native==>Java barriers can call this function when thread state
// is _thread_in_native_trans.
void JavaThread::check_special_condition_for_native_trans(JavaThread *thread) {
  assert(thread->thread_state() == _thread_in_native_trans, "wrong state");
  assert(!thread->has_last_Java_frame() || thread->frame_anchor()->walkable(), "Unwalkable stack in native->Java transition");

  thread->set_thread_state(_thread_in_vm);

  // Enable WXWrite: called directly from interpreter native wrapper.
  MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread));

  SafepointMechanism::process_if_requested_with_exit_check(thread, true /* check asyncs */);

  // After returning from native, it could be that the stack frames are not
  // yet safe to use. We catch such situations in the subsequent stack watermark
  // barrier, which will trap unsafe stack frames.
  StackWatermarkSet::before_unwind(thread);
}

#ifndef PRODUCT
// Deoptimization
// Function for testing deoptimization
void JavaThread::deoptimize() {
  StackFrameStream fst(thisfalse /* update */, true /* process_frames */);
  bool deopt = false;           // Dump stack only if a deopt actually happens.
  bool only_at = strlen(DeoptimizeOnlyAt) > 0;
  // Iterate over all frames in the thread and deoptimize
  for (; !fst.is_done(); fst.next()) {
    if (fst.current()->can_be_deoptimized()) {

      if (only_at) {
        // Deoptimize only at particular bcis.  DeoptimizeOnlyAt
        // consists of comma or carriage return separated numbers so
        // search for the current bci in that string.
        address pc = fst.current()->pc();
        nmethod* nm =  (nmethod*) fst.current()->cb();
        ScopeDesc* sd = nm->scope_desc_at(pc);
        char buffer[8];
        jio_snprintf(buffer, sizeof(buffer), "%d", sd->bci());
        size_t len = strlen(buffer);
        const char * found = strstr(DeoptimizeOnlyAt, buffer);
        while (found != NULL) {
          if ((found[len] == ',' || found[len] == '\n' || found[len] == '\0') &&
              (found == DeoptimizeOnlyAt || found[-1] == ',' || found[-1] == '\n')) {
            // Check that the bci found is bracketed by terminators.
            break;
          }
          found = strstr(found + 1, buffer);
        }
        if (!found) {
          continue;
        }
      }

      if (DebugDeoptimization && !deopt) {
        deopt = true// One-time only print before deopt
        tty->print_cr("[BEFORE Deoptimization]");
        trace_frames();
        trace_stack();
      }
      Deoptimization::deoptimize(this, *fst.current());
    }
  }

  if (DebugDeoptimization && deopt) {
    tty->print_cr("[AFTER Deoptimization]");
    trace_frames();
  }
}


// Make zombies
void JavaThread::make_zombies() {
  for (StackFrameStream fst(thistrue /* update */, true /* process_frames */); !fst.is_done(); fst.next()) {
    if (fst.current()->can_be_deoptimized()) {
      // it is a Java nmethod
      nmethod* nm = CodeCache::find_nmethod(fst.current()->pc());
      nm->make_not_entrant();
    }
  }
}
#endif // PRODUCT


void JavaThread::deoptimize_marked_methods() {
  if (!has_last_Java_frame()) return;
  StackFrameStream fst(thisfalse /* update */, true /* process_frames */);
  for (; !fst.is_done(); fst.next()) {
    if (fst.current()->should_be_deoptimized()) {
      Deoptimization::deoptimize(this, *fst.current());
    }
  }
}

#ifdef ASSERT
void JavaThread::verify_frame_info() {
  assert((!has_last_Java_frame() && java_call_counter() == 0) ||
         (has_last_Java_frame() && java_call_counter() > 0),
         "unexpected frame info: has_last_frame=%s, java_call_counter=%d",
         has_last_Java_frame() ? "true" : "false", java_call_counter());
}
#endif

// Push on a new block of JNI handles.
void JavaThread::push_jni_handle_block() {
  // Allocate a new block for JNI handles.
  // Inlined code from jni_PushLocalFrame()
  JNIHandleBlock* old_handles = active_handles();
  JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(this);
  assert(old_handles != NULL && new_handles != NULL, "should not be NULL");
  new_handles->set_pop_frame_link(old_handles);  // make sure java handles get gc'd.
  set_active_handles(new_handles);
}

// Pop off the current block of JNI handles.
void JavaThread::pop_jni_handle_block() {
  // Release our JNI handle block
  JNIHandleBlock* old_handles = active_handles();
  JNIHandleBlock* new_handles = old_handles->pop_frame_link();
  assert(new_handles != nullptr, "should never set active handles to null");
  set_active_handles(new_handles);
  old_handles->set_pop_frame_link(NULL);
  JNIHandleBlock::release_block(old_handles, this);
}

void JavaThread::oops_do_no_frames(OopClosure* f, CodeBlobClosure* cf) {
  // Verify that the deferred card marks have been flushed.
  assert(deferred_card_mark().is_empty(), "Should be empty during GC");

  // Traverse the GCHandles
  Thread::oops_do_no_frames(f, cf);

  if (active_handles() != NULL) {
    active_handles()->oops_do(f);
  }

  DEBUG_ONLY(verify_frame_info();)

  if (has_last_Java_frame()) {
    // Traverse the monitor chunks
    for (MonitorChunk* chunk = monitor_chunks(); chunk != NULL; chunk = chunk->next()) {
      chunk->oops_do(f);
    }
  }

  assert(vframe_array_head() == NULL, "deopt in progress at a safepoint!");
  // If we have deferred set_locals there might be oops waiting to be
  // written
  GrowableArray<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(this);
  if (list != NULL) {
    for (int i = 0; i < list->length(); i++) {
      list->at(i)->oops_do(f);
    }
  }

  // Traverse instance variables at the end since the GC may be moving things
  // around using this function
  f->do_oop((oop*) &_vm_result);
  f->do_oop((oop*) &_exception_oop);
#if INCLUDE_JVMCI
  f->do_oop((oop*) &_jvmci_reserved_oop0);
#endif

  if (jvmti_thread_state() != NULL) {
    jvmti_thread_state()->oops_do(f, cf);
  }

  // The continuation oops are really on the stack. But there is typically at most
  // one of those per thread, so we handle them here in the oops_do_no_frames part
  // so that we don't have to sprinkle as many stack watermark checks where these
  // oops are used. We just need to make sure the thread has started processing.
  ContinuationEntry* entry = _cont_entry;
  while (entry != nullptr) {
    f->do_oop((oop*)entry->cont_addr());
    f->do_oop((oop*)entry->chunk_addr());
    entry = entry->parent();
  }
}

void JavaThread::oops_do_frames(OopClosure* f, CodeBlobClosure* cf) {
  if (!has_last_Java_frame()) {
    return;
  }
  // Finish any pending lazy GC activity for the frames
  StackWatermarkSet::finish_processing(this, NULL /* context */, StackWatermarkKind::gc);
  // Traverse the execution stack
  for (StackFrameStream fst(thistrue /* update */, false /* process_frames */); !fst.is_done(); fst.next()) {
    fst.current()->oops_do(f, cf, fst.register_map());
  }
}

#ifdef ASSERT
void JavaThread::verify_states_for_handshake() {
  // This checks that the thread has a correct frame state during a handshake.
  verify_frame_info();
}
#endif

void JavaThread::nmethods_do(CodeBlobClosure* cf) {
  DEBUG_ONLY(verify_frame_info();)
  MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current());)

  if (has_last_Java_frame()) {
    // Traverse the execution stack
    for (StackFrameStream fst(thistrue /* update */, true /* process_frames */); !fst.is_done(); fst.next()) {
      fst.current()->nmethods_do(cf);
    }
  }

  if (jvmti_thread_state() != NULL) {
    jvmti_thread_state()->nmethods_do(cf);
  }
}

void JavaThread::metadata_do(MetadataClosure* f) {
  if (has_last_Java_frame()) {
    // Traverse the execution stack to call f() on the methods in the stack
    for (StackFrameStream fst(thistrue /* update */, true /* process_frames */); !fst.is_done(); fst.next()) {
      fst.current()->metadata_do(f);
    }
  } else if (is_Compiler_thread()) {
    // need to walk ciMetadata in current compile tasks to keep alive.
    CompilerThread* ct = (CompilerThread*)this;
    if (ct->env() != NULL) {
      ct->env()->metadata_do(f);
    }
    CompileTask* task = ct->task();
    if (task != NULL) {
      task->metadata_do(f);
    }
  }
}

// Printing
const char* _get_thread_state_name(JavaThreadState _thread_state) {
  switch (_thread_state) {
  case _thread_uninitialized:     return "_thread_uninitialized";
  case _thread_new:               return "_thread_new";
  case _thread_new_trans:         return "_thread_new_trans";
  case _thread_in_native:         return "_thread_in_native";
  case _thread_in_native_trans:   return "_thread_in_native_trans";
  case _thread_in_vm:             return "_thread_in_vm";
  case _thread_in_vm_trans:       return "_thread_in_vm_trans";
  case _thread_in_Java:           return "_thread_in_Java";
  case _thread_in_Java_trans:     return "_thread_in_Java_trans";
  case _thread_blocked:           return "_thread_blocked";
  case _thread_blocked_trans:     return "_thread_blocked_trans";
  default:                        return "unknown thread state";
  }
}

void JavaThread::print_thread_state_on(outputStream *st) const {
  st->print_cr(" JavaThread state: %s", _get_thread_state_name(_thread_state));
}

// Called by Threads::print() for VM_PrintThreads operation
void JavaThread::print_on(outputStream *st, bool print_extended_info) const {
  st->print_raw("\"");
  st->print_raw(name());
  st->print_raw("\" ");
  oop thread_oop = threadObj();
  if (thread_oop != NULL) {
    st->print("#" INT64_FORMAT " [%ld] ", (int64_t)java_lang_Thread::thread_id(thread_oop), (long) osthread()->thread_id());
    if (java_lang_Thread::is_daemon(thread_oop))  st->print("daemon ");
    st->print("prio=%d ", java_lang_Thread::priority(thread_oop));
  }
  Thread::print_on(st, print_extended_info);
  // print guess for valid stack memory region (assume 4K pages); helps lock debugging
  st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
  if (thread_oop != NULL) {
    if (is_vthread_mounted()) {
      oop vt = vthread();
      assert(vt != NULL, "");
      st->print_cr(" Carrying virtual thread #" INT64_FORMAT, (int64_t)java_lang_Thread::thread_id(vt));
    } else {
      st->print_cr(" java.lang.Thread.State: %s", java_lang_Thread::thread_status_name(thread_oop));
    }
  }
#ifndef PRODUCT
  _safepoint_state->print_on(st);
#endif // PRODUCT
  if (is_Compiler_thread()) {
    CompileTask *task = ((CompilerThread*)this)->task();
    if (task != NULL) {
      st->print(" Compiling: ");
      task->print(st, NULL, truefalse);
    } else {
      st->print(" No compile task");
    }
    st->cr();
  }
}

void JavaThread::print() const { print_on(tty); }

void JavaThread::print_name_on_error(outputStream* st, char *buf, int buflen) const {
  st->print("%s", get_thread_name_string(buf, buflen));
}

// Called by fatal error handler. The difference between this and
// JavaThread::print() is that we can't grab lock or allocate memory.
void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const {
  st->print("%s \"%s\"", type_name(), get_thread_name_string(buf, buflen));
  Thread* current = Thread::current_or_null_safe();
  assert(current != nullptr, "cannot be called by a detached thread");
  if (!current->is_Java_thread() || JavaThread::cast(current)->is_oop_safe()) {
    // Only access threadObj() if current thread is not a JavaThread
    // or if it is a JavaThread that can safely access oops.
    oop thread_obj = threadObj();
    if (thread_obj != nullptr) {
      if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon");
    }
  }
  st->print(" [");
  st->print("%s", _get_thread_state_name(_thread_state));
  if (osthread()) {
    st->print(", id=%d", osthread()->thread_id());
  }
  st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
            p2i(stack_end()), p2i(stack_base()));
  st->print("]");

  ThreadsSMRSupport::print_info_on(this, st);
  return;
}


// Verification

void JavaThread::frames_do(void f(frame*, const RegisterMap* map)) {
  // ignore if there is no stack
  if (!has_last_Java_frame()) return;
  // traverse the stack frames. Starts from top frame.
  for (StackFrameStream fst(thistrue /* update_map */, true /* process_frames */, false /* walk_cont */); !fst.is_done(); fst.next()) {
    frame* fr = fst.current();
    f(fr, fst.register_map());
  }
}

static void frame_verify(frame* f, const RegisterMap *map) { f->verify(map); }

void JavaThread::verify() {
  // Verify oops in the thread.
  oops_do(&VerifyOopClosure::verify_oop, NULL);

  // Verify the stack frames.
  frames_do(frame_verify);
}

// CR 6300358 (sub-CR 2137150)
// Most callers of this method assume that it can't return NULL but a
// thread may not have a name whilst it is in the process of attaching to
// the VM - see CR 6412693, and there are places where a JavaThread can be
// seen prior to having its threadObj set (e.g., JNI attaching threads and
// if vm exit occurs during initialization). These cases can all be accounted
// for such that this method never returns NULL.
const char* JavaThread::name() const  {
  if (Thread::is_JavaThread_protected(/* target */ this)) {
    // The target JavaThread is protected so get_thread_name_string() is safe:
    return get_thread_name_string();
  }

  // The target JavaThread is not protected so we return the default:
  return Thread::name();
}

// Returns a non-NULL representation of this thread's name, or a suitable
// descriptive string if there is no set name.
const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
  const char* name_str;
#ifdef ASSERT
  Thread* current = Thread::current_or_null_safe();
  assert(current != nullptr, "cannot be called by a detached thread");
  if (!current->is_Java_thread() || JavaThread::cast(current)->is_oop_safe()) {
    // Only access threadObj() if current thread is not a JavaThread
    // or if it is a JavaThread that can safely access oops.
#endif
    oop thread_obj = threadObj();
    if (thread_obj != NULL) {
      oop name = java_lang_Thread::name(thread_obj);
      if (name != NULL) {
        if (buf == NULL) {
          name_str = java_lang_String::as_utf8_string(name);
        } else {
          name_str = java_lang_String::as_utf8_string(name, buf, buflen);
        }
      } else if (is_attaching_via_jni()) { // workaround for 6412693 - see 6404306
        name_str = "";
      } else {
        name_str = "";
      }
    } else {
      name_str = Thread::name();
    }
#ifdef ASSERT
  } else {
    // Current JavaThread has exited...
    if (current == this) {
      // ... and is asking about itself:
      name_str = "";
    } else {
      // ... and it can't safely determine this JavaThread's name so
      // use the default thread name.
      name_str = Thread::name();
    }
  }
#endif
  assert(name_str != NULL, "unexpected NULL thread name");
  return name_str;
}

// Helper to extract the name from the thread oop for logging.
const char* JavaThread::name_for(oop thread_obj) {
  assert(thread_obj != NULL, "precondition");
  oop name = java_lang_Thread::name(thread_obj);
  const char* name_str;
  if (name != NULL) {
    name_str = java_lang_String::as_utf8_string(name);
  } else {
    name_str = "";
  }
  return name_str;
}

void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {

  assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
  assert(NoPriority <= prio && prio <= MaxPriority, "sanity check");
  // Link Java Thread object <-> C++ Thread

  // Get the C++ thread object (an oop) from the JNI handle (a jthread)
  // and put it into a new Handle.  The Handle "thread_oop" can then
  // be used to pass the C++ thread object to other methods.

  // Set the Java level thread object (jthread) field of the
  // new thread (a JavaThread *) to C++ thread object using the
  // "thread_oop" handle.

  // Set the thread field (a JavaThread *) of the
  // oop representing the java_lang_Thread to the new thread (a JavaThread *).

  Handle thread_oop(Thread::current(),
                    JNIHandles::resolve_non_null(jni_thread));
  assert(InstanceKlass::cast(thread_oop->klass())->is_linked(),
         "must be initialized");
  set_threadOopHandles(thread_oop());
  java_lang_Thread::set_thread(thread_oop(), this);

  if (prio == NoPriority) {
    prio = java_lang_Thread::priority(thread_oop());
    assert(prio != NoPriority, "A valid priority should be present");
  }

  // Push the Java priority down to the native thread; needs Threads_lock
  Thread::set_priority(this, prio);

  // Add the new thread to the Threads list and set it in motion.
  // We must have threads lock in order to call Threads::add.
  // It is crucial that we do not block before the thread is
  // added to the Threads list for if a GC happens, then the java_thread oop
  // will not be visited by GC.
  Threads::add(this);
}

oop JavaThread::current_park_blocker() {
  // Support for JSR-166 locks
  oop thread_oop = threadObj();
  if (thread_oop != NULL) {
    return java_lang_Thread::park_blocker(thread_oop);
  }
  return NULL;
}


void JavaThread::print_stack_on(outputStream* st) {
  if (!has_last_Java_frame()) return;

  Thread* current_thread = Thread::current();
  ResourceMark rm(current_thread);
  HandleMark hm(current_thread);

  RegisterMap reg_map(this,
                      RegisterMap::UpdateMap::include,
                      RegisterMap::ProcessFrames::include,
                      RegisterMap::WalkContinuation::skip);
  vframe* start_vf = platform_thread_last_java_vframe(®_map);
  int count = 0;
  for (vframe* f = start_vf; f != NULL; f = f->sender()) {
    if (f->is_java_frame()) {
      javaVFrame* jvf = javaVFrame::cast(f);
      java_lang_Throwable::print_stack_element(st, jvf->method(), jvf->bci());

      // Print out lock information
      if (JavaMonitorsInStackTrace) {
        jvf->print_lock_info_on(st, count);
      }
    } else {
      // Ignore non-Java frames
    }

    // Bail-out case for too deep stacks if MaxJavaStackTraceDepth > 0
    count++;
    if (MaxJavaStackTraceDepth > 0 && MaxJavaStackTraceDepth == count) return;
  }
}

#if INCLUDE_JVMTI
// Rebind JVMTI thread state from carrier to virtual or from virtual to carrier.
JvmtiThreadState* JavaThread::rebind_to_jvmti_thread_state_of(oop thread_oop) {
  set_jvmti_vthread(thread_oop);

  // unbind current JvmtiThreadState from JavaThread
  JvmtiThreadState::unbind_from(jvmti_thread_state(), this);

  // bind new JvmtiThreadState to JavaThread
  JvmtiThreadState::bind_to(java_lang_Thread::jvmti_thread_state(thread_oop), this);

  return jvmti_thread_state();
}
#endif

// JVMTI PopFrame support
void JavaThread::popframe_preserve_args(ByteSize size_in_bytes, void* start) {
  assert(_popframe_preserved_args == NULL, "should not wipe out old PopFrame preserved arguments");
  if (in_bytes(size_in_bytes) != 0) {
    _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes), mtThread);
    _popframe_preserved_args_size = in_bytes(size_in_bytes);
    Copy::conjoint_jbytes(start, _popframe_preserved_args, _popframe_preserved_args_size);
  }
}

void* JavaThread::popframe_preserved_args() {
  return _popframe_preserved_args;
}

ByteSize JavaThread::popframe_preserved_args_size() {
  return in_ByteSize(_popframe_preserved_args_size);
}

WordSize JavaThread::popframe_preserved_args_size_in_words() {
  int sz = in_bytes(popframe_preserved_args_size());
  assert(sz % wordSize == 0, "argument size must be multiple of wordSize");
  return in_WordSize(sz / wordSize);
}

void JavaThread::popframe_free_preserved_args() {
  assert(_popframe_preserved_args != NULL, "should not free PopFrame preserved arguments twice");
  FREE_C_HEAP_ARRAY(char, (char*)_popframe_preserved_args);
  _popframe_preserved_args = NULL;
  _popframe_preserved_args_size = 0;
}

#ifndef PRODUCT

void JavaThread::trace_frames() {
  tty->print_cr("[Describe stack]");
  int frame_no = 1;
  for (StackFrameStream fst(thistrue /* update */, true /* process_frames */); !fst.is_done(); fst.next()) {
    tty->print(" %d. ", frame_no++);
    fst.current()->print_value_on(tty, this);
    tty->cr();
  }
}

class PrintAndVerifyOopClosure: public OopClosure {
 protected:
  template <class T> inline void do_oop_work(T* p) {
    oop obj = RawAccess<>::oop_load(p);
    if (obj == NULL) return;
    tty->print(INTPTR_FORMAT ": ", p2i(p));
    if (oopDesc::is_oop_or_null(obj)) {
      if (obj->is_objArray()) {
        tty->print_cr("valid objArray: " INTPTR_FORMAT, p2i(obj));
      } else {
        obj->print();
      }
    } else {
      tty->print_cr("invalid oop: " INTPTR_FORMAT, p2i(obj));
    }
    tty->cr();
  }
 public:
  virtual void do_oop(oop* p) { do_oop_work(p); }
  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
};

#ifdef ASSERT
// Print or validate the layout of stack frames
void JavaThread::print_frame_layout(int depth, bool validate_only) {
  ResourceMark rm;
  PreserveExceptionMark pm(this);
  FrameValues values;
  int frame_no = 0;
  for (StackFrameStream fst(thistruetruetrue); !fst.is_done(); fst.next()) {
    fst.current()->describe(values, ++frame_no, fst.register_map());
    if (depth == frame_no) break;
  }
  Continuation::describe(values);
  if (validate_only) {
    values.validate();
  } else {
    tty->print_cr("[Describe stack layout]");
    values.print(this);
  }
}
#endif

void JavaThread::trace_stack_from(vframe* start_vf) {
  ResourceMark rm;
  int vframe_no = 1;
  for (vframe* f = start_vf; f; f = f->sender()) {
    if (f->is_java_frame()) {
      javaVFrame::cast(f)->print_activation(vframe_no++);
    } else {
      f->print();
    }
    if (vframe_no > StackPrintLimit) {
      tty->print_cr("......");
      return;
    }
  }
}


void JavaThread::trace_stack() {
  if (!has_last_Java_frame()) return;
  Thread* current_thread = Thread::current();
  ResourceMark rm(current_thread);
  HandleMark hm(current_thread);
  RegisterMap reg_map(this,
                      RegisterMap::UpdateMap::include,
                      RegisterMap::ProcessFrames::include,
                      RegisterMap::WalkContinuation::skip);
  trace_stack_from(last_java_vframe(®_map));
}


#endif // PRODUCT

void JavaThread::inc_held_monitor_count(int i, bool jni) {
#ifdef SUPPORT_MONITOR_COUNT
  assert(_held_monitor_count >= 0, "Must always be greater than 0: " INT64_FORMAT, (int64_t)_held_monitor_count);
  _held_monitor_count += i;
  if (jni) {
    assert(_jni_monitor_count >= 0, "Must always be greater than 0: " INT64_FORMAT, (int64_t)_jni_monitor_count);
    _jni_monitor_count += i;
  }
#endif
}

void JavaThread::dec_held_monitor_count(int i, bool jni) {
#ifdef SUPPORT_MONITOR_COUNT
  _held_monitor_count -= i;
  assert(_held_monitor_count >= 0, "Must always be greater than 0: " INT64_FORMAT, (int64_t)_held_monitor_count);
  if (jni) {
    _jni_monitor_count -= i;
    assert(_jni_monitor_count >= 0, "Must always be greater than 0: " INT64_FORMAT, (int64_t)_jni_monitor_count);
  }
#endif
}

frame JavaThread::vthread_last_frame() {
  assert (is_vthread_mounted(), "Virtual thread not mounted");
  return last_frame();
}

--> --------------------

--> maximum size reached

--> --------------------

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.64Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤





zum Wurzelverzeichnis wechseln
Diese Quellcodebibliothek enthält Beispiele in vielen Programmiersprachen. Man kann per Verzeichnistruktur darin navigieren. Der Code wird farblich markiert angezeigt.
zum Wurzelverzeichnis wechseln
Hier finden Sie eine Liste der Produkte des Unternehmens

Mittel




Laden

Fehler beim Verzeichnis:


in der Quellcodebibliothek suchen

Entwicklung einer Software für die statische Quellcodeanalyse


Bot Zugriff