/* * 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. *
*/
class AsyncExceptionHandshake; class ContinuationEntry; class DeoptResourceMark; class JNIHandleBlock; class JVMCIRuntime;
class JvmtiDeferredUpdates; class JvmtiSampledObjectAllocEventCollector; class JvmtiThreadState;
class Metadata; class OopHandleList; class OopStorage; class OSThread;
class ThreadsList; class ThreadSafepointState; class ThreadStatistics;
class vframeArray; class vframe; class javaVFrame;
class JavaThread; typedefvoid (*ThreadFunction)(JavaThread*, TRAPS);
class JavaThread: public Thread { friendclass VMStructs; friendclass JVMCIVMStructs; friendclass WhiteBox; friendclass ThreadsSMRSupport; // to access _threadObj for exiting_threads_oops_do friendclass HandshakeState; friendclass Continuation; friendclass Threads; friendclass ServiceThread; // for deferred OopHandle release access private: bool _on_thread_list; // Is set when this JavaThread is added to the Threads list
// All references to Java objects managed via OopHandles. These // have to be released by the ServiceThread after the JavaThread has // terminated - see add_oop_handles_for_release().
OopHandle _threadObj; // The Java level thread object
OopHandle _vthread; // the value returned by Thread.currentThread(): the virtual thread, if mounted, otherwise _threadObj
OopHandle _jvmti_vthread;
OopHandle _scopedValueCache;
JavaFrameAnchor _anchor; // Encapsulation of current java frame and it state
ThreadFunction _entry_point;
JNIEnv _jni_environment;
// Deopt support
DeoptResourceMark* _deopt_mark; // Holds special ResourceMark for deoptimization
CompiledMethod* _deopt_nmethod; // CompiledMethod that is currently being deoptimized
vframeArray* _vframe_array_head; // Holds the heap of the active vframeArrays
vframeArray* _vframe_array_last; // Holds last vFrameArray we popped // Holds updates by JVMTI agents for compiled frames that cannot be performed immediately. They // will be carried out as soon as possible which, in most cases, is just before deoptimization of // the frame, when control returns to it.
JvmtiDeferredUpdates* _jvmti_deferred_updates;
// Handshake value for fixing 6243940. We need a place for the i2c // adapter to store the callee Method*. This value is NEVER live // across a gc point so it does NOT have to be gc'd // The handshake is open ended since we can't be certain that it will // be NULLed. This is because we rarely ever see the race and end up // in handle_wrong_method which is the backend of the handshake. See // code in i2c adapters and handle_wrong_method.
Method* _callee_target;
// Used to pass back results to the interpreter or generated code running Java code.
oop _vm_result; // oop result is GC-preserved
Metadata* _vm_result_2; // non-oop result
// See ReduceInitialCardMarks: this holds the precise space interval of // the most recent slow path allocation for which compiled code has // elided card-marks for performance along the fast-path.
MemRegion _deferred_card_mark;
ObjectMonitor* volatile _current_pending_monitor; // ObjectMonitor this thread is waiting to lock bool _current_pending_monitor_is_from_java; // locking is from Java code
ObjectMonitor* volatile _current_waiting_monitor; // ObjectMonitor on which this thread called Object.wait()
// Active_handles points to a block of handles
JNIHandleBlock* _active_handles;
// One-element thread local free list
JNIHandleBlock* _free_handle_block;
public: volatile intptr_t _Stalled;
// For tracking the heavyweight monitor the thread is pending on.
ObjectMonitor* current_pending_monitor() { // Use Atomic::load() to prevent data race between concurrent modification and // concurrent readers, e.g. ThreadService::get_current_contended_monitor(). // Especially, reloading pointer from thread after NULL check must be prevented. return Atomic::load(&_current_pending_monitor);
} void set_current_pending_monitor(ObjectMonitor* monitor) {
Atomic::store(&_current_pending_monitor, monitor);
} void set_current_pending_monitor_is_from_java(bool from_java) {
_current_pending_monitor_is_from_java = from_java;
} bool current_pending_monitor_is_from_java() { return _current_pending_monitor_is_from_java;
}
ObjectMonitor* current_waiting_monitor() { // See the comment in current_pending_monitor() above. return Atomic::load(&_current_waiting_monitor);
} void set_current_waiting_monitor(ObjectMonitor* monitor) {
Atomic::store(&_current_waiting_monitor, monitor);
}
private:
MonitorChunk* _monitor_chunks; // Contains the off stack monitors // allocated during deoptimization // and by JNI_MonitorEnter/Exit
enum SuspendFlags { // NOTE: avoid using the sign-bit as cc generates different test code // when the sign-bit is used, and sometimes incorrectly - see CR 6398077
_trace_flag = 0x00000004U, // call tracing backend
_obj_deopt = 0x00000008U // suspend for object reallocation and relocking for JVMTI agent
};
// various suspension related flags - atomically updated volatile uint32_t _suspend_flags;
class NoAsyncExceptionDeliveryMark : public StackObj { friend JavaThread;
JavaThread *_target; inline NoAsyncExceptionDeliveryMark(JavaThread *t); inline ~NoAsyncExceptionDeliveryMark();
};
// Safepoint support public: // Expose _thread_state for SafeFetchInt() volatile JavaThreadState _thread_state; private:
SafepointMechanism::ThreadData _poll_data;
ThreadSafepointState* _safepoint_state; // Holds information about a thread during a safepoint
address _saved_exception_pc; // Saved pc of instruction where last implicit exception happened
NOT_PRODUCT(bool _requires_cross_modify_fence;) // State used by VerifyCrossModifyFence #ifdef ASSERT // Debug support for checking if code allows safepoints or not. // Safepoints in the VM can happen because of allocation, invoking a VM operation, or blocking on // mutex, or blocking on an object synchronizer (Java locking). // If _no_safepoint_count is non-zero, then an assertion failure will happen in any of // the above cases. The class NoSafepointVerifier is used to set this counter. int _no_safepoint_count; // If 0, thread allow a safepoint to happen
public: void inc_no_safepoint_count() { _no_safepoint_count++; } void dec_no_safepoint_count() { _no_safepoint_count--; } #endif// ASSERT public: // These functions check conditions before possibly going to a safepoint. // including NoSafepointVerifier. void check_for_valid_safepoint_state() NOT_DEBUG_RETURN; void check_possible_safepoint() NOT_DEBUG_RETURN;
// JavaThread termination support public: enum TerminatedTypes {
_not_terminated = 0xDEAD - 3,
_thread_exiting, // JavaThread::exit() has been called for this thread
_thread_gc_barrier_detached, // thread's GC barrier has been detached
_thread_terminated, // JavaThread is removed from thread list
_vm_exited // JavaThread is still executing native code, but VM is terminated // only VM_Exit can set _vm_exited
};
private: // In general a JavaThread's _terminated field transitions as follows: // // _not_terminated => _thread_exiting => _thread_gc_barrier_detached => _thread_terminated // // _vm_exited is a special value to cover the case of a JavaThread // executing native code after the VM itself is terminated. // // A JavaThread that fails to JNI attach has these _terminated field transitions: // _not_terminated => _thread_terminated // volatile TerminatedTypes _terminated;
jint _in_deopt_handler; // count of deoptimization // handlers thread is in volatilebool _doing_unsafe_access; // Thread may fault due to unsafe access bool _do_not_unlock_if_synchronized; // Do not unlock the receiver of a synchronized method (since it was // never locked) when throwing an exception. Used by interpreter only. #if INCLUDE_JVMTI volatilebool _carrier_thread_suspended; // Carrier thread is externally suspended bool _is_in_VTMS_transition; // thread is in virtual thread mount state transition bool _is_in_tmp_VTMS_transition; // thread is in temporary virtual thread mount state transition #ifdef ASSERT bool _is_VTMS_transition_disabler; // thread currently disabled VTMS transitions #endif #endif
// JNI attach states: enum JNIAttachStates {
_not_attaching_via_jni = 1, // thread is not attaching via JNI
_attaching_via_jni, // thread is attaching via JNI
_attached_via_jni // thread has attached via JNI
};
// A regular JavaThread's _jni_attach_state is _not_attaching_via_jni. // A native thread that is attaching via JNI starts with a value // of _attaching_via_jni and transitions to _attached_via_jni. volatile JNIAttachStates _jni_attach_state;
#if INCLUDE_JVMCI // The _pending_* fields below are used to communicate extra information // from an uncommon trap in JVMCI compiled code to the uncommon trap handler.
// Communicates the DeoptReason and DeoptAction of the uncommon trap int _pending_deoptimization;
// Specifies whether the uncommon trap is to bci 0 of a synchronized method // before the monitor has been acquired. bool _pending_monitorenter;
// Specifies if the DeoptReason for the last uncommon trap was Reason_transfer_to_interpreter bool _pending_transfer_to_interpreter;
// True if in a runtime call from compiled code that will deoptimize // and re-execute a failed heap allocation in the interpreter. bool _in_retryable_allocation;
// An id of a speculation that JVMCI compiled code can use to further describe and // uniquely identify the speculative optimization guarded by an uncommon trap. // See JVMCINMethodData::SPECULATION_LENGTH_BITS for further details.
jlong _pending_failed_speculation;
// These fields are mutually exclusive in terms of live ranges. union { // Communicates the pc at which the most recent implicit exception occurred // from the signal handler to a deoptimization stub.
address _implicit_exception_pc;
// Communicates an alternative call target to an i2c stub from a JavaCall .
address _alternate_call_target;
} _jvmci;
// The JVMCIRuntime in a JVMCI shared library
JVMCIRuntime* _libjvmci_runtime;
// Support for high precision, thread sensitive counters in JVMCI compiled code.
jlong* _jvmci_counters;
// Fast thread locals for use by JVMCI
jlong _jvmci_reserved0;
jlong _jvmci_reserved1;
oop _jvmci_reserved_oop0;
public: static jlong* _jvmci_old_thread_counters; staticvoid collect_counters(jlong* array, int length);
bool resize_counters(int current_size, int new_size);
// Compiler exception handling (NOTE: The _exception_oop is *NOT* the same as _pending_exception. It is // used to temp. parsing values into and out of the runtime system during exception handling for compiled // code) volatile oop _exception_oop; // Exception thrown in compiled code volatile address _exception_pc; // PC where exception happened volatile address _exception_handler_pc; // PC for handler of exception volatileint _is_method_handle_return; // true (== 1) if the current exception PC is a MethodHandle call site.
private: // support for JNI critical regions
jint _jni_active_critical; // count of entries into JNI critical region
// Checked JNI: function name requires exception check char* _pending_jni_exception_check_fn;
// For deadlock detection. int _depth_first_number;
// JVMTI PopFrame support // This is set to popframe_pending to signal that top Java frame should be popped immediately int _popframe_condition;
// If reallocation of scalar replaced objects fails, we throw OOM // and during exception propagation, pop the top // _frames_to_pop_failed_realloc frames, the ones that reference // failed reallocations. int _frames_to_pop_failed_realloc;
ContinuationEntry* _cont_entry;
intptr_t* _cont_fastpath; // the sp of the oldest known interpreted/call_stub frame inside the // continuation that we know about int _cont_fastpath_thread_state; // whether global thread state allows continuation fastpath (JVMTI) // It's signed for error detection. #ifdef _LP64
int64_t _held_monitor_count; // used by continuations for fast lock detection
int64_t _jni_monitor_count; #else
int32_t _held_monitor_count; // used by continuations for fast lock detection
int32_t _jni_monitor_count; #endif
// Thread oop. threadObj() can be NULL for initial JavaThread // (or for threads attached via JNI)
oop threadObj() const; void set_threadOopHandles(oop p);
oop vthread() const; void set_vthread(oop p);
oop scopedValueCache() const; void set_scopedValueCache(oop p); void clear_scopedValueBindings();
oop jvmti_vthread() const; void set_jvmti_vthread(oop p);
// Prepare thread and add to priority queue. If a priority is // not specified, use the priority of the thread object. Threads_lock // must be held while this function is called. void prepare(jobject jni_thread, ThreadPriority prio=NoPriority);
// Allocates a new Java level thread object for this thread. thread_name may be NULL. void allocate_threadObj(Handle thread_group, constchar* thread_name, bool daemon, TRAPS);
// thread has called JavaThread::exit(), thread's GC barrier is detached // or thread is terminated bool is_exiting() const; // thread's GC barrier is NOT detached and thread is NOT terminated bool is_oop_safe() const; // thread is terminated (no longer on the threads list); the thread must // be protected by a ThreadsListHandle to avoid potential crashes. bool check_is_terminated(TerminatedTypes l_terminated) const { return l_terminated == _thread_terminated || l_terminated == _vm_exited;
} bool is_terminated() const; void set_terminated(TerminatedTypes t);
// Support for thread handshake operations
HandshakeState _handshake; public:
HandshakeState* handshake_state() { return &_handshake; }
// A JavaThread can always safely operate on it self and other threads // can do it safely if they are the active handshaker. bool is_handshake_safe_for(Thread* th) const { return _handshake.active_handshaker() == th || this == th;
}
// Suspend/resume support for JavaThread // higher-level suspension/resume logic called by the public APIs bool java_suspend(); bool java_resume(); bool is_suspended() { return _handshake.is_suspended(); }
// Check for async exception in addition to safepoint. staticvoid check_special_condition_for_native_trans(JavaThread *thread);
// Synchronize with another thread that is deoptimizing objects of the // current thread, i.e. reverts optimizations based on escape analysis. void wait_for_object_deoptimization();
// Support for object deoptimization and JFR suspension void handle_special_runtime_exit_condition(); bool has_special_runtime_exit_condition() { return (_suspend_flags & (_obj_deopt JFR_ONLY(| _trace_flag))) != 0;
}
// Fast-locking support bool is_lock_owned(address adr) const;
// Accessors for vframe array top // The linked list of vframe arrays are sorted on sp. This means when we // unpack the head must contain the vframe array to unpack. void set_vframe_array_head(vframeArray* value) { _vframe_array_head = value; }
vframeArray* vframe_array_head() const { return _vframe_array_head; }
// Side structure for deferring update of java frame locals until deopt occurs
JvmtiDeferredUpdates* deferred_updates() const { return _jvmti_deferred_updates; } void set_deferred_updates(JvmtiDeferredUpdates* du) { _jvmti_deferred_updates = du; }
// These only really exist to make debugging deopt problems simpler
// Check if address is in the usable part of the stack (excludes protected // guard pages). Can be applied to any thread and is an approximation for // using is_in_live_stack when the query has to happen from another thread. bool is_in_usable_stack(address adr) const { return is_in_stack_range_incl(adr, _stack_overflow_state.stack_reserved_zone_base());
}
// Returns the jni environment for this thread
JNIEnv* jni_environment() { return &_jni_environment; }
// Returns the current thread as indicated by the given JNIEnv. // We don't assert it is Thread::current here as that is done at the // external JNI entry points where the JNIEnv is passed into the VM. static JavaThread* thread_from_jni_environment(JNIEnv* env) {
JavaThread* current = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset())); // We can't normally get here in a thread that has completed its // execution and so "is_terminated", except when the call is from // AsyncGetCallTrace, which can be triggered by a signal at any point in // a thread's lifecycle. A thread is also considered terminated if the VM // has exited, so we have to check this and block in case this is a daemon // thread returning to the VM (the JNI DirectBuffer entry points rely on // this). if (current->is_terminated()) {
current->block_if_vm_exited();
} return current;
}
// JNI critical regions. These can nest. bool in_critical() { return _jni_active_critical > 0; } bool in_last_critical() { return _jni_active_critical == 1; } inlinevoid enter_critical(); void exit_critical() {
assert(Thread::current() == this, "this must be current thread");
_jni_active_critical--;
assert(_jni_active_critical >= 0, "JNI critical nesting problem?");
}
// Checked JNI: is the programmer required to check for exceptions, if so specify // which function name. Returning to a Java frame should implicitly clear the // pending check, this is done for Native->Java transitions (i.e. user JNI code). // VM->Java transitions are not cleared, it is expected that JNI code enclosed // within ThreadToNativeFromVM makes proper exception checks (i.e. VM internal). bool is_pending_jni_exception_check() const { return _pending_jni_exception_check_fn != NULL; } void clear_pending_jni_exception_check() { _pending_jni_exception_check_fn = NULL; } constchar* get_pending_jni_exception_check() const { return _pending_jni_exception_check_fn; } void set_pending_jni_exception_check(constchar* fn_name) { _pending_jni_exception_check_fn = (char*) fn_name; }
// For deadlock detection int depth_first_number() { return _depth_first_number; } void set_depth_first_number(int dfn) { _depth_first_number = dfn; }
// Returns the active Java thread. Do not use this if you know you are calling // from a JavaThread, as it's slower than JavaThread::current. If called from // the VMThread, it also returns the JavaThread that instigated the VMThread's // operation. You may not want that either. static JavaThread* active();
public: // Thread local information maintained by JVMTI. void set_jvmti_thread_state(JvmtiThreadState *value) { _jvmti_thread_state = value; } // A JvmtiThreadState is lazily allocated. This jvmti_thread_state() // getter is used to get this JavaThread's JvmtiThreadState if it has // one which means NULL can be returned. JvmtiThreadState::state_for() // is used to get the specified JavaThread's JvmtiThreadState if it has // one or it allocates a new JvmtiThreadState for the JavaThread and // returns it. JvmtiThreadState::state_for() will return NULL only if // the specified JavaThread is exiting.
JvmtiThreadState *jvmti_thread_state() const { return _jvmti_thread_state; } static ByteSize jvmti_thread_state_offset() { return byte_offset_of(JavaThread, _jvmti_thread_state); }
#if INCLUDE_JVMTI // Rebind JVMTI thread state from carrier to virtual or from virtual to carrier.
JvmtiThreadState *rebind_to_jvmti_thread_state_of(oop thread_oop); #endif
// JVMTI PopFrame support // Setting and clearing popframe_condition // All of these enumerated values are bits. popframe_pending // indicates that a PopFrame() has been requested and not yet been // completed. popframe_processing indicates that that PopFrame() is in // the process of being completed. popframe_force_deopt_reexecution_bit // indicates that special handling is required when returning to a // deoptimized caller. enum PopCondition {
popframe_inactive = 0x00,
popframe_pending_bit = 0x01,
popframe_processing_bit = 0x02,
popframe_force_deopt_reexecution_bit = 0x04
};
PopCondition popframe_condition() { return (PopCondition) _popframe_condition; } void set_popframe_condition(PopCondition c) { _popframe_condition = c; } void set_popframe_condition_bit(PopCondition c) { _popframe_condition |= c; } void clear_popframe_condition() { _popframe_condition = popframe_inactive; } static ByteSize popframe_condition_offset() { return byte_offset_of(JavaThread, _popframe_condition); } bool has_pending_popframe() { return (popframe_condition() & popframe_pending_bit) != 0; } bool popframe_forcing_deopt_reexecution() { return (popframe_condition() & popframe_force_deopt_reexecution_bit) != 0; }
private: // Saved incoming arguments to popped frame. // Used only when popped interpreted frame returns to deoptimized frame. void* _popframe_preserved_args; int _popframe_preserved_args_size;
// Used by the interpreter in fullspeed mode for frame pop, method // entry, method exit and single stepping support. This field is // only set to non-zero at a safepoint or using a direct handshake // (see EnterInterpOnlyModeClosure). // It can be set to zero asynchronously to this threads execution (i.e., without // safepoint/handshake or a lock) so we have to be very careful. // Accesses by other threads are synchronized using JvmtiThreadState_lock though. int _interp_only_mode;
public: // used by the interpreter for fullspeed debugging support (see above) static ByteSize interp_only_mode_offset() { return byte_offset_of(JavaThread, _interp_only_mode); } bool is_interp_only_mode() { return (_interp_only_mode != 0); } int get_interp_only_mode() { return _interp_only_mode; } int set_interp_only_mode(int val) { return _interp_only_mode = val; } void increment_interp_only_mode() { ++_interp_only_mode; } void decrement_interp_only_mode() { --_interp_only_mode; }
// support for cached flag that indicates whether exceptions need to be posted for this thread // if this is false, we can avoid deoptimizing when events are thrown // this gets set to reflect whether jvmtiExport::post_exception_throw would actually do anything private: int _should_post_on_exceptions_flag;
// Stack dump assistance: // Track the class we want to initialize but for which we have to wait // on its init_lock() because it is already being initialized. void set_class_to_be_initialized(InstanceKlass* k);
InstanceKlass* class_to_be_initialized() const;
private:
InstanceKlass* _class_to_be_initialized;
// java.lang.Thread.sleep support
ParkEvent * _SleepEvent; public: bool sleep(jlong millis);
// java.lang.Thread interruption support void interrupt(); bool is_interrupted(bool clear_interrupted);
// Helper function to create the java.lang.Thread object for a // VM-internal thread. The thread will have the given name, be // part of the System ThreadGroup and if is_visible is true will be // discoverable via the system ThreadGroup. static Handle create_system_thread_object(constchar* name, bool is_visible, TRAPS);
// Helper function to start a VM-internal daemon thread. // E.g. ServiceThread, NotificationThread, CompilerThread etc. staticvoid start_internal_daemon(JavaThread* current, JavaThread* target,
Handle thread_oop, ThreadPriority prio);
// Helper function to do vm_exit_on_initialization for osthread // resource allocation failure. staticvoid vm_exit_on_osthread_failure(JavaThread* thread);
// Deferred OopHandle release support private: // List of OopHandles to be released - guarded by the Service_lock. static OopHandleList* _oop_handle_list; // Add our OopHandles to the list for the service thread to release. void add_oop_handles_for_release(); // Called by the ServiceThread to release the OopHandles. staticvoid release_oop_handles(); // Called by the ServiceThread to poll if there are any OopHandles to release. // Called when holding the Service_lock. staticbool has_oop_handles_to_release() { return _oop_handle_list != nullptr;
}
};
inline JavaThread* JavaThread::current_or_null() {
Thread* current = Thread::current_or_null(); return current != nullptr ? JavaThread::cast(current) : nullptr;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.