48 #include "logging/log.hpp"
49 #include "logging/logStream.hpp"
50 #include "memory/oopFactory.hpp"
51 #include "memory/resourceArea.hpp"
52 #include "memory/universe.hpp"
53 #include "oops/fieldInfo.hpp"
54 #include "oops/fieldStreams.inline.hpp"
55 #include "oops/instanceKlass.inline.hpp"
56 #include "oops/instanceMirrorKlass.hpp"
57 #include "oops/klass.hpp"
58 #include "oops/klass.inline.hpp"
59 #include "oops/method.inline.hpp"
60 #include "oops/objArrayKlass.hpp"
61 #include "oops/objArrayOop.inline.hpp"
62 #include "oops/oopCast.inline.hpp"
63 #include "oops/oop.inline.hpp"
64 #include "oops/symbol.hpp"
65 #include "oops/recordComponent.hpp"
66 #include "oops/typeArrayOop.inline.hpp"
67 #include "prims/jvmtiExport.hpp"
68 #include "prims/methodHandles.hpp"
69 #include "prims/resolvedMethodTable.hpp"
70 #include "runtime/continuationEntry.inline.hpp"
71 #include "runtime/continuationJavaClasses.inline.hpp"
72 #include "runtime/fieldDescriptor.inline.hpp"
73 #include "runtime/frame.inline.hpp"
74 #include "runtime/handles.inline.hpp"
75 #include "runtime/handshake.hpp"
76 #include "runtime/init.hpp"
77 #include "runtime/interfaceSupport.inline.hpp"
78 #include "runtime/java.hpp"
79 #include "runtime/javaCalls.hpp"
80 #include "runtime/javaThread.hpp"
81 #include "runtime/jniHandles.inline.hpp"
82 #include "runtime/reflectionUtils.hpp"
83 #include "runtime/safepoint.hpp"
84 #include "runtime/safepointVerifiers.hpp"
85 #include "runtime/threadSMR.hpp"
86 #include "runtime/vframe.inline.hpp"
87 #include "runtime/vm_version.hpp"
88 #include "utilities/align.hpp"
89 #include "utilities/globalDefinitions.hpp"
90 #include "utilities/growableArray.hpp"
91 #include "utilities/preserveException.hpp"
92 #include "utilities/utf8.hpp"
93 #if INCLUDE_JVMCI
94 #include "jvmci/jvmciJavaClasses.hpp"
95 #endif
96
97 #define DECLARE_INJECTED_FIELD(klass, name, signature, may_be_java) \
98 { VM_CLASS_ID(klass), VM_SYMBOL_ENUM_NAME(name##_name), VM_SYMBOL_ENUM_NAME(signature), may_be_java },
99
100 InjectedField JavaClasses::_injected_fields[] = {
101 ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD)
102 };
103
104 // Register native methods of Object
1857 }
1858
1859 // Read thread status value from threadStatus field in java.lang.Thread java class.
1860 JavaThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
1861 // Make sure the caller is operating on behalf of the VM or is
1862 // running VM code (state == _thread_in_vm).
1863 assert(Threads_lock->owned_by_self() || Thread::current()->is_VM_thread() ||
1864 JavaThread::current()->thread_state() == _thread_in_vm,
1865 "Java Thread is not running in vm");
1866 GET_FIELDHOLDER_FIELD(java_thread, get_thread_status, JavaThreadStatus::NEW /* not initialized */);
1867 }
1868
1869 ByteSize java_lang_Thread::thread_id_offset() {
1870 return in_ByteSize(_tid_offset);
1871 }
1872
1873 oop java_lang_Thread::park_blocker(oop java_thread) {
1874 return java_thread->obj_field(_park_blocker_offset);
1875 }
1876
1877 oop java_lang_Thread::async_get_stack_trace(oop java_thread, TRAPS) {
1878 ThreadsListHandle tlh(JavaThread::current());
1879 JavaThread* thread;
1880 bool is_virtual = java_lang_VirtualThread::is_instance(java_thread);
1881 if (is_virtual) {
1882 oop carrier_thread = java_lang_VirtualThread::carrier_thread(java_thread);
1883 if (carrier_thread == nullptr) {
1884 return nullptr;
1885 }
1886 thread = java_lang_Thread::thread(carrier_thread);
1887 } else {
1888 thread = java_lang_Thread::thread(java_thread);
1889 }
1890 if (thread == nullptr) {
1891 return nullptr;
1892 }
1893
1894 class GetStackTraceClosure : public HandshakeClosure {
1895 public:
1896 const Handle _java_thread;
1981
1982 // Convert to StackTraceElement array
1983 InstanceKlass* k = vmClasses::StackTraceElement_klass();
1984 assert(k != nullptr, "must be loaded in 1.4+");
1985 if (k->should_be_initialized()) {
1986 k->initialize(CHECK_NULL);
1987 }
1988 objArrayHandle trace = oopFactory::new_objArray_handle(k, gstc._depth, CHECK_NULL);
1989
1990 for (int i = 0; i < gstc._depth; i++) {
1991 methodHandle method(THREAD, gstc._methods->at(i));
1992 oop element = java_lang_StackTraceElement::create(method,
1993 gstc._bcis->at(i),
1994 CHECK_NULL);
1995 trace->obj_at_put(i, element);
1996 }
1997
1998 return trace();
1999 }
2000
2001 const char* java_lang_Thread::thread_status_name(oop java_thread) {
2002 JavaThreadStatus status = get_thread_status(java_thread);
2003 switch (status) {
2004 case JavaThreadStatus::NEW : return "NEW";
2005 case JavaThreadStatus::RUNNABLE : return "RUNNABLE";
2006 case JavaThreadStatus::SLEEPING : return "TIMED_WAITING (sleeping)";
2007 case JavaThreadStatus::IN_OBJECT_WAIT : return "WAITING (on object monitor)";
2008 case JavaThreadStatus::IN_OBJECT_WAIT_TIMED : return "TIMED_WAITING (on object monitor)";
2009 case JavaThreadStatus::PARKED : return "WAITING (parking)";
2010 case JavaThreadStatus::PARKED_TIMED : return "TIMED_WAITING (parking)";
2011 case JavaThreadStatus::BLOCKED_ON_MONITOR_ENTER : return "BLOCKED (on object monitor)";
2012 case JavaThreadStatus::TERMINATED : return "TERMINATED";
2013 default : return "UNKNOWN";
2014 };
2015 }
2016 int java_lang_ThreadGroup::_parent_offset;
2017 int java_lang_ThreadGroup::_name_offset;
2018 int java_lang_ThreadGroup::_maxPriority_offset;
2019 int java_lang_ThreadGroup::_daemon_offset;
2020
2056 InstanceKlass* k = vmClasses::ThreadGroup_klass();
2057 THREADGROUP_FIELDS_DO(FIELD_COMPUTE_OFFSET);
2058 }
2059
2060 #if INCLUDE_CDS
2061 void java_lang_ThreadGroup::serialize_offsets(SerializeClosure* f) {
2062 THREADGROUP_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
2063 }
2064 #endif
2065
2066
2067 // java_lang_VirtualThread
2068
2069 int java_lang_VirtualThread::static_vthread_scope_offset;
2070 int java_lang_VirtualThread::_carrierThread_offset;
2071 int java_lang_VirtualThread::_continuation_offset;
2072 int java_lang_VirtualThread::_state_offset;
2073 int java_lang_VirtualThread::_next_offset;
2074 int java_lang_VirtualThread::_onWaitingList_offset;
2075 int java_lang_VirtualThread::_notified_offset;
2076 int java_lang_VirtualThread::_timeout_offset;
2077 int java_lang_VirtualThread::_objectWaiter_offset;
2078
2079 #define VTHREAD_FIELDS_DO(macro) \
2080 macro(static_vthread_scope_offset, k, "VTHREAD_SCOPE", continuationscope_signature, true); \
2081 macro(_carrierThread_offset, k, "carrierThread", thread_signature, false); \
2082 macro(_continuation_offset, k, "cont", continuation_signature, false); \
2083 macro(_state_offset, k, "state", int_signature, false); \
2084 macro(_next_offset, k, "next", vthread_signature, false); \
2085 macro(_onWaitingList_offset, k, "onWaitingList", bool_signature, false); \
2086 macro(_notified_offset, k, "notified", bool_signature, false); \
2087 macro(_timeout_offset, k, "timeout", long_signature, false);
2088
2089
2090 void java_lang_VirtualThread::compute_offsets() {
2091 InstanceKlass* k = vmClasses::VirtualThread_klass();
2092 VTHREAD_FIELDS_DO(FIELD_COMPUTE_OFFSET);
2093 VTHREAD_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
2094 }
2095
2096 bool java_lang_VirtualThread::is_instance(oop obj) {
2097 return obj != nullptr && is_subclass(obj->klass());
2098 }
2099
2100 oop java_lang_VirtualThread::carrier_thread(oop vthread) {
2101 oop thread = vthread->obj_field(_carrierThread_offset);
2102 return thread;
2103 }
2104
2105 oop java_lang_VirtualThread::continuation(oop vthread) {
2106 oop cont = vthread->obj_field(_continuation_offset);
2136 bool java_lang_VirtualThread::set_onWaitingList(oop vthread, OopHandle& list_head) {
2137 jboolean* addr = vthread->field_addr<jboolean>(_onWaitingList_offset);
2138 jboolean vthread_on_list = Atomic::load(addr);
2139 if (!vthread_on_list) {
2140 vthread_on_list = Atomic::cmpxchg(addr, (jboolean)JNI_FALSE, (jboolean)JNI_TRUE);
2141 if (!vthread_on_list) {
2142 for (;;) {
2143 oop head = list_head.resolve();
2144 java_lang_VirtualThread::set_next(vthread, head);
2145 if (list_head.cmpxchg(head, vthread) == head) return true;
2146 }
2147 }
2148 }
2149 return false; // already on waiting list
2150 }
2151
2152 void java_lang_VirtualThread::set_notified(oop vthread, jboolean value) {
2153 vthread->bool_field_put_volatile(_notified_offset, value);
2154 }
2155
2156 jlong java_lang_VirtualThread::timeout(oop vthread) {
2157 return vthread->long_field(_timeout_offset);
2158 }
2159
2160 void java_lang_VirtualThread::set_timeout(oop vthread, jlong value) {
2161 vthread->long_field_put(_timeout_offset, value);
2162 }
2163
2164 JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) {
2165 JavaThreadStatus status = JavaThreadStatus::NEW;
2166 switch (state & ~SUSPENDED) {
2167 case NEW:
2168 status = JavaThreadStatus::NEW;
2169 break;
2170 case STARTED:
2171 case RUNNING:
2172 case PARKING:
2173 case TIMED_PARKING:
2174 case UNPARKED:
2175 case YIELDING:
3350 LIVESTACKFRAMEINFO_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
3351 }
3352 #endif
3353
3354 void java_lang_LiveStackFrameInfo::set_monitors(oop obj, oop value) {
3355 obj->obj_field_put(_monitors_offset, value);
3356 }
3357
3358 void java_lang_LiveStackFrameInfo::set_locals(oop obj, oop value) {
3359 obj->obj_field_put(_locals_offset, value);
3360 }
3361
3362 void java_lang_LiveStackFrameInfo::set_operands(oop obj, oop value) {
3363 obj->obj_field_put(_operands_offset, value);
3364 }
3365
3366 void java_lang_LiveStackFrameInfo::set_mode(oop obj, int value) {
3367 obj->int_field_put(_mode_offset, value);
3368 }
3369
3370
3371 // java_lang_AccessibleObject
3372
3373 int java_lang_reflect_AccessibleObject::_override_offset;
3374
3375 #define ACCESSIBLEOBJECT_FIELDS_DO(macro) \
3376 macro(_override_offset, k, "override", bool_signature, false)
3377
3378 void java_lang_reflect_AccessibleObject::compute_offsets() {
3379 InstanceKlass* k = vmClasses::reflect_AccessibleObject_klass();
3380 ACCESSIBLEOBJECT_FIELDS_DO(FIELD_COMPUTE_OFFSET);
3381 }
3382
3383 #if INCLUDE_CDS
3384 void java_lang_reflect_AccessibleObject::serialize_offsets(SerializeClosure* f) {
3385 ACCESSIBLEOBJECT_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
3386 }
3387 #endif
3388
3389 jboolean java_lang_reflect_AccessibleObject::override(oop reflect) {
3390 return (jboolean) reflect->bool_field(_override_offset);
|
48 #include "logging/log.hpp"
49 #include "logging/logStream.hpp"
50 #include "memory/oopFactory.hpp"
51 #include "memory/resourceArea.hpp"
52 #include "memory/universe.hpp"
53 #include "oops/fieldInfo.hpp"
54 #include "oops/fieldStreams.inline.hpp"
55 #include "oops/instanceKlass.inline.hpp"
56 #include "oops/instanceMirrorKlass.hpp"
57 #include "oops/klass.hpp"
58 #include "oops/klass.inline.hpp"
59 #include "oops/method.inline.hpp"
60 #include "oops/objArrayKlass.hpp"
61 #include "oops/objArrayOop.inline.hpp"
62 #include "oops/oopCast.inline.hpp"
63 #include "oops/oop.inline.hpp"
64 #include "oops/symbol.hpp"
65 #include "oops/recordComponent.hpp"
66 #include "oops/typeArrayOop.inline.hpp"
67 #include "prims/jvmtiExport.hpp"
68 #include "prims/jvmtiThreadState.hpp" // for JvmtiVTMSTransitionDisabler
69 #include "prims/methodHandles.hpp"
70 #include "prims/resolvedMethodTable.hpp"
71 #include "runtime/continuationEntry.inline.hpp"
72 #include "runtime/continuationJavaClasses.inline.hpp"
73 #include "runtime/fieldDescriptor.inline.hpp"
74 #include "runtime/frame.inline.hpp"
75 #include "runtime/handles.inline.hpp"
76 #include "runtime/handshake.hpp"
77 #include "runtime/init.hpp"
78 #include "runtime/interfaceSupport.inline.hpp"
79 #include "runtime/java.hpp"
80 #include "runtime/javaCalls.hpp"
81 #include "runtime/javaThread.hpp"
82 #include "runtime/jniHandles.inline.hpp"
83 #include "runtime/reflectionUtils.hpp"
84 #include "runtime/safepoint.hpp"
85 #include "runtime/safepointVerifiers.hpp"
86 #include "runtime/synchronizer.inline.hpp"
87 #include "runtime/threadSMR.hpp"
88 #include "runtime/vframe.inline.hpp"
89 #include "runtime/vm_version.hpp"
90 #include "utilities/align.hpp"
91 #include "utilities/globalDefinitions.hpp"
92 #include "utilities/growableArray.hpp"
93 #include "utilities/preserveException.hpp"
94 #include "utilities/utf8.hpp"
95 #if INCLUDE_JVMCI
96 #include "jvmci/jvmciJavaClasses.hpp"
97 #endif
98
99 #define DECLARE_INJECTED_FIELD(klass, name, signature, may_be_java) \
100 { VM_CLASS_ID(klass), VM_SYMBOL_ENUM_NAME(name##_name), VM_SYMBOL_ENUM_NAME(signature), may_be_java },
101
102 InjectedField JavaClasses::_injected_fields[] = {
103 ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD)
104 };
105
106 // Register native methods of Object
1859 }
1860
1861 // Read thread status value from threadStatus field in java.lang.Thread java class.
1862 JavaThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
1863 // Make sure the caller is operating on behalf of the VM or is
1864 // running VM code (state == _thread_in_vm).
1865 assert(Threads_lock->owned_by_self() || Thread::current()->is_VM_thread() ||
1866 JavaThread::current()->thread_state() == _thread_in_vm,
1867 "Java Thread is not running in vm");
1868 GET_FIELDHOLDER_FIELD(java_thread, get_thread_status, JavaThreadStatus::NEW /* not initialized */);
1869 }
1870
1871 ByteSize java_lang_Thread::thread_id_offset() {
1872 return in_ByteSize(_tid_offset);
1873 }
1874
1875 oop java_lang_Thread::park_blocker(oop java_thread) {
1876 return java_thread->obj_field(_park_blocker_offset);
1877 }
1878
1879
1880 struct LockInfo {
1881 enum { // should be synced with jdk.internal.vm.ThreadSnapshot.ThreadLock constants
1882 PARKING_TO_WAIT = 0,
1883 ELEMINATED_SCALAR_REPLACED = 1,
1884 ELEMINATED_MONITOR = 2,
1885 LOCKED = 3,
1886 WAITING_TO_LOCK = 4,
1887 WAITING_ON = 5,
1888 WAITING_TO_RELOCK = 6,
1889 OWNABLE_SYNCHRONIZER = 7,
1890 };
1891
1892 int _depth;
1893 int _type;
1894 oop _obj;
1895
1896 LockInfo(int depth, int type, oop obj) : _depth(depth), _type(type), _obj(obj) {}
1897 LockInfo() : _depth(0), _type(0), _obj(nullptr) {}
1898 };
1899
1900 class GetThreadSnapshotClosure : public HandshakeClosure {
1901 public:
1902 Handle _java_thread;
1903 JavaThread* _thread;
1904 int _depth;
1905 bool _retry_handshake;
1906 GrowableArray<Method*>* _methods;
1907 GrowableArray<int>* _bcis;
1908 JavaThreadStatus _thread_status;
1909 oop _name;
1910 bool _with_locks;
1911 bool _found_first_lock;
1912 GrowableArray<LockInfo>* _locks;
1913
1914 GetThreadSnapshotClosure(Handle java_thread, JavaThread* thread, bool with_locks) :
1915 HandshakeClosure("GetThreadSnapshotClosure"), _java_thread(java_thread), _thread(thread),
1916 _depth(0), _retry_handshake(false),
1917 _methods(nullptr), _bcis(nullptr),
1918 _thread_status(), _name(nullptr),
1919 _with_locks(with_locks), _found_first_lock(false), _locks(nullptr) { }
1920 virtual ~GetThreadSnapshotClosure() {
1921 delete _methods;
1922 delete _bcis;
1923 if (_locks != nullptr) {
1924 delete _locks;
1925 }
1926 }
1927
1928 bool read_reset_retry() {
1929 bool ret = _retry_handshake;
1930 // If we re-execute the handshake this method need to return false
1931 // when the handshake cannot be performed. (E.g. thread terminating)
1932 _retry_handshake = false;
1933 return ret;
1934 }
1935
1936 void detect_locks(javaVFrame* jvf, int depth) {
1937 Thread* current = Thread::current();
1938
1939 if (depth == 0 && !_found_first_lock) {
1940 // See javaVFrame::print_lock_info_on() for some other cases:
1941 // "waiting to re-lock in wait", "waiting on the Class initialization monitor".
1942
1943 // If this is the first frame and it is java.lang.Object.wait(...)
1944 // then print out the receiver.
1945 if (jvf->method()->name() == vmSymbols::wait_name() &&
1946 jvf->method()->method_holder()->name() == vmSymbols::java_lang_Object()) {
1947 StackValueCollection* locs = jvf->locals();
1948 if (locs->is_empty()) {
1949 _locks->push(LockInfo(depth, LockInfo::WAITING_ON, nullptr));
1950 } else {
1951 int type = LockInfo::WAITING_ON;
1952 StackValue* sv = locs->at(0);
1953 if (sv->type() == T_OBJECT) {
1954 Handle o = locs->at(0)->get_obj();
1955 if (_thread_status == JavaThreadStatus::BLOCKED_ON_MONITOR_ENTER) {
1956 type = LockInfo::WAITING_TO_RELOCK;;
1957 }
1958 _locks->push(LockInfo(depth, type, o()));
1959 }
1960 }
1961 _found_first_lock = true;
1962 } else {
1963 oop park_blocker = java_lang_Thread::park_blocker(_java_thread());
1964 if (park_blocker != nullptr) {
1965 _locks->push(LockInfo(depth, LockInfo::PARKING_TO_WAIT, park_blocker));
1966 _found_first_lock = true;
1967 }
1968 }
1969 }
1970
1971 GrowableArray<MonitorInfo*>* mons = jvf->monitors();
1972 if (!mons->is_empty()) {
1973 for (int index = (mons->length() - 1); index >= 0; index--) {
1974 MonitorInfo* monitor = mons->at(index);
1975 if (monitor->eliminated() && jvf->is_compiled_frame()) { // Eliminated in compiled code
1976 if (monitor->owner_is_scalar_replaced()) {
1977 Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
1978 _locks->push(LockInfo(depth, LockInfo::ELEMINATED_SCALAR_REPLACED, k->klass_holder()));
1979 } else {
1980 Handle obj(current, monitor->owner());
1981 if (obj() != nullptr) {
1982 _locks->push(LockInfo(depth, LockInfo::ELEMINATED_MONITOR, obj()));
1983 }
1984 }
1985 continue;
1986 }
1987 if (monitor->owner() != nullptr) {
1988 // the monitor is associated with an object, i.e., it is locked
1989 int type = LockInfo::LOCKED;
1990
1991 if (depth == 0 && !_found_first_lock) {
1992 ObjectMonitor* pending_moninor = java_lang_VirtualThread::is_instance(_java_thread())
1993 ? java_lang_VirtualThread::current_pending_monitor(_java_thread())
1994 : jvf->thread()->current_pending_monitor();
1995
1996 markWord mark = monitor->owner()->mark();
1997 // The first stage of async deflation does not affect any field
1998 // used by this comparison so the ObjectMonitor* is usable here.
1999 if (mark.has_monitor()) {
2000 ObjectMonitor* mon = ObjectSynchronizer::read_monitor(current, monitor->owner(), mark);
2001 if (// if the monitor is null we must be in the process of locking
2002 mon == nullptr ||
2003 // we have marked ourself as pending on this monitor
2004 mon == pending_moninor ||
2005 // we are not the owner of this monitor
2006 false/*!mon->is_entered(thread())*/) {
2007 type = LockInfo::WAITING_TO_LOCK;
2008 }
2009 }
2010 }
2011 _locks->push(LockInfo(depth, type, monitor->owner()));
2012
2013 _found_first_lock = true;
2014 }
2015 }
2016 }
2017 }
2018
2019 void do_thread(Thread* th) override {
2020 if (!Thread::current()->is_Java_thread()) {
2021 _retry_handshake = true;
2022 return;
2023 }
2024
2025 bool is_virtual = java_lang_VirtualThread::is_instance(_java_thread());
2026 if (_thread != nullptr) {
2027 if (is_virtual) {
2028 // mounted vthread, use carrier thread state
2029 oop carrier_thread = java_lang_VirtualThread::carrier_thread(_java_thread());
2030 _thread_status = java_lang_Thread::get_thread_status(carrier_thread);
2031 } else {
2032 _thread_status = java_lang_Thread::get_thread_status(_java_thread());
2033 }
2034 } else {
2035 // unmounted vthread
2036 int vt_state = java_lang_VirtualThread::state(_java_thread());
2037 _thread_status = java_lang_VirtualThread::map_state_to_thread_status(vt_state);
2038 }
2039 _name = java_lang_Thread::name(_java_thread());
2040
2041 if (_thread != nullptr && !_thread->has_last_Java_frame()) {
2042 // stack trace is empty
2043 return;
2044 }
2045
2046 bool carrier = false;
2047
2048 if (is_virtual) {
2049 if (_thread != nullptr) {
2050 // if (thread->vthread() != _java_thread()) // We might be inside a System.executeOnCarrierThread
2051 const ContinuationEntry* ce = _thread->vthread_continuation();
2052 if (ce == nullptr || ce->cont_oop(_thread) != java_lang_VirtualThread::continuation(_java_thread())) {
2053 // TODO: handle
2054 }
2055 }
2056 } else {
2057 carrier = (_thread->vthread_continuation() != nullptr);
2058 }
2059
2060 ResourceMark rm(Thread::current());
2061
2062 const int max_depth = MaxJavaStackTraceDepth;
2063 const bool skip_hidden = !ShowHiddenFrames;
2064
2065 // Pick minimum length that will cover most cases
2066 int init_length = 64;
2067 _methods = new (mtInternal) GrowableArray<Method*>(init_length, mtInternal);
2068 _bcis = new (mtInternal) GrowableArray<int>(init_length, mtInternal);
2069
2070 if (_with_locks) {
2071 _locks = new (mtInternal) GrowableArray<LockInfo>(init_length, mtInternal);
2072 }
2073 int total_count = 0;
2074
2075 vframeStream vfst(_thread != nullptr
2076 ? vframeStream(_thread, false, false, carrier)
2077 : vframeStream(java_lang_VirtualThread::continuation(_java_thread())));
2078
2079 for (;
2080 !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
2081 vfst.next()) {
2082 if (_with_locks) {
2083 detect_locks(vfst.asJavaVFrame(), total_count);
2084 }
2085 if (skip_hidden && (vfst.method()->is_hidden() ||
2086 vfst.method()->is_continuation_enter_intrinsic())) {
2087 continue;
2088 }
2089 _methods->push(vfst.method());
2090 _bcis->push(vfst.bci());
2091 total_count++;
2092 }
2093
2094 _depth = total_count;
2095 }
2096 };
2097
2098 oop java_lang_Thread::async_get_stack_trace(oop java_thread, TRAPS) {
2099 ThreadsListHandle tlh(JavaThread::current());
2100 JavaThread* thread;
2101 bool is_virtual = java_lang_VirtualThread::is_instance(java_thread);
2102 if (is_virtual) {
2103 oop carrier_thread = java_lang_VirtualThread::carrier_thread(java_thread);
2104 if (carrier_thread == nullptr) {
2105 return nullptr;
2106 }
2107 thread = java_lang_Thread::thread(carrier_thread);
2108 } else {
2109 thread = java_lang_Thread::thread(java_thread);
2110 }
2111 if (thread == nullptr) {
2112 return nullptr;
2113 }
2114
2115 class GetStackTraceClosure : public HandshakeClosure {
2116 public:
2117 const Handle _java_thread;
2202
2203 // Convert to StackTraceElement array
2204 InstanceKlass* k = vmClasses::StackTraceElement_klass();
2205 assert(k != nullptr, "must be loaded in 1.4+");
2206 if (k->should_be_initialized()) {
2207 k->initialize(CHECK_NULL);
2208 }
2209 objArrayHandle trace = oopFactory::new_objArray_handle(k, gstc._depth, CHECK_NULL);
2210
2211 for (int i = 0; i < gstc._depth; i++) {
2212 methodHandle method(THREAD, gstc._methods->at(i));
2213 oop element = java_lang_StackTraceElement::create(method,
2214 gstc._bcis->at(i),
2215 CHECK_NULL);
2216 trace->obj_at_put(i, element);
2217 }
2218
2219 return trace();
2220 }
2221
2222 oop java_lang_Thread::get_thread_snapshot(jobject jthread, bool with_locks, TRAPS) {
2223 ThreadsListHandle tlh(JavaThread::current());
2224
2225 ResourceMark rm(THREAD);
2226 HandleMark hm(THREAD);
2227 Handle java_thread(THREAD, JNIHandles::resolve(jthread));
2228
2229 // wrapper to auto delete JvmtiVTMSTransitionDisabler
2230 class TransitionDisabler {
2231 JvmtiVTMSTransitionDisabler* _transition_disabler;
2232 public:
2233 TransitionDisabler() : _transition_disabler(nullptr) {}
2234 ~TransitionDisabler() {
2235 reset();
2236 }
2237 void init(jobject jthread) {
2238 _transition_disabler = new (mtInternal) JvmtiVTMSTransitionDisabler(jthread);
2239 }
2240 void reset() {
2241 if (_transition_disabler != nullptr) {
2242 delete _transition_disabler;
2243 _transition_disabler = nullptr;
2244 }
2245 }
2246 } transition_disabler;
2247
2248 JavaThread* thread = nullptr;
2249 bool is_virtual = java_lang_VirtualThread::is_instance(java_thread());
2250
2251 if (is_virtual) {
2252 // 1st need to disable mount/unmount transitions
2253 transition_disabler.init(jthread);
2254
2255 oop carrier_thread = java_lang_VirtualThread::carrier_thread(java_thread());
2256 if (carrier_thread != nullptr) {
2257 thread = java_lang_Thread::thread(carrier_thread);
2258 }
2259 } else {
2260 thread = java_lang_Thread::thread(java_thread());
2261 }
2262
2263 // Handshake with target
2264 GetThreadSnapshotClosure cl(java_thread, thread, with_locks);
2265 if (thread == nullptr) {
2266 // unmounted vthread, execute on the current thread
2267 cl.do_thread(nullptr);
2268 } else {
2269 do {
2270 Handshake::execute(&cl, &tlh, thread);
2271 } while (cl.read_reset_retry());
2272 }
2273
2274 // Handle thread name
2275 Handle thread_name(THREAD, cl._name);
2276
2277 // Convert to StackTraceElement array
2278 InstanceKlass* ste_klass = vmClasses::StackTraceElement_klass();
2279 assert(ste_klass != nullptr, "must be loaded in 1.4+");
2280 if (ste_klass->should_be_initialized()) {
2281 ste_klass->initialize(CHECK_NULL);
2282 }
2283
2284 int max_locks = cl._locks != nullptr ? cl._locks->length() : 0;
2285
2286 InstanceKlass* lock_klass = nullptr;
2287 if (with_locks) {
2288 Symbol* sym = vmSymbols::jdk_internal_vm_ThreadLock();
2289 Klass* k = SystemDictionary::resolve_or_fail(sym, true, CHECK_NULL);
2290 lock_klass = InstanceKlass::cast(k);
2291 }
2292
2293 objArrayHandle trace = oopFactory::new_objArray_handle(ste_klass, cl._depth, CHECK_NULL);
2294
2295 for (int i = 0; i < cl._depth; i++) {
2296 methodHandle method(THREAD, cl._methods->at(i));
2297 oop element = java_lang_StackTraceElement::create(method, cl._bcis->at(i), CHECK_NULL);
2298 trace->obj_at_put(i, element);
2299 }
2300 // call static StackTraceElement[] of(StackTraceElement[] stackTrace)
2301 // to properly initialize STE.
2302 {
2303 JavaValue result(T_OBJECT);
2304 JavaCalls::call_static(&result,
2305 ste_klass,
2306 vmSymbols::java_lang_StackTraceElement_of_name(),
2307 vmSymbols::java_lang_StackTraceElement_of_signature(),
2308 trace,
2309 CHECK_NULL);
2310 // the method return the same trace object
2311 }
2312
2313 objArrayHandle locks;
2314 int lock_index = 0;
2315 if (with_locks && max_locks > 0) {
2316 locks = oopFactory::new_objArray_handle(lock_klass, max_locks, CHECK_NULL);
2317 for (int n = 0; n < max_locks; n++) {
2318 LockInfo* lock_info = cl._locks->adr_at(lock_index++);
2319 oop o = lock_info->_obj;
2320 Handle lock_object = Handle(THREAD, o);
2321
2322 // TODO: allocate and fill in the VM
2323 JavaCallArguments args;
2324 args.push_int(lock_info->_depth);
2325 args.push_int(lock_info->_type);
2326 args.push_oop(lock_object);
2327 Handle lock = JavaCalls::construct_new_instance(lock_klass,
2328 vmSymbols::jdk_internal_vm_ThreadLock_ctor_signature(), &args, CHECK_NULL);
2329
2330 locks->obj_at_put(n, lock());
2331 }
2332 }
2333
2334 // all oops are handled, can enable transitions.
2335 transition_disabler.reset();
2336
2337 Symbol* snapshot_name = vmSymbols::jdk_internal_vm_ThreadSnapshot();
2338 Klass* snapshot_klass = SystemDictionary::resolve_or_fail(snapshot_name, true, CHECK_NULL);
2339 if (snapshot_klass->should_be_initialized()) {
2340 snapshot_klass->initialize(CHECK_NULL);
2341 }
2342
2343 // TODO: allocate and fill in the VM
2344 JavaCallArguments args;
2345 args.push_oop(trace);
2346 args.push_oop(locks);
2347 args.push_oop(thread_name);
2348 args.push_int((int)cl._thread_status);
2349 Handle snapshot = JavaCalls::construct_new_instance(InstanceKlass::cast(snapshot_klass),
2350 vmSymbols::jdk_internal_vm_ThreadSnapshot_ctor_signature(), &args, CHECK_NULL);
2351 return snapshot();
2352 }
2353
2354 const char* java_lang_Thread::thread_status_name(oop java_thread) {
2355 JavaThreadStatus status = get_thread_status(java_thread);
2356 switch (status) {
2357 case JavaThreadStatus::NEW : return "NEW";
2358 case JavaThreadStatus::RUNNABLE : return "RUNNABLE";
2359 case JavaThreadStatus::SLEEPING : return "TIMED_WAITING (sleeping)";
2360 case JavaThreadStatus::IN_OBJECT_WAIT : return "WAITING (on object monitor)";
2361 case JavaThreadStatus::IN_OBJECT_WAIT_TIMED : return "TIMED_WAITING (on object monitor)";
2362 case JavaThreadStatus::PARKED : return "WAITING (parking)";
2363 case JavaThreadStatus::PARKED_TIMED : return "TIMED_WAITING (parking)";
2364 case JavaThreadStatus::BLOCKED_ON_MONITOR_ENTER : return "BLOCKED (on object monitor)";
2365 case JavaThreadStatus::TERMINATED : return "TERMINATED";
2366 default : return "UNKNOWN";
2367 };
2368 }
2369 int java_lang_ThreadGroup::_parent_offset;
2370 int java_lang_ThreadGroup::_name_offset;
2371 int java_lang_ThreadGroup::_maxPriority_offset;
2372 int java_lang_ThreadGroup::_daemon_offset;
2373
2409 InstanceKlass* k = vmClasses::ThreadGroup_klass();
2410 THREADGROUP_FIELDS_DO(FIELD_COMPUTE_OFFSET);
2411 }
2412
2413 #if INCLUDE_CDS
2414 void java_lang_ThreadGroup::serialize_offsets(SerializeClosure* f) {
2415 THREADGROUP_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
2416 }
2417 #endif
2418
2419
2420 // java_lang_VirtualThread
2421
2422 int java_lang_VirtualThread::static_vthread_scope_offset;
2423 int java_lang_VirtualThread::_carrierThread_offset;
2424 int java_lang_VirtualThread::_continuation_offset;
2425 int java_lang_VirtualThread::_state_offset;
2426 int java_lang_VirtualThread::_next_offset;
2427 int java_lang_VirtualThread::_onWaitingList_offset;
2428 int java_lang_VirtualThread::_notified_offset;
2429 int java_lang_VirtualThread::_interruptible_wait_offset;
2430 int java_lang_VirtualThread::_timeout_offset;
2431 int java_lang_VirtualThread::_objectWaiter_offset;
2432
2433 #define VTHREAD_FIELDS_DO(macro) \
2434 macro(static_vthread_scope_offset, k, "VTHREAD_SCOPE", continuationscope_signature, true); \
2435 macro(_carrierThread_offset, k, "carrierThread", thread_signature, false); \
2436 macro(_continuation_offset, k, "cont", continuation_signature, false); \
2437 macro(_state_offset, k, "state", int_signature, false); \
2438 macro(_next_offset, k, "next", vthread_signature, false); \
2439 macro(_onWaitingList_offset, k, "onWaitingList", bool_signature, false); \
2440 macro(_notified_offset, k, "notified", bool_signature, false); \
2441 macro(_interruptible_wait_offset, k, "interruptableWait", bool_signature, false); \
2442 macro(_timeout_offset, k, "timeout", long_signature, false);
2443
2444
2445 void java_lang_VirtualThread::compute_offsets() {
2446 InstanceKlass* k = vmClasses::VirtualThread_klass();
2447 VTHREAD_FIELDS_DO(FIELD_COMPUTE_OFFSET);
2448 VTHREAD_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
2449 }
2450
2451 bool java_lang_VirtualThread::is_instance(oop obj) {
2452 return obj != nullptr && is_subclass(obj->klass());
2453 }
2454
2455 oop java_lang_VirtualThread::carrier_thread(oop vthread) {
2456 oop thread = vthread->obj_field(_carrierThread_offset);
2457 return thread;
2458 }
2459
2460 oop java_lang_VirtualThread::continuation(oop vthread) {
2461 oop cont = vthread->obj_field(_continuation_offset);
2491 bool java_lang_VirtualThread::set_onWaitingList(oop vthread, OopHandle& list_head) {
2492 jboolean* addr = vthread->field_addr<jboolean>(_onWaitingList_offset);
2493 jboolean vthread_on_list = Atomic::load(addr);
2494 if (!vthread_on_list) {
2495 vthread_on_list = Atomic::cmpxchg(addr, (jboolean)JNI_FALSE, (jboolean)JNI_TRUE);
2496 if (!vthread_on_list) {
2497 for (;;) {
2498 oop head = list_head.resolve();
2499 java_lang_VirtualThread::set_next(vthread, head);
2500 if (list_head.cmpxchg(head, vthread) == head) return true;
2501 }
2502 }
2503 }
2504 return false; // already on waiting list
2505 }
2506
2507 void java_lang_VirtualThread::set_notified(oop vthread, jboolean value) {
2508 vthread->bool_field_put_volatile(_notified_offset, value);
2509 }
2510
2511 void java_lang_VirtualThread::set_interruptible_wait(oop vthread, jboolean value) {
2512 vthread->bool_field_put_volatile(_interruptible_wait_offset, value);
2513 }
2514
2515 jlong java_lang_VirtualThread::timeout(oop vthread) {
2516 return vthread->long_field(_timeout_offset);
2517 }
2518
2519 void java_lang_VirtualThread::set_timeout(oop vthread, jlong value) {
2520 vthread->long_field_put(_timeout_offset, value);
2521 }
2522
2523 JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) {
2524 JavaThreadStatus status = JavaThreadStatus::NEW;
2525 switch (state & ~SUSPENDED) {
2526 case NEW:
2527 status = JavaThreadStatus::NEW;
2528 break;
2529 case STARTED:
2530 case RUNNING:
2531 case PARKING:
2532 case TIMED_PARKING:
2533 case UNPARKED:
2534 case YIELDING:
3709 LIVESTACKFRAMEINFO_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
3710 }
3711 #endif
3712
3713 void java_lang_LiveStackFrameInfo::set_monitors(oop obj, oop value) {
3714 obj->obj_field_put(_monitors_offset, value);
3715 }
3716
3717 void java_lang_LiveStackFrameInfo::set_locals(oop obj, oop value) {
3718 obj->obj_field_put(_locals_offset, value);
3719 }
3720
3721 void java_lang_LiveStackFrameInfo::set_operands(oop obj, oop value) {
3722 obj->obj_field_put(_operands_offset, value);
3723 }
3724
3725 void java_lang_LiveStackFrameInfo::set_mode(oop obj, int value) {
3726 obj->int_field_put(_mode_offset, value);
3727 }
3728
3729 // java_lang_AccessibleObject
3730
3731 int java_lang_reflect_AccessibleObject::_override_offset;
3732
3733 #define ACCESSIBLEOBJECT_FIELDS_DO(macro) \
3734 macro(_override_offset, k, "override", bool_signature, false)
3735
3736 void java_lang_reflect_AccessibleObject::compute_offsets() {
3737 InstanceKlass* k = vmClasses::reflect_AccessibleObject_klass();
3738 ACCESSIBLEOBJECT_FIELDS_DO(FIELD_COMPUTE_OFFSET);
3739 }
3740
3741 #if INCLUDE_CDS
3742 void java_lang_reflect_AccessibleObject::serialize_offsets(SerializeClosure* f) {
3743 ACCESSIBLEOBJECT_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
3744 }
3745 #endif
3746
3747 jboolean java_lang_reflect_AccessibleObject::override(oop reflect) {
3748 return (jboolean) reflect->bool_field(_override_offset);
|