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 GetThreadSnapshotHandshakeClosure(Handle thread_h, JavaThread* java_thread):
1184 HandshakeClosure("GetThreadSnapshotHandshakeClosure"),
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 ~GetThreadSnapshotHandshakeClosure() {
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();
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 assert(carrier_thread != nullptr, "should only get here for a mounted vthread");
1282 _thread_status = java_lang_Thread::get_thread_status(carrier_thread);
1283 } else {
1284 _thread_status = java_lang_Thread::get_thread_status(_thread_h());
1285 }
1286 } else {
1287 // unmounted vthread
1288 int vt_state = java_lang_VirtualThread::state(_thread_h());
1289 _thread_status = java_lang_VirtualThread::map_state_to_thread_status(vt_state);
1290 }
1291 _thread_name = OopHandle(oop_storage(), java_lang_Thread::name(_thread_h()));
1292
1293 if (_java_thread != nullptr && !_java_thread->has_last_Java_frame()) {
1294 // stack trace is empty
1295 return;
1296 }
1297
1298 bool vthread_carrier = !is_virtual && (_java_thread != nullptr) && (_java_thread->vthread_continuation() != nullptr);
1299
1300 oop park_blocker = java_lang_Thread::park_blocker(_thread_h());
1301 if (park_blocker != nullptr) {
1302 _blocker = Blocker(Blocker::PARK_BLOCKER, OopHandle(oop_storage(), park_blocker));
1303 }
1304
1305 ResourceMark rm(current);
1306 HandleMark hm(current);
1307
1308 const int max_depth = MaxJavaStackTraceDepth;
1309 const bool skip_hidden = !ShowHiddenFrames;
1310
1318 vframeStream vfst(_java_thread != nullptr
1319 ? vframeStream(_java_thread, false, true, vthread_carrier)
1320 : vframeStream(java_lang_VirtualThread::continuation(_thread_h())));
1321
1322 for (;
1323 !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
1324 vfst.next()) {
1325
1326 detect_locks(vfst.asJavaVFrame(), total_count);
1327
1328 if (skip_hidden && (vfst.method()->is_hidden() ||
1329 vfst.method()->is_continuation_enter_intrinsic())) {
1330 continue;
1331 }
1332 _methods->push(vfst.method());
1333 _bcis->push(vfst.bci());
1334 total_count++;
1335 }
1336
1337 _frame_count = total_count;
1338 }
1339 };
1340
1341 class jdk_internal_vm_ThreadLock: AllStatic {
1342 static bool _inited;
1343 static int _depth_offset;
1344 static int _typeOrdinal_offset;
1345 static int _obj_offset;
1346
1347 static void compute_offsets(InstanceKlass* klass, TRAPS) {
1348 JavaClasses::compute_offset(_depth_offset, klass, "depth", vmSymbols::int_signature(), false);
1349 JavaClasses::compute_offset(_typeOrdinal_offset, klass, "typeOrdinal", vmSymbols::int_signature(), false);
1350 JavaClasses::compute_offset(_obj_offset, klass, "obj", vmSymbols::object_signature(), false);
1351 }
1352 public:
1353 static void init(InstanceKlass* klass, TRAPS) {
1354 if (!_inited) {
1355 compute_offsets(klass, CHECK);
1356 _inited = true;
1357 }
1418 snapshot->obj_field_put(_stackTrace_offset, trace);
1419 }
1420 static void set_locks(oop snapshot, oop locks) {
1421 snapshot->obj_field_put(_locks_offset, locks);
1422 }
1423 static void set_blocker(oop snapshot, int type_ordinal, oop lock) {
1424 snapshot->int_field_put(_blockerTypeOrdinal_offset, type_ordinal);
1425 snapshot->obj_field_put(_blockerObject_offset, lock);
1426 }
1427 };
1428
1429 bool jdk_internal_vm_ThreadSnapshot::_inited = false;
1430 int jdk_internal_vm_ThreadSnapshot::_name_offset;
1431 int jdk_internal_vm_ThreadSnapshot::_threadStatus_offset;
1432 int jdk_internal_vm_ThreadSnapshot::_carrierThread_offset;
1433 int jdk_internal_vm_ThreadSnapshot::_stackTrace_offset;
1434 int jdk_internal_vm_ThreadSnapshot::_locks_offset;
1435 int jdk_internal_vm_ThreadSnapshot::_blockerTypeOrdinal_offset;
1436 int jdk_internal_vm_ThreadSnapshot::_blockerObject_offset;
1437
1438 oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
1439 ThreadsListHandle tlh(THREAD);
1440
1441 ResourceMark rm(THREAD);
1442 HandleMark hm(THREAD);
1443
1444 JavaThread* java_thread = nullptr;
1445 oop thread_oop;
1446 bool has_javathread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
1447 assert((has_javathread && thread_oop != nullptr) || !has_javathread, "Missing Thread oop");
1448 Handle thread_h(THREAD, thread_oop);
1449 bool is_virtual = java_lang_VirtualThread::is_instance(thread_h()); // Deals with null
1450
1451 if (!has_javathread && !is_virtual) {
1452 return nullptr; // thread terminated so not of interest
1453 }
1454
1455 // wrapper to auto delete JvmtiVTMSTransitionDisabler
1456 class TransitionDisabler {
1457 JvmtiVTMSTransitionDisabler* _transition_disabler;
1458 public:
1459 TransitionDisabler(): _transition_disabler(nullptr) {}
1460 ~TransitionDisabler() {
1461 reset();
1462 }
1463 void init(jobject jthread) {
1464 _transition_disabler = new (mtInternal) JvmtiVTMSTransitionDisabler(jthread);
1465 }
1466 void reset() {
1467 if (_transition_disabler != nullptr) {
1468 delete _transition_disabler;
1469 _transition_disabler = nullptr;
1470 }
1471 }
1472 } transition_disabler;
1473
1474 Handle carrier_thread;
1475 if (is_virtual) {
1476 // 1st need to disable mount/unmount transitions
1477 transition_disabler.init(jthread);
1478
1479 carrier_thread = Handle(THREAD, java_lang_VirtualThread::carrier_thread(thread_h()));
1480 if (carrier_thread != nullptr) {
1481 // Note: The java_thread associated with this carrier_thread may not be
1482 // protected by the ThreadsListHandle above. There could have been an
1483 // unmount and remount after the ThreadsListHandle above was created
1484 // and before the JvmtiVTMSTransitionDisabler was created. However, as
1485 // we have disabled transitions, if we are mounted on it, then it cannot
1486 // terminate and so is safe to handshake with.
1487 java_thread = java_lang_Thread::thread(carrier_thread());
1488 } else {
1489 // We may have previously found a carrier but the virtual thread has unmounted
1490 // after that, so clear that previous reference.
1491 java_thread = nullptr;
1492 }
1493 } else {
1494 java_thread = java_lang_Thread::thread(thread_h());
1495 }
1496
1497 // Handshake with target
1498 GetThreadSnapshotHandshakeClosure cl(thread_h, java_thread);
1499 if (java_thread == nullptr) {
1500 // unmounted vthread, execute on the current thread
1501 cl.do_thread(nullptr);
1502 } else {
1503 Handshake::execute(&cl, &tlh, java_thread);
1504 }
1505
1506 // all info is collected, can enable transitions.
1507 transition_disabler.reset();
1508
1509 // StackTrace
1510 InstanceKlass* ste_klass = vmClasses::StackTraceElement_klass();
1511 assert(ste_klass != nullptr, "must be loaded");
1512
1513 objArrayHandle trace = oopFactory::new_objArray_handle(ste_klass, cl._frame_count, CHECK_NULL);
1514
1515 for (int i = 0; i < cl._frame_count; i++) {
1516 methodHandle method(THREAD, cl._methods->at(i));
1517 oop element = java_lang_StackTraceElement::create(method, cl._bcis->at(i), CHECK_NULL);
1518 trace->obj_at_put(i, element);
1519 }
1520
1521 // Locks
1522 Symbol* lock_sym = vmSymbols::jdk_internal_vm_ThreadLock();
1523 Klass* lock_k = SystemDictionary::resolve_or_fail(lock_sym, true, CHECK_NULL);
1524 InstanceKlass* lock_klass = InstanceKlass::cast(lock_k);
1525
1526 objArrayHandle locks;
1527 if (cl._locks != nullptr && cl._locks->length() > 0) {
1538 // call static StackTraceElement[] StackTraceElement.of(StackTraceElement[] stackTrace)
1539 // to properly initialize STEs.
1540 JavaValue result(T_OBJECT);
1541 JavaCalls::call_static(&result,
1542 ste_klass,
1543 vmSymbols::java_lang_StackTraceElement_of_name(),
1544 vmSymbols::java_lang_StackTraceElement_of_signature(),
1545 trace,
1546 CHECK_NULL);
1547 // the method return the same trace array
1548
1549 Symbol* snapshot_klass_name = vmSymbols::jdk_internal_vm_ThreadSnapshot();
1550 Klass* snapshot_klass = SystemDictionary::resolve_or_fail(snapshot_klass_name, true, CHECK_NULL);
1551 if (snapshot_klass->should_be_initialized()) {
1552 snapshot_klass->initialize(CHECK_NULL);
1553 }
1554
1555 Handle snapshot = jdk_internal_vm_ThreadSnapshot::allocate(InstanceKlass::cast(snapshot_klass), CHECK_NULL);
1556 jdk_internal_vm_ThreadSnapshot::set_name(snapshot(), cl._thread_name.resolve());
1557 jdk_internal_vm_ThreadSnapshot::set_thread_status(snapshot(), (int)cl._thread_status);
1558 jdk_internal_vm_ThreadSnapshot::set_carrier_thread(snapshot(), carrier_thread());
1559 jdk_internal_vm_ThreadSnapshot::set_stack_trace(snapshot(), trace());
1560 jdk_internal_vm_ThreadSnapshot::set_locks(snapshot(), locks());
1561 if (!cl._blocker.is_empty()) {
1562 jdk_internal_vm_ThreadSnapshot::set_blocker(snapshot(), cl._blocker._type, cl._blocker._obj.resolve());
1563 }
1564 return snapshot();
1565 }
1566
1567 #endif // INCLUDE_JVMTI
|
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 OopHandle _carrier_thread;
1181 GrowableArray<OwnedLock>* _locks;
1182 Blocker _blocker;
1183 bool _completed;
1184
1185 GetThreadSnapshotHandshakeClosure(Handle thread_h, JavaThread* java_thread):
1186 HandshakeClosure("GetThreadSnapshotHandshakeClosure"),
1187 _thread_h(thread_h), _java_thread(java_thread),
1188 _frame_count(0), _methods(nullptr), _bcis(nullptr),
1189 _thread_status(), _thread_name(nullptr), _carrier_thread(nullptr),
1190 _locks(nullptr), _blocker(),
1191 _completed(false) {
1192 }
1193 virtual ~GetThreadSnapshotHandshakeClosure() {
1194 delete _methods;
1195 delete _bcis;
1196 _thread_name.release(oop_storage());
1197 _carrier_thread.release(oop_storage());
1198 if (_locks != nullptr) {
1199 for (int i = 0; i < _locks->length(); i++) {
1200 _locks->at(i)._obj.release(oop_storage());
1201 }
1202 delete _locks;
1203 }
1204 _blocker._obj.release(oop_storage());
1205 }
1206
1207 private:
1208 void detect_locks(javaVFrame* jvf, int depth) {
1209 Thread* current = Thread::current();
1210
1211 if (depth == 0 && _blocker.is_empty()) {
1212 // If this is the first frame and it is java.lang.Object.wait(...)
1213 // then print out the receiver.
1214 if (jvf->method()->name() == vmSymbols::wait_name() &&
1215 jvf->method()->method_holder()->name() == vmSymbols::java_lang_Object()) {
1216 OopHandle lock_object;
1217 StackValueCollection* locs = jvf->locals();
1261 // we have marked ourself as pending on this monitor
1262 mon == pending_moninor ||
1263 // we are not the owner of this monitor
1264 (_java_thread != nullptr && !mon->is_entered(_java_thread))) {
1265 _blocker = Blocker(Blocker::WAITING_TO_LOCK, OopHandle(oop_storage(), monitor->owner()));
1266 continue; // go to next monitor
1267 }
1268 }
1269 }
1270 _locks->push(OwnedLock(depth, OwnedLock::LOCKED, OopHandle(oop_storage(), monitor->owner())));
1271 }
1272 }
1273 }
1274 }
1275
1276 public:
1277 void do_thread(Thread* th) override {
1278 Thread* current = Thread::current();
1279
1280 bool is_virtual = java_lang_VirtualThread::is_instance(_thread_h());
1281
1282 // For a mounted virtual thread then we must check that we are in a handshake with
1283 // the JavaThread that has the virtual thread's continuation mounted.
1284 if (is_virtual && _java_thread != nullptr) {
1285 const ContinuationEntry* ce = _java_thread->vthread_continuation();
1286 if (ce == nullptr || ce->cont_oop(_java_thread) != java_lang_VirtualThread::continuation(_thread_h())) {
1287 return; // continuation not mounted
1288 }
1289 assert(_java_thread->vthread() == _thread_h(), "Wrong Thread identity");
1290 }
1291
1292 // thread status, and carrier if mounted
1293 if (is_virtual) {
1294 if (_java_thread != nullptr) {
1295 // use carrier status when mounted
1296 _thread_status = java_lang_Thread::get_thread_status(_java_thread->threadObj());
1297 _carrier_thread = OopHandle(oop_storage(), _java_thread->threadObj());
1298 } else {
1299 // use virtual thread state when unmounted
1300 int vt_state = java_lang_VirtualThread::state(_thread_h());
1301 assert((vt_state & java_lang_VirtualThread::SUSPENDED) != 0, "Unmounted virtual thread should be suspended");
1302 _thread_status = java_lang_VirtualThread::map_state_to_thread_status(vt_state);
1303 }
1304 } else {
1305 _thread_status = java_lang_Thread::get_thread_status(_thread_h());
1306 }
1307
1308 _thread_name = OopHandle(oop_storage(), java_lang_Thread::name(_thread_h()));
1309
1310 if (_java_thread != nullptr && !_java_thread->has_last_Java_frame()) {
1311 // stack trace is empty
1312 return;
1313 }
1314
1315 bool vthread_carrier = !is_virtual && (_java_thread != nullptr) && (_java_thread->vthread_continuation() != nullptr);
1316
1317 oop park_blocker = java_lang_Thread::park_blocker(_thread_h());
1318 if (park_blocker != nullptr) {
1319 _blocker = Blocker(Blocker::PARK_BLOCKER, OopHandle(oop_storage(), park_blocker));
1320 }
1321
1322 ResourceMark rm(current);
1323 HandleMark hm(current);
1324
1325 const int max_depth = MaxJavaStackTraceDepth;
1326 const bool skip_hidden = !ShowHiddenFrames;
1327
1335 vframeStream vfst(_java_thread != nullptr
1336 ? vframeStream(_java_thread, false, true, vthread_carrier)
1337 : vframeStream(java_lang_VirtualThread::continuation(_thread_h())));
1338
1339 for (;
1340 !vfst.at_end() && (max_depth == 0 || max_depth != total_count);
1341 vfst.next()) {
1342
1343 detect_locks(vfst.asJavaVFrame(), total_count);
1344
1345 if (skip_hidden && (vfst.method()->is_hidden() ||
1346 vfst.method()->is_continuation_enter_intrinsic())) {
1347 continue;
1348 }
1349 _methods->push(vfst.method());
1350 _bcis->push(vfst.bci());
1351 total_count++;
1352 }
1353
1354 _frame_count = total_count;
1355
1356 _completed = true;
1357 }
1358
1359 bool is_completed() {
1360 return _completed;
1361 }
1362 };
1363
1364 class jdk_internal_vm_ThreadLock: AllStatic {
1365 static bool _inited;
1366 static int _depth_offset;
1367 static int _typeOrdinal_offset;
1368 static int _obj_offset;
1369
1370 static void compute_offsets(InstanceKlass* klass, TRAPS) {
1371 JavaClasses::compute_offset(_depth_offset, klass, "depth", vmSymbols::int_signature(), false);
1372 JavaClasses::compute_offset(_typeOrdinal_offset, klass, "typeOrdinal", vmSymbols::int_signature(), false);
1373 JavaClasses::compute_offset(_obj_offset, klass, "obj", vmSymbols::object_signature(), false);
1374 }
1375 public:
1376 static void init(InstanceKlass* klass, TRAPS) {
1377 if (!_inited) {
1378 compute_offsets(klass, CHECK);
1379 _inited = true;
1380 }
1441 snapshot->obj_field_put(_stackTrace_offset, trace);
1442 }
1443 static void set_locks(oop snapshot, oop locks) {
1444 snapshot->obj_field_put(_locks_offset, locks);
1445 }
1446 static void set_blocker(oop snapshot, int type_ordinal, oop lock) {
1447 snapshot->int_field_put(_blockerTypeOrdinal_offset, type_ordinal);
1448 snapshot->obj_field_put(_blockerObject_offset, lock);
1449 }
1450 };
1451
1452 bool jdk_internal_vm_ThreadSnapshot::_inited = false;
1453 int jdk_internal_vm_ThreadSnapshot::_name_offset;
1454 int jdk_internal_vm_ThreadSnapshot::_threadStatus_offset;
1455 int jdk_internal_vm_ThreadSnapshot::_carrierThread_offset;
1456 int jdk_internal_vm_ThreadSnapshot::_stackTrace_offset;
1457 int jdk_internal_vm_ThreadSnapshot::_locks_offset;
1458 int jdk_internal_vm_ThreadSnapshot::_blockerTypeOrdinal_offset;
1459 int jdk_internal_vm_ThreadSnapshot::_blockerObject_offset;
1460
1461 oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, jboolean suspended_by_caller, TRAPS) {
1462 ThreadsListHandle tlh(THREAD);
1463
1464 ResourceMark rm(THREAD);
1465 HandleMark hm(THREAD);
1466
1467 JavaThread* java_thread = nullptr;
1468 oop thread_oop;
1469 bool has_javathread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
1470 assert((has_javathread && thread_oop != nullptr) || !has_javathread, "Missing Thread oop");
1471 Handle thread_h(THREAD, thread_oop);
1472 bool is_virtual = java_lang_VirtualThread::is_instance(thread_h()); // Deals with null
1473 if (!has_javathread && !is_virtual) {
1474 return nullptr; // thread terminated so not of interest
1475 }
1476
1477 // unmounted virtual thread needs to be suspended by caller
1478 if (is_virtual && !has_javathread) {
1479 if (suspended_by_caller == JNI_FALSE) {
1480 return nullptr; // called needs to suspend and retry
1481 }
1482 assert((java_lang_VirtualThread::state(thread_h()) & java_lang_VirtualThread::SUSPENDED) != 0, "Not suspended");
1483 }
1484
1485 // Handshake with target
1486 GetThreadSnapshotHandshakeClosure cl(thread_h, java_thread);
1487 if (java_thread == nullptr) {
1488 // unmounted vthread, execute on the current thread
1489 cl.do_thread(nullptr);
1490 } else {
1491 Handshake::execute(&cl, &tlh, java_thread);
1492 }
1493 if (!cl.is_completed()) {
1494 return nullptr;
1495 }
1496
1497 // StackTrace
1498 InstanceKlass* ste_klass = vmClasses::StackTraceElement_klass();
1499 assert(ste_klass != nullptr, "must be loaded");
1500
1501 objArrayHandle trace = oopFactory::new_objArray_handle(ste_klass, cl._frame_count, CHECK_NULL);
1502
1503 for (int i = 0; i < cl._frame_count; i++) {
1504 methodHandle method(THREAD, cl._methods->at(i));
1505 oop element = java_lang_StackTraceElement::create(method, cl._bcis->at(i), CHECK_NULL);
1506 trace->obj_at_put(i, element);
1507 }
1508
1509 // Locks
1510 Symbol* lock_sym = vmSymbols::jdk_internal_vm_ThreadLock();
1511 Klass* lock_k = SystemDictionary::resolve_or_fail(lock_sym, true, CHECK_NULL);
1512 InstanceKlass* lock_klass = InstanceKlass::cast(lock_k);
1513
1514 objArrayHandle locks;
1515 if (cl._locks != nullptr && cl._locks->length() > 0) {
1526 // call static StackTraceElement[] StackTraceElement.of(StackTraceElement[] stackTrace)
1527 // to properly initialize STEs.
1528 JavaValue result(T_OBJECT);
1529 JavaCalls::call_static(&result,
1530 ste_klass,
1531 vmSymbols::java_lang_StackTraceElement_of_name(),
1532 vmSymbols::java_lang_StackTraceElement_of_signature(),
1533 trace,
1534 CHECK_NULL);
1535 // the method return the same trace array
1536
1537 Symbol* snapshot_klass_name = vmSymbols::jdk_internal_vm_ThreadSnapshot();
1538 Klass* snapshot_klass = SystemDictionary::resolve_or_fail(snapshot_klass_name, true, CHECK_NULL);
1539 if (snapshot_klass->should_be_initialized()) {
1540 snapshot_klass->initialize(CHECK_NULL);
1541 }
1542
1543 Handle snapshot = jdk_internal_vm_ThreadSnapshot::allocate(InstanceKlass::cast(snapshot_klass), CHECK_NULL);
1544 jdk_internal_vm_ThreadSnapshot::set_name(snapshot(), cl._thread_name.resolve());
1545 jdk_internal_vm_ThreadSnapshot::set_thread_status(snapshot(), (int)cl._thread_status);
1546 jdk_internal_vm_ThreadSnapshot::set_carrier_thread(snapshot(), cl._carrier_thread.resolve());
1547 jdk_internal_vm_ThreadSnapshot::set_stack_trace(snapshot(), trace());
1548 jdk_internal_vm_ThreadSnapshot::set_locks(snapshot(), locks());
1549 if (!cl._blocker.is_empty()) {
1550 jdk_internal_vm_ThreadSnapshot::set_blocker(snapshot(), cl._blocker._type, cl._blocker._obj.resolve());
1551 }
1552 return snapshot();
1553 }
1554
1555 #endif // INCLUDE_JVMTI
|