< prev index next >

src/hotspot/share/services/threadService.cpp

Print this page

  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "classfile/javaClasses.inline.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "classfile/vmClasses.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "gc/shared/oopStorageSet.hpp"
  30 #include "memory/heapInspection.hpp"
  31 #include "memory/oopFactory.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "memory/universe.hpp"
  34 #include "nmt/memTag.hpp"
  35 #include "oops/instanceKlass.hpp"
  36 #include "oops/klass.inline.hpp"

  37 #include "oops/objArrayKlass.hpp"
  38 #include "oops/objArrayOop.inline.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "oops/oopHandle.inline.hpp"
  41 #include "prims/jvmtiRawMonitor.hpp"

  42 #include "runtime/atomic.hpp"
  43 #include "runtime/handles.inline.hpp"
  44 #include "runtime/init.hpp"

  45 #include "runtime/javaThread.inline.hpp"

  46 #include "runtime/objectMonitor.inline.hpp"
  47 #include "runtime/synchronizer.hpp"
  48 #include "runtime/thread.inline.hpp"
  49 #include "runtime/threads.hpp"
  50 #include "runtime/threadSMR.inline.hpp"
  51 #include "runtime/vframe.hpp"
  52 #include "runtime/vmThread.hpp"
  53 #include "runtime/vmOperations.hpp"
  54 #include "services/threadService.hpp"
  55 
  56 // TODO: we need to define a naming convention for perf counters
  57 // to distinguish counters for:
  58 //   - standard JSR174 use
  59 //   - Hotspot extension (public and committed)
  60 //   - Hotspot extension (private/internal and uncommitted)
  61 
  62 // Default is disabled.
  63 bool ThreadService::_thread_monitoring_contention_enabled = false;
  64 bool ThreadService::_thread_cpu_time_enabled = false;
  65 bool ThreadService::_thread_allocated_memory_enabled = false;
  66 
  67 PerfCounter*  ThreadService::_total_threads_count = nullptr;
  68 PerfVariable* ThreadService::_live_threads_count = nullptr;
  69 PerfVariable* ThreadService::_peak_threads_count = nullptr;
  70 PerfVariable* ThreadService::_daemon_threads_count = nullptr;
  71 volatile int ThreadService::_atomic_threads_count = 0;

1098 
1099     // skip agent threads
1100     if (!include_jvmti_agent_threads && jt->is_jvmti_agent_thread()) {
1101       continue;
1102     }
1103 
1104     // skip jni threads in the process of attaching
1105     if (!include_jni_attaching_threads && jt->is_attaching_via_jni()) {
1106       continue;
1107     }
1108 
1109     // skip instances of BoundVirtualThread
1110     if (!include_bound_virtual_threads && jt->threadObj()->is_a(vmClasses::BoundVirtualThread_klass())) {
1111       continue;
1112     }
1113 
1114     instanceHandle h(cur_thread, (instanceOop) jt->threadObj());
1115     _threads_array->append(h);
1116   }
1117 }













































































































































































































































































































































































































































  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "classfile/javaClasses.inline.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "classfile/vmClasses.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "gc/shared/oopStorageSet.hpp"
  30 #include "memory/heapInspection.hpp"
  31 #include "memory/oopFactory.hpp"
  32 #include "memory/resourceArea.hpp"
  33 #include "memory/universe.hpp"
  34 #include "nmt/memTag.hpp"
  35 #include "oops/instanceKlass.hpp"
  36 #include "oops/klass.inline.hpp"
  37 #include "oops/method.inline.hpp"
  38 #include "oops/objArrayKlass.hpp"
  39 #include "oops/objArrayOop.inline.hpp"
  40 #include "oops/oop.inline.hpp"
  41 #include "oops/oopHandle.inline.hpp"
  42 #include "prims/jvmtiRawMonitor.hpp"
  43 #include "prims/jvmtiThreadState.hpp"
  44 #include "runtime/atomic.hpp"
  45 #include "runtime/handles.inline.hpp"
  46 #include "runtime/init.hpp"
  47 #include "runtime/javaCalls.hpp"
  48 #include "runtime/javaThread.inline.hpp"
  49 #include "runtime/jniHandles.inline.hpp"
  50 #include "runtime/objectMonitor.inline.hpp"
  51 #include "runtime/synchronizer.inline.hpp"
  52 #include "runtime/thread.inline.hpp"
  53 #include "runtime/threads.hpp"
  54 #include "runtime/threadSMR.inline.hpp"
  55 #include "runtime/vframe.inline.hpp"
  56 #include "runtime/vmThread.hpp"
  57 #include "runtime/vmOperations.hpp"
  58 #include "services/threadService.hpp"
  59 
  60 // TODO: we need to define a naming convention for perf counters
  61 // to distinguish counters for:
  62 //   - standard JSR174 use
  63 //   - Hotspot extension (public and committed)
  64 //   - Hotspot extension (private/internal and uncommitted)
  65 
  66 // Default is disabled.
  67 bool ThreadService::_thread_monitoring_contention_enabled = false;
  68 bool ThreadService::_thread_cpu_time_enabled = false;
  69 bool ThreadService::_thread_allocated_memory_enabled = false;
  70 
  71 PerfCounter*  ThreadService::_total_threads_count = nullptr;
  72 PerfVariable* ThreadService::_live_threads_count = nullptr;
  73 PerfVariable* ThreadService::_peak_threads_count = nullptr;
  74 PerfVariable* ThreadService::_daemon_threads_count = nullptr;
  75 volatile int ThreadService::_atomic_threads_count = 0;

1102 
1103     // skip agent threads
1104     if (!include_jvmti_agent_threads && jt->is_jvmti_agent_thread()) {
1105       continue;
1106     }
1107 
1108     // skip jni threads in the process of attaching
1109     if (!include_jni_attaching_threads && jt->is_attaching_via_jni()) {
1110       continue;
1111     }
1112 
1113     // skip instances of BoundVirtualThread
1114     if (!include_bound_virtual_threads && jt->threadObj()->is_a(vmClasses::BoundVirtualThread_klass())) {
1115       continue;
1116     }
1117 
1118     instanceHandle h(cur_thread, (instanceOop) jt->threadObj());
1119     _threads_array->append(h);
1120   }
1121 }
1122 
1123 
1124 // jdk.internal.vm.ThreadSnapshot support
1125 #if INCLUDE_JVMTI
1126 
1127 class GetThreadSnapshotClosure: public HandshakeClosure {
1128 private:
1129   static OopStorage* oop_storage() {
1130     assert(_thread_service_storage != nullptr, "sanity");
1131     return _thread_service_storage;
1132   }
1133 
1134 public:
1135   struct OwnedLock {
1136     // should be synced with ordinals of jdk.internal.vm.ThreadSnapshot.OwnedLockType enum
1137     enum Type {
1138       NOTHING = -1,
1139       LOCKED = 0,
1140       ELIMINATED = 1,
1141     };
1142 
1143     int _frame_depth;
1144     Type _type;
1145     // synchronization object (when type == LOCKED) or its klass (type == ELIMINATED)
1146     OopHandle _obj;
1147 
1148     OwnedLock(int depth, Type type, OopHandle obj): _frame_depth(depth), _type(type), _obj(obj) {}
1149     OwnedLock(): _frame_depth(0), _type(NOTHING), _obj(nullptr) {}
1150   };
1151 
1152   struct Blocker {
1153     // should be synced with ordinals of jdk.internal.vm.ThreadSnapshot.BlockerLockType enum
1154     enum Type {
1155       NOTHING = -1,
1156       PARK_BLOCKER = 0,
1157       WAITING_TO_LOCK = 1,
1158       WAITING_ON = 2,
1159     };
1160 
1161     Type _type;
1162     // park blocker or an object the thread waiting on/trying to lock
1163     OopHandle _obj;
1164 
1165     Blocker(Type type, OopHandle obj): _type(type), _obj(obj) {}
1166     Blocker(): _type(NOTHING), _obj(nullptr) {}
1167 
1168     bool is_empty() const {
1169       return _type == NOTHING;
1170     }
1171   };
1172 
1173   Handle _thread_h;
1174   JavaThread* _java_thread;
1175   int _frame_count; // length of _methods and _bcis arrays
1176   GrowableArray<Method*>* _methods;
1177   GrowableArray<int>* _bcis;
1178   JavaThreadStatus _thread_status;
1179   OopHandle _thread_name;
1180   GrowableArray<OwnedLock>* _locks;
1181   Blocker _blocker;
1182 
1183   GetThreadSnapshotClosure(Handle thread_h, JavaThread* java_thread):
1184     HandshakeClosure("GetThreadSnapshotClosure"),
1185     _thread_h(thread_h), _java_thread(java_thread),
1186     _frame_count(0), _methods(nullptr), _bcis(nullptr),
1187     _thread_status(), _thread_name(nullptr),
1188     _locks(nullptr), _blocker() {
1189   }
1190   virtual ~GetThreadSnapshotClosure() {
1191     delete _methods;
1192     delete _bcis;
1193     _thread_name.release(oop_storage());
1194     if (_locks != nullptr) {
1195       for (int i = 0; i < _locks->length(); i++) {
1196         _locks->at(i)._obj.release(oop_storage());
1197       }
1198       delete _locks;
1199     }
1200     _blocker._obj.release(oop_storage());
1201   }
1202 
1203 private:
1204   void detect_locks(javaVFrame* jvf, int depth) {
1205     Thread* current = Thread::current();
1206 
1207     if (depth == 0 && _blocker.is_empty()) {
1208       // If this is the first frame and it is java.lang.Object.wait(...)
1209       // then print out the receiver.
1210       if (jvf->method()->name() == vmSymbols::wait_name() &&
1211         jvf->method()->method_holder()->name() == vmSymbols::java_lang_Object()) {
1212         OopHandle lock_object;
1213         StackValueCollection* locs = jvf->locals();
1214         if (!locs->is_empty()) {
1215           StackValue* sv = locs->at(0);
1216           if (sv->type() == T_OBJECT) {
1217             Handle o = locs->at(0)->get_obj();
1218             lock_object = OopHandle(oop_storage(), o());
1219           }
1220         }
1221         _blocker = Blocker(Blocker::WAITING_ON, lock_object);
1222       }
1223     }
1224 
1225     GrowableArray<MonitorInfo*>* mons = jvf->monitors();
1226     if (!mons->is_empty()) {
1227       for (int index = (mons->length() - 1); index >= 0; index--) {
1228         MonitorInfo* monitor = mons->at(index);
1229         if (monitor->eliminated() && jvf->is_compiled_frame()) { // Eliminated in compiled code
1230           if (monitor->owner_is_scalar_replaced()) {
1231             Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
1232             _locks->push(OwnedLock(depth, OwnedLock::ELIMINATED, OopHandle(oop_storage(), k->klass_holder())));
1233           } else {
1234             Handle owner(current, monitor->owner());
1235             if (owner.not_null()) {
1236               Klass* k = owner->klass();
1237               _locks->push(OwnedLock(depth, OwnedLock::ELIMINATED, OopHandle(oop_storage(), k->klass_holder())));
1238             }
1239           }
1240           continue;
1241         }
1242         if (monitor->owner() != nullptr) {
1243           // the monitor is associated with an object, i.e., it is locked
1244 
1245           if (depth == 0 && _blocker.is_empty()) {
1246             ObjectMonitor* pending_moninor = java_lang_VirtualThread::is_instance(_thread_h())
1247               ? java_lang_VirtualThread::current_pending_monitor(_thread_h())
1248               : jvf->thread()->current_pending_monitor();
1249 
1250             markWord mark = monitor->owner()->mark();
1251             // The first stage of async deflation does not affect any field
1252             // used by this comparison so the ObjectMonitor* is usable here.
1253             if (mark.has_monitor()) {
1254               ObjectMonitor* mon = ObjectSynchronizer::read_monitor(current, monitor->owner(), mark);
1255               if (// if the monitor is null we must be in the process of locking
1256                   mon == nullptr ||
1257                   // we have marked ourself as pending on this monitor
1258                   mon == pending_moninor ||
1259                   // we are not the owner of this monitor
1260                   (_java_thread != nullptr && !mon->is_entered(_java_thread))) {
1261                 _blocker = Blocker(Blocker::WAITING_TO_LOCK, OopHandle(oop_storage(), monitor->owner()));
1262                 continue; // go to next monitor
1263               }
1264             }
1265           }
1266           _locks->push(OwnedLock(depth, OwnedLock::LOCKED, OopHandle(oop_storage(), monitor->owner())));
1267         }
1268       }
1269     }
1270   }
1271 
1272 public:
1273   void do_thread(Thread* th) override {
1274     Thread* current = Thread::current();
1275 
1276     bool is_virtual = java_lang_VirtualThread::is_instance(_thread_h());
1277     if (_java_thread != nullptr) {
1278       if (is_virtual) {
1279         // mounted vthread, use carrier thread state
1280         oop carrier_thread = java_lang_VirtualThread::carrier_thread(_thread_h());
1281         _thread_status = java_lang_Thread::get_thread_status(carrier_thread);
1282       } else {
1283         _thread_status = java_lang_Thread::get_thread_status(_thread_h());
1284       }
1285     } else {
1286       // unmounted vthread
1287       int vt_state = java_lang_VirtualThread::state(_thread_h());
1288       _thread_status = java_lang_VirtualThread::map_state_to_thread_status(vt_state);
1289     }
1290     _thread_name = OopHandle(oop_storage(), java_lang_Thread::name(_thread_h()));
1291 
1292     if (_java_thread != nullptr && !_java_thread->has_last_Java_frame()) {
1293       // stack trace is empty
1294       return;
1295     }
1296 
1297     bool vthread_carrier = !is_virtual && (_java_thread != nullptr) && (_java_thread->vthread_continuation() != nullptr);
1298 
1299     oop park_blocker = java_lang_Thread::park_blocker(_thread_h());
1300     if (park_blocker != nullptr) {
1301       _blocker = Blocker(Blocker::PARK_BLOCKER, OopHandle(oop_storage(), park_blocker));
1302     }
1303 
1304     ResourceMark rm(current);
1305     HandleMark hm(current);
1306 
1307     const int max_depth = MaxJavaStackTraceDepth;
1308     const bool skip_hidden = !ShowHiddenFrames;
1309 
1310     // Pick minimum length that will cover most cases
1311     int init_length = 64;
1312     _methods = new (mtInternal) GrowableArray<Method*>(init_length, mtInternal);
1313     _bcis = new (mtInternal) GrowableArray<int>(init_length, mtInternal);
1314     _locks = new (mtInternal) GrowableArray<OwnedLock>(init_length, mtInternal);
1315     int total_count = 0;
1316 
1317     vframeStream vfst(_java_thread != nullptr
1318       ? vframeStream(_java_thread, false, true, vthread_carrier)
1319       : vframeStream(java_lang_VirtualThread::continuation(_thread_h())));
1320 
1321     for (;
1322       !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
1323       vfst.next()) {
1324 
1325       detect_locks(vfst.asJavaVFrame(), total_count);
1326 
1327       if (skip_hidden && (vfst.method()->is_hidden() ||
1328         vfst.method()->is_continuation_enter_intrinsic())) {
1329         continue;
1330       }
1331       _methods->push(vfst.method());
1332       _bcis->push(vfst.bci());
1333       total_count++;
1334     }
1335 
1336     _frame_count = total_count;
1337   }
1338 };
1339 
1340 class jdk_internal_vm_ThreadLock: AllStatic {
1341   static bool _inited;
1342   static int _depth_offset;
1343   static int _typeOrdinal_offset;
1344   static int _obj_offset;
1345 
1346   static void compute_offsets(InstanceKlass* klass, TRAPS) {
1347     JavaClasses::compute_offset(_depth_offset, klass, "depth", vmSymbols::int_signature(), false);
1348     JavaClasses::compute_offset(_typeOrdinal_offset, klass, "typeOrdinal", vmSymbols::int_signature(), false);
1349     JavaClasses::compute_offset(_obj_offset, klass, "obj", vmSymbols::object_signature(), false);
1350   }
1351 public:
1352   static void init(InstanceKlass* klass, TRAPS) {
1353     if (!_inited) {
1354       compute_offsets(klass, CHECK);
1355       _inited = true;
1356     }
1357   }
1358 
1359   static Handle create(InstanceKlass* klass, int depth, int type_ordinal, OopHandle obj, TRAPS) {
1360     init(klass, CHECK_NH);
1361     Handle result = klass->allocate_instance_handle(CHECK_NH);
1362     result->int_field_put(_depth_offset, depth);
1363     result->int_field_put(_typeOrdinal_offset, type_ordinal);
1364     result->obj_field_put(_obj_offset, obj.resolve());
1365     return result;
1366   }
1367 };
1368 
1369 bool jdk_internal_vm_ThreadLock::_inited = false;
1370 int jdk_internal_vm_ThreadLock::_depth_offset;
1371 int jdk_internal_vm_ThreadLock::_typeOrdinal_offset;
1372 int jdk_internal_vm_ThreadLock::_obj_offset;
1373 
1374 class jdk_internal_vm_ThreadSnapshot: AllStatic {
1375   static bool _inited;
1376   static int _name_offset;
1377   static int _threadStatus_offset;
1378   static int _carrierThread_offset;
1379   static int _stackTrace_offset;
1380   static int _locks_offset;
1381   static int _blockerTypeOrdinal_offset;
1382   static int _blockerObject_offset;
1383 
1384   static void compute_offsets(InstanceKlass* klass, TRAPS) {
1385     JavaClasses::compute_offset(_name_offset, klass, "name", vmSymbols::string_signature(), false);
1386     JavaClasses::compute_offset(_threadStatus_offset, klass, "threadStatus", vmSymbols::int_signature(), false);
1387     JavaClasses::compute_offset(_carrierThread_offset, klass, "carrierThread", vmSymbols::thread_signature(), false);
1388     JavaClasses::compute_offset(_stackTrace_offset, klass, "stackTrace", vmSymbols::java_lang_StackTraceElement_array(), false);
1389     JavaClasses::compute_offset(_locks_offset, klass, "locks", vmSymbols::jdk_internal_vm_ThreadLock_array(), false);
1390     JavaClasses::compute_offset(_blockerTypeOrdinal_offset, klass, "blockerTypeOrdinal", vmSymbols::int_signature(), false);
1391     JavaClasses::compute_offset(_blockerObject_offset, klass, "blockerObject", vmSymbols::object_signature(), false);
1392   }
1393 public:
1394   static void init(InstanceKlass* klass, TRAPS) {
1395     if (!_inited) {
1396       compute_offsets(klass, CHECK);
1397       _inited = true;
1398     }
1399   }
1400 
1401   static Handle allocate(InstanceKlass* klass, TRAPS) {
1402     init(klass, CHECK_NH);
1403     Handle h_k = klass->allocate_instance_handle(CHECK_NH);
1404     return h_k;
1405   }
1406 
1407   static void set_name(oop snapshot, oop name) {
1408     snapshot->obj_field_put(_name_offset, name);
1409   }
1410   static void set_thread_status(oop snapshot, int status) {
1411     snapshot->int_field_put(_threadStatus_offset, status);
1412   }
1413   static void set_carrier_thread(oop snapshot, oop carrier_thread) {
1414     snapshot->obj_field_put(_carrierThread_offset, carrier_thread);
1415   }
1416   static void set_stack_trace(oop snapshot, oop trace) {
1417     snapshot->obj_field_put(_stackTrace_offset, trace);
1418   }
1419   static void set_locks(oop snapshot, oop locks) {
1420     snapshot->obj_field_put(_locks_offset, locks);
1421   }
1422   static void set_blocker(oop snapshot, int type_ordinal, oop lock) {
1423     snapshot->int_field_put(_blockerTypeOrdinal_offset, type_ordinal);
1424     snapshot->obj_field_put(_blockerObject_offset, lock);
1425   }
1426 };
1427 
1428 bool jdk_internal_vm_ThreadSnapshot::_inited = false;
1429 int jdk_internal_vm_ThreadSnapshot::_name_offset;
1430 int jdk_internal_vm_ThreadSnapshot::_threadStatus_offset;
1431 int jdk_internal_vm_ThreadSnapshot::_carrierThread_offset;
1432 int jdk_internal_vm_ThreadSnapshot::_stackTrace_offset;
1433 int jdk_internal_vm_ThreadSnapshot::_locks_offset;
1434 int jdk_internal_vm_ThreadSnapshot::_blockerTypeOrdinal_offset;
1435 int jdk_internal_vm_ThreadSnapshot::_blockerObject_offset;
1436 
1437 oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
1438   ThreadsListHandle tlh(THREAD);
1439 
1440   ResourceMark rm(THREAD);
1441   HandleMark   hm(THREAD);
1442   Handle thread_h(THREAD, JNIHandles::resolve(jthread));
1443 
1444   // wrapper to auto delete JvmtiVTMSTransitionDisabler
1445   class TransitionDisabler {
1446     JvmtiVTMSTransitionDisabler* _transition_disabler;
1447   public:
1448     TransitionDisabler(): _transition_disabler(nullptr) {}
1449     ~TransitionDisabler() {
1450       reset();
1451     }
1452     void init(jobject jthread) {
1453       _transition_disabler = new (mtInternal) JvmtiVTMSTransitionDisabler(jthread);
1454     }
1455     void reset() {
1456       if (_transition_disabler != nullptr) {
1457         delete _transition_disabler;
1458         _transition_disabler = nullptr;
1459       }
1460     }
1461   } transition_disabler;
1462 
1463   JavaThread* java_thread = nullptr;
1464   bool is_virtual = java_lang_VirtualThread::is_instance(thread_h());
1465   Handle carrier_thread;
1466   if (is_virtual) {
1467     // 1st need to disable mount/unmount transitions
1468     transition_disabler.init(jthread);
1469 
1470     carrier_thread = Handle(THREAD, java_lang_VirtualThread::carrier_thread(thread_h()));
1471     if (carrier_thread != nullptr) {
1472       java_thread = java_lang_Thread::thread(carrier_thread());
1473     }
1474   } else {
1475     java_thread = java_lang_Thread::thread(thread_h());
1476   }
1477 
1478   // Handshake with target
1479   GetThreadSnapshotClosure cl(thread_h, java_thread);
1480   if (java_thread == nullptr) {
1481     // unmounted vthread, execute on the current thread
1482     cl.do_thread(nullptr);
1483   } else {
1484     Handshake::execute(&cl, &tlh, java_thread);
1485   }
1486 
1487   // all info is collected, can enable transitions.
1488   transition_disabler.reset();
1489 
1490   // StackTrace
1491   InstanceKlass* ste_klass = vmClasses::StackTraceElement_klass();
1492   assert(ste_klass != nullptr, "must be loaded");
1493 
1494   objArrayHandle trace = oopFactory::new_objArray_handle(ste_klass, cl._frame_count, CHECK_NULL);
1495 
1496   for (int i = 0; i < cl._frame_count; i++) {
1497     methodHandle method(THREAD, cl._methods->at(i));
1498     oop element = java_lang_StackTraceElement::create(method, cl._bcis->at(i), CHECK_NULL);
1499     trace->obj_at_put(i, element);
1500   }
1501 
1502   // Locks
1503   Symbol* lock_sym = vmSymbols::jdk_internal_vm_ThreadLock();
1504   Klass* lock_k = SystemDictionary::resolve_or_fail(lock_sym, true, CHECK_NULL);
1505   InstanceKlass* lock_klass = InstanceKlass::cast(lock_k);
1506 
1507   objArrayHandle locks;
1508   if (cl._locks != nullptr && cl._locks->length() > 0) {
1509     locks = oopFactory::new_objArray_handle(lock_klass, cl._locks->length(), CHECK_NULL);
1510     for (int n = 0; n < cl._locks->length(); n++) {
1511       GetThreadSnapshotClosure::OwnedLock* lock_info = cl._locks->adr_at(n);
1512 
1513       Handle lock = jdk_internal_vm_ThreadLock::create(lock_klass,
1514         lock_info->_frame_depth, lock_info->_type, lock_info->_obj, CHECK_NULL);
1515       locks->obj_at_put(n, lock());
1516     }
1517   }
1518 
1519   // call static StackTraceElement[] StackTraceElement.of(StackTraceElement[] stackTrace)
1520   // to properly initialize STEs.
1521   JavaValue result(T_OBJECT);
1522   JavaCalls::call_static(&result,
1523     ste_klass,
1524     vmSymbols::java_lang_StackTraceElement_of_name(),
1525     vmSymbols::java_lang_StackTraceElement_of_signature(),
1526     trace,
1527     CHECK_NULL);
1528   // the method return the same trace array
1529 
1530   Symbol* snapshot_klass_name = vmSymbols::jdk_internal_vm_ThreadSnapshot();
1531   Klass* snapshot_klass = SystemDictionary::resolve_or_fail(snapshot_klass_name, true, CHECK_NULL);
1532   if (snapshot_klass->should_be_initialized()) {
1533     snapshot_klass->initialize(CHECK_NULL);
1534   }
1535 
1536   Handle snapshot = jdk_internal_vm_ThreadSnapshot::allocate(InstanceKlass::cast(snapshot_klass), CHECK_NULL);
1537   jdk_internal_vm_ThreadSnapshot::set_name(snapshot(), cl._thread_name.resolve());
1538   jdk_internal_vm_ThreadSnapshot::set_thread_status(snapshot(), (int)cl._thread_status);
1539   jdk_internal_vm_ThreadSnapshot::set_carrier_thread(snapshot(), carrier_thread());
1540   jdk_internal_vm_ThreadSnapshot::set_stack_trace(snapshot(), trace());
1541   jdk_internal_vm_ThreadSnapshot::set_locks(snapshot(), locks());
1542   if (!cl._blocker.is_empty()) {
1543     jdk_internal_vm_ThreadSnapshot::set_blocker(snapshot(), cl._blocker._type, cl._blocker._obj.resolve());
1544   }
1545   return snapshot();
1546 }
1547 
1548 #endif // INCLUDE_JVMTI
1549 
< prev index next >