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
|