< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page

1887 
1888 // Read thread status value from threadStatus field in java.lang.Thread java class.
1889 JavaThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
1890   // Make sure the caller is operating on behalf of the VM or is
1891   // running VM code (state == _thread_in_vm).
1892   assert(Threads_lock->owned_by_self() || Thread::current()->is_VM_thread() ||
1893          JavaThread::current()->thread_state() == _thread_in_vm ||
1894          JavaThread::current() == java_lang_Thread::thread(java_thread),
1895          "unsafe call to java_lang_Thread::get_thread_status()?");
1896   GET_FIELDHOLDER_FIELD(java_thread, get_thread_status, JavaThreadStatus::NEW /* not initialized */);
1897 }
1898 
1899 ByteSize java_lang_Thread::thread_id_offset() {
1900   return in_ByteSize(_tid_offset);
1901 }
1902 
1903 oop java_lang_Thread::park_blocker(oop java_thread) {
1904   return java_thread->obj_field_access<MO_RELAXED>(_park_blocker_offset);
1905 }
1906 
1907 // Obtain stack trace for platform or mounted virtual thread.
1908 // If jthread is a virtual thread and it has been unmounted (or remounted to different carrier) the method returns null.
1909 // The caller (java.lang.VirtualThread) handles returned nulls via retry.
1910 oop java_lang_Thread::async_get_stack_trace(jobject jthread, TRAPS) {
1911   ThreadsListHandle tlh(THREAD);
1912   JavaThread* java_thread = nullptr;
1913   oop thread_oop;
1914 
1915   bool has_java_thread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
1916   if (!has_java_thread) {


1917     return nullptr;
1918   }
1919 
1920   class GetStackTraceHandshakeClosure : public HandshakeClosure {
1921   public:
1922     const Handle _thread_h;
1923     int _depth;
1924     bool _retry_handshake;
1925     GrowableArray<Method*>* _methods;
1926     GrowableArray<int>*     _bcis;
1927 
1928     GetStackTraceHandshakeClosure(Handle thread_h) :
1929         HandshakeClosure("GetStackTraceHandshakeClosure"), _thread_h(thread_h), _depth(0), _retry_handshake(false),
1930         _methods(nullptr), _bcis(nullptr) {
1931     }
1932     ~GetStackTraceHandshakeClosure() {
1933       delete _methods;
1934       delete _bcis;
1935     }
1936 
1937     bool read_reset_retry() {
1938       bool ret = _retry_handshake;
1939       // If we re-execute the handshake this method need to return false
1940       // when the handshake cannot be performed. (E.g. thread terminating)
1941       _retry_handshake = false;
1942       return ret;
1943     }
1944 
1945     void do_thread(Thread* th) {
1946       if (!Thread::current()->is_Java_thread()) {
1947         _retry_handshake = true;

1948         return;
1949       }
1950 
1951       JavaThread* java_thread = JavaThread::cast(th);
1952 
1953       if (!java_thread->has_last_Java_frame()) {
1954         return;
1955       }
1956 
1957       bool carrier = false;
1958       if (java_lang_VirtualThread::is_instance(_thread_h())) {
1959         // Ensure _thread_h is still mounted to java_thread.
1960         const ContinuationEntry* ce = java_thread->vthread_continuation();
1961         if (ce == nullptr || ce->cont_oop(java_thread) != java_lang_VirtualThread::continuation(_thread_h())) {
1962           // Target thread has been unmounted.
1963           return;
1964         }
1965       } else {
1966         carrier = (java_thread->vthread_continuation() != nullptr);
1967       }
1968 
1969       const int max_depth = MaxJavaStackTraceDepth;
1970       const bool skip_hidden = !ShowHiddenFrames;
1971 
1972       // Pick minimum length that will cover most cases
1973       int init_length = 64;
1974       _methods = new (mtInternal) GrowableArray<Method*>(init_length, mtInternal);
1975       _bcis = new (mtInternal) GrowableArray<int>(init_length, mtInternal);
1976 
1977       int total_count = 0;
1978       for (vframeStream vfst(java_thread, false, false, carrier); // we don't process frames as we don't care about oops



1979            !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
1980            vfst.next()) {
1981 
1982         if (skip_hidden && (vfst.method()->is_hidden() ||
1983                             vfst.method()->is_continuation_enter_intrinsic())) {
1984           continue;
1985         }
1986 
1987         _methods->push(vfst.method());
1988         _bcis->push(vfst.bci());
1989         total_count++;
1990       }
1991 
1992       _depth = total_count;
1993     }
1994   };
1995 
1996   // Handshake with target
1997   ResourceMark rm(THREAD);
1998   HandleMark   hm(THREAD);
1999   GetStackTraceHandshakeClosure gsthc(Handle(THREAD, thread_oop));
2000   do {
2001    Handshake::execute(&gsthc, &tlh, java_thread);
2002   } while (gsthc.read_reset_retry());


2003 
2004   // Stop if no stack trace is found.
2005   if (gsthc._depth == 0) {
2006     return nullptr;
2007   }
2008 
2009   // Convert to StackTraceElement array
2010   InstanceKlass* k = vmClasses::StackTraceElement_klass();
2011   assert(k != nullptr, "must be loaded in 1.4+");
2012   if (k->should_be_initialized()) {
2013     k->initialize(CHECK_NULL);
2014   }
2015   objArrayHandle trace = oopFactory::new_objArray_handle(k, gsthc._depth, CHECK_NULL);
2016 
2017   for (int i = 0; i < gsthc._depth; i++) {
2018     methodHandle method(THREAD, gsthc._methods->at(i));
2019     oop element = java_lang_StackTraceElement::create(method,
2020                                                       gsthc._bcis->at(i),
2021                                                       CHECK_NULL);
2022     trace->obj_at_put(i, element);

2179 }
2180 
2181 void java_lang_VirtualThread::set_notified(oop vthread, jboolean value) {
2182   vthread->bool_field_put_volatile(_notified_offset, value);
2183 }
2184 
2185 void java_lang_VirtualThread::set_interruptible_wait(oop vthread, jboolean value) {
2186   vthread->bool_field_put_volatile(_interruptible_wait_offset, value);
2187 }
2188 
2189 jlong java_lang_VirtualThread::timeout(oop vthread) {
2190   return vthread->long_field(_timeout_offset);
2191 }
2192 
2193 void java_lang_VirtualThread::set_timeout(oop vthread, jlong value) {
2194   vthread->long_field_put(_timeout_offset, value);
2195 }
2196 
2197 JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) {
2198   JavaThreadStatus status = JavaThreadStatus::NEW;
2199   switch (state & ~SUSPENDED) {
2200     case NEW:
2201       status = JavaThreadStatus::NEW;
2202       break;
2203     case STARTED:
2204     case RUNNING:
2205     case PARKING:
2206     case TIMED_PARKING:
2207     case UNPARKED:
2208     case YIELDING:
2209     case YIELDED:
2210     case UNBLOCKED:
2211     case WAITING:
2212     case TIMED_WAITING:
2213       status = JavaThreadStatus::RUNNABLE;
2214       break;
2215     case PARKED:
2216     case PINNED:
2217       status = JavaThreadStatus::PARKED;
2218       break;
2219     case TIMED_PARKED:

1887 
1888 // Read thread status value from threadStatus field in java.lang.Thread java class.
1889 JavaThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
1890   // Make sure the caller is operating on behalf of the VM or is
1891   // running VM code (state == _thread_in_vm).
1892   assert(Threads_lock->owned_by_self() || Thread::current()->is_VM_thread() ||
1893          JavaThread::current()->thread_state() == _thread_in_vm ||
1894          JavaThread::current() == java_lang_Thread::thread(java_thread),
1895          "unsafe call to java_lang_Thread::get_thread_status()?");
1896   GET_FIELDHOLDER_FIELD(java_thread, get_thread_status, JavaThreadStatus::NEW /* not initialized */);
1897 }
1898 
1899 ByteSize java_lang_Thread::thread_id_offset() {
1900   return in_ByteSize(_tid_offset);
1901 }
1902 
1903 oop java_lang_Thread::park_blocker(oop java_thread) {
1904   return java_thread->obj_field_access<MO_RELAXED>(_park_blocker_offset);
1905 }
1906 
1907 // Obtain stack trace for a platform of virtual thread.


1908 oop java_lang_Thread::async_get_stack_trace(jobject jthread, TRAPS) {
1909   ThreadsListHandle tlh(THREAD);
1910   JavaThread* java_thread = nullptr;
1911   oop thread_oop;
1912 
1913   bool has_java_thread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
1914   assert((has_java_thread && thread_oop != nullptr) || !has_java_thread, "Missing Thread oop");
1915   bool is_virtual = java_lang_VirtualThread::is_instance(thread_oop);
1916   if (!has_java_thread && !is_virtual) {
1917     return nullptr;
1918   }
1919 
1920   class GetStackTraceHandshakeClosure : public HandshakeClosure {
1921   public:
1922     const Handle _thread_h;
1923     int _depth;

1924     GrowableArray<Method*>* _methods;
1925     GrowableArray<int>*     _bcis;
1926 
1927     GetStackTraceHandshakeClosure(Handle thread_h) :
1928         HandshakeClosure("GetStackTraceHandshakeClosure"), _thread_h(thread_h), _depth(0),
1929         _methods(nullptr), _bcis(nullptr) {
1930     }
1931     ~GetStackTraceHandshakeClosure() {
1932       delete _methods;
1933       delete _bcis;
1934     }
1935 








1936     void do_thread(Thread* th) {
1937       JavaThread* java_thread = th != nullptr ? JavaThread::cast(th) : nullptr;
1938       if (java_thread != nullptr && !java_thread->has_last_Java_frame()) {
1939         // stack trace is empty
1940         return;
1941       }
1942 
1943       bool is_virtual = java_lang_VirtualThread::is_instance(_thread_h());
1944       bool vthread_carrier = !is_virtual && (java_thread != nullptr) && (java_thread->vthread_continuation() != nullptr);















1945 
1946       const int max_depth = MaxJavaStackTraceDepth;
1947       const bool skip_hidden = !ShowHiddenFrames;
1948 
1949       // Pick minimum length that will cover most cases
1950       int init_length = 64;
1951       _methods = new (mtInternal) GrowableArray<Method*>(init_length, mtInternal);
1952       _bcis = new (mtInternal) GrowableArray<int>(init_length, mtInternal);
1953 
1954       int total_count = 0;
1955       vframeStream vfst(java_thread != nullptr
1956         ? vframeStream(java_thread, false, false, vthread_carrier)  // we don't process frames as we don't care about oops
1957         : vframeStream(java_lang_VirtualThread::continuation(_thread_h())));
1958       for (;
1959            !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
1960            vfst.next()) {
1961 
1962         if (skip_hidden && (vfst.method()->is_hidden() ||
1963                             vfst.method()->is_continuation_enter_intrinsic())) {
1964           continue;
1965         }
1966 
1967         _methods->push(vfst.method());
1968         _bcis->push(vfst.bci());
1969         total_count++;
1970       }
1971 
1972       _depth = total_count;
1973     }
1974   };
1975 
1976   // Handshake with target
1977   ResourceMark rm(THREAD);
1978   HandleMark   hm(THREAD);
1979   GetStackTraceHandshakeClosure gsthc(Handle(THREAD, thread_oop));
1980   if (is_virtual) {
1981     Handshake::execute(&gsthc, thread_oop);
1982   } else {
1983     Handshake::execute(&gsthc, &tlh, java_thread);
1984   }
1985 
1986   // Stop if no stack trace is found.
1987   if (gsthc._depth == 0) {
1988     return nullptr;
1989   }
1990 
1991   // Convert to StackTraceElement array
1992   InstanceKlass* k = vmClasses::StackTraceElement_klass();
1993   assert(k != nullptr, "must be loaded in 1.4+");
1994   if (k->should_be_initialized()) {
1995     k->initialize(CHECK_NULL);
1996   }
1997   objArrayHandle trace = oopFactory::new_objArray_handle(k, gsthc._depth, CHECK_NULL);
1998 
1999   for (int i = 0; i < gsthc._depth; i++) {
2000     methodHandle method(THREAD, gsthc._methods->at(i));
2001     oop element = java_lang_StackTraceElement::create(method,
2002                                                       gsthc._bcis->at(i),
2003                                                       CHECK_NULL);
2004     trace->obj_at_put(i, element);

2161 }
2162 
2163 void java_lang_VirtualThread::set_notified(oop vthread, jboolean value) {
2164   vthread->bool_field_put_volatile(_notified_offset, value);
2165 }
2166 
2167 void java_lang_VirtualThread::set_interruptible_wait(oop vthread, jboolean value) {
2168   vthread->bool_field_put_volatile(_interruptible_wait_offset, value);
2169 }
2170 
2171 jlong java_lang_VirtualThread::timeout(oop vthread) {
2172   return vthread->long_field(_timeout_offset);
2173 }
2174 
2175 void java_lang_VirtualThread::set_timeout(oop vthread, jlong value) {
2176   vthread->long_field_put(_timeout_offset, value);
2177 }
2178 
2179 JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) {
2180   JavaThreadStatus status = JavaThreadStatus::NEW;
2181   switch (state) {
2182     case NEW:
2183       status = JavaThreadStatus::NEW;
2184       break;
2185     case STARTED:
2186     case RUNNING:
2187     case PARKING:
2188     case TIMED_PARKING:
2189     case UNPARKED:
2190     case YIELDING:
2191     case YIELDED:
2192     case UNBLOCKED:
2193     case WAITING:
2194     case TIMED_WAITING:
2195       status = JavaThreadStatus::RUNNABLE;
2196       break;
2197     case PARKED:
2198     case PINNED:
2199       status = JavaThreadStatus::PARKED;
2200       break;
2201     case TIMED_PARKED:
< prev index next >