< prev index next >

src/hotspot/share/prims/jvmtiEnvBase.cpp

Print this page

 999          jvf != nullptr; jvf = jvf->java_sender()) {
1000       if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep
1001         // add locked objects for this frame into list
1002         err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
1003         if (err != JVMTI_ERROR_NONE) {
1004           return err;
1005         }
1006       }
1007     }
1008   }
1009 
1010   // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
1011   JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
1012   ObjectSynchronizer::owned_monitors_iterate(&jmc, java_thread);
1013   err = jmc.error();
1014 
1015   return err;
1016 }
1017 
1018 jvmtiError
1019 JvmtiEnvBase::get_owned_monitors(JavaThread* calling_thread, JavaThread* java_thread, javaVFrame* jvf,
1020                                  GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) {
1021   jvmtiError err = JVMTI_ERROR_NONE;
1022   Thread *current_thread = Thread::current();
1023   assert(java_thread->is_handshake_safe_for(current_thread),
1024          "call by myself or at handshake");
1025 
1026   int depth = 0;
1027   for ( ; jvf != nullptr; jvf = jvf->java_sender()) {
1028     if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep
1029       // Add locked objects for this frame into list.
1030       err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth - 1);
1031       if (err != JVMTI_ERROR_NONE) {
1032         return err;
1033       }
1034     }
1035   }
1036 






1037   // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
1038   JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
1039   ObjectSynchronizer::owned_monitors_iterate(&jmc, java_thread);
1040   err = jmc.error();
1041 
1042   return err;
1043 }
1044 
1045 // Save JNI local handles for any objects that this frame owns.
1046 jvmtiError
1047 JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
1048                                  javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, jint stack_depth) {

1049   jvmtiError err = JVMTI_ERROR_NONE;
1050   Thread* current_thread = Thread::current();
1051   ResourceMark rm(current_thread);
1052   HandleMark   hm(current_thread);
1053 
1054   GrowableArray<MonitorInfo*>* mons = jvf->monitors();
1055   if (mons->is_empty()) {
1056     return err;  // this javaVFrame holds no monitors
1057   }
1058 
1059   oop wait_obj = nullptr;
1060   {
1061     // The ObjectMonitor* can't be async deflated since we are either
1062     // at a safepoint or the calling thread is operating on itself so
1063     // it cannot leave the underlying wait() call.
1064     // Save object of current wait() call (if any) for later comparison.
1065     ObjectMonitor *mon = java_thread->current_waiting_monitor();
1066     if (mon != nullptr) {
1067       wait_obj = mon->object();
1068     }
1069   }
1070   oop pending_obj = nullptr;
1071   {
1072     // The ObjectMonitor* can't be async deflated since we are either
1073     // at a safepoint or the calling thread is operating on itself so
1074     // it cannot leave the underlying enter() call.
1075     // Save object of current enter() call (if any) for later comparison.
1076     ObjectMonitor *mon = java_thread->current_pending_monitor();
1077     if (mon != nullptr) {
1078       pending_obj = mon->object();








1079     }
1080   }
1081 
1082   for (int i = 0; i < mons->length(); i++) {
1083     MonitorInfo *mi = mons->at(i);
1084 
1085     if (mi->owner_is_scalar_replaced()) continue;
1086 
1087     oop obj = mi->owner();
1088     if (obj == nullptr) {
1089       // this monitor doesn't have an owning object so skip it
1090       continue;
1091     }
1092 
1093     if (wait_obj == obj) {
1094       // the thread is waiting on this monitor so it isn't really owned
1095       continue;
1096     }
1097 
1098     if (pending_obj == obj) {

1507                                 // or to re-enter monitor, in Object.wait()
1508 
1509     // Get the actual set of threads trying to enter, or re-enter, the monitor.
1510     wantList = Threads::get_pending_threads(tlh.list(), nWant + nWait, (address)mon);
1511     nWant = wantList->length();
1512   } else {
1513     // this object has a lightweight monitor
1514   }
1515 
1516   jint skipped = 0;
1517   if (mon != nullptr) {
1518     // Robustness: the actual waiting list can be smaller.
1519     // The nWait count we got from the mon->waiters() may include the re-entering
1520     // the monitor threads after being notified. Here we are correcting the actual
1521     // number of the waiting threads by excluding those re-entering the monitor.
1522     nWait = 0;
1523     for (ObjectWaiter* waiter = mon->first_waiter();
1524          waiter != nullptr && (nWait == 0 || waiter != mon->first_waiter());
1525          waiter = mon->next_waiter(waiter)) {
1526       JavaThread *w = mon->thread_of_waiter(waiter);
1527       oop thread_oop = get_vthread_or_thread_oop(w);
1528       if (thread_oop->is_a(vmClasses::BaseVirtualThread_klass())) {
1529         skipped++;





1530       }
1531       nWait++;
1532     }
1533   }
1534   ret.waiter_count = nWant;
1535   ret.notify_waiter_count = nWait - skipped;
1536 
1537   // Allocate memory for heavyweight and lightweight monitor.
1538   jvmtiError err;
1539   err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters);
1540   if (err != JVMTI_ERROR_NONE) {
1541     return err;
1542   }
1543   err = allocate(ret.notify_waiter_count * sizeof(jthread *),
1544                  (unsigned char**)&ret.notify_waiters);
1545   if (err != JVMTI_ERROR_NONE) {
1546     deallocate((unsigned char*)ret.waiters);
1547     return err;
1548   }
1549 

1557     }
1558     if (ret.notify_waiters != nullptr) {
1559       memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
1560     }
1561 
1562     if (ret.waiter_count > 0) { // we have contending threads waiting to enter/re-enter the monitor
1563       // identify threads waiting to enter and re-enter the monitor
1564       // get_pending_threads returns only java thread so we do not need to
1565       // check for non java threads.
1566       for (int i = 0; i < nWant; i++) {
1567         JavaThread *pending_thread = wantList->at(i);
1568         Handle th(current_thread, get_vthread_or_thread_oop(pending_thread));
1569         ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
1570       }
1571     }
1572     if (ret.notify_waiter_count > 0) { // we have threads waiting to be notified in Object.wait()
1573       ObjectWaiter *waiter = mon->first_waiter();
1574       jint skipped = 0;
1575       for (int i = 0; i < nWait; i++) {
1576         JavaThread *w = mon->thread_of_waiter(waiter);
1577         oop thread_oop = get_vthread_or_thread_oop(w);
1578         bool is_virtual = thread_oop->is_a(vmClasses::BaseVirtualThread_klass());
1579         assert(w != nullptr, "sanity check");




1580         if (is_virtual) {
1581           skipped++;
1582         } else {
1583           // If the thread was found on the ObjectWaiter list, then
1584           // it has not been notified.
1585           Handle th(current_thread, get_vthread_or_thread_oop(w));
1586           ret.notify_waiters[i - skipped] = (jthread)jni_reference(calling_thread, th);
1587         }
1588         waiter = mon->next_waiter(waiter);
1589       }
1590     }
1591   } else {
1592     // this object has a lightweight monitor and we have nothing more
1593     // to do here because the defaults are just fine.
1594   }
1595 
1596   // we don't update return parameter unless everything worked
1597   *info_ptr = ret;
1598 
1599   return JVMTI_ERROR_NONE;
1600 }
1601 
1602 jvmtiError
1603 JvmtiEnvBase::check_thread_list(jint count, const jthread* list) {
1604   if (list == nullptr && count != 0) {
1605     return JVMTI_ERROR_NULL_POINTER;

2484   if (!_self && !JvmtiVTSuspender::is_vthread_suspended(target_h())) {
2485     _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
2486     return;
2487   }
2488   javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h());
2489   _result = ((JvmtiEnvBase*)_env)->set_frame_pop(_state, jvf, _depth);
2490 }
2491 
2492 void
2493 GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
2494   JavaThread *jt = JavaThread::cast(target);
2495   if (!jt->is_exiting() && (jt->threadObj() != nullptr)) {
2496     _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
2497                                                          jt,
2498                                                          _owned_monitors_list);
2499   }
2500 }
2501 
2502 void
2503 GetOwnedMonitorInfoClosure::do_vthread(Handle target_h) {
2504   assert(_target_jt != nullptr, "sanity check");
2505   Thread* current = Thread::current();
2506   ResourceMark rm(current); // vframes are resource allocated
2507   HandleMark hm(current);
2508 
2509   javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h());
2510 
2511   if (!_target_jt->is_exiting() && _target_jt->threadObj() != nullptr) {
2512     _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
2513                                                          _target_jt,
2514                                                          jvf,
2515                                                          _owned_monitors_list);

2516   }
2517 }
2518 
2519 void
2520 GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
2521   JavaThread *jt = JavaThread::cast(target);
2522   if (!jt->is_exiting() && (jt->threadObj() != nullptr)) {
2523     _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,
2524                                                                     jt,
2525                                                                     _owned_monitor_ptr,
2526                                                                     _is_virtual);
2527   }
2528 }
2529 
2530 void
2531 GetCurrentContendedMonitorClosure::do_vthread(Handle target_h) {
2532   if (_target_jt == nullptr) {







2533     _result = JVMTI_ERROR_NONE; // target virtual thread is unmounted
2534     return;
2535   }
2536   // mounted virtual thread case
2537   do_thread(_target_jt);
2538 }
2539 
2540 void
2541 GetStackTraceClosure::do_thread(Thread *target) {
2542   Thread* current = Thread::current();
2543   ResourceMark rm(current);
2544 
2545   JavaThread *jt = JavaThread::cast(target);
2546   if (!jt->is_exiting() && jt->threadObj() != nullptr) {
2547     _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt,
2548                                                       _start_depth, _max_count,
2549                                                       _frame_buffer, _count_ptr);
2550   }
2551 }
2552 

 999          jvf != nullptr; jvf = jvf->java_sender()) {
1000       if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep
1001         // add locked objects for this frame into list
1002         err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
1003         if (err != JVMTI_ERROR_NONE) {
1004           return err;
1005         }
1006       }
1007     }
1008   }
1009 
1010   // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
1011   JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
1012   ObjectSynchronizer::owned_monitors_iterate(&jmc, java_thread);
1013   err = jmc.error();
1014 
1015   return err;
1016 }
1017 
1018 jvmtiError
1019 JvmtiEnvBase::get_owned_monitors(JavaThread* calling_thread, JavaThread* carrier, javaVFrame* jvf,
1020                                  GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list, oop vthread) {
1021   jvmtiError err = JVMTI_ERROR_NONE;
1022   Thread *current_thread = Thread::current();
1023   assert(carrier == nullptr || carrier->is_handshake_safe_for(current_thread),
1024          "call by myself or at handshake");
1025 
1026   int depth = 0;
1027   for ( ; jvf != nullptr; jvf = jvf->java_sender()) {
1028     if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep
1029       // Add locked objects for this frame into list.
1030       err = get_locked_objects_in_frame(calling_thread, carrier, jvf, owned_monitors_list, depth - 1, vthread);
1031       if (err != JVMTI_ERROR_NONE) {
1032         return err;
1033       }
1034     }
1035   }
1036 
1037   if (carrier == nullptr) {
1038     // vthread gets pinned if monitors are acquired via jni MonitorEnter
1039     // so nothing else to do for unmounted case.
1040     return err;
1041   }
1042 
1043   // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
1044   JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this);
1045   ObjectSynchronizer::owned_monitors_iterate(&jmc, carrier);
1046   err = jmc.error();
1047 
1048   return err;
1049 }
1050 
1051 // Save JNI local handles for any objects that this frame owns.
1052 jvmtiError
1053 JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* target,
1054                                  javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list,
1055                                  jint stack_depth, oop vthread) {
1056   jvmtiError err = JVMTI_ERROR_NONE;
1057   Thread* current_thread = Thread::current();
1058   ResourceMark rm(current_thread);
1059   HandleMark   hm(current_thread);
1060 
1061   GrowableArray<MonitorInfo*>* mons = jvf->monitors();
1062   if (mons->is_empty()) {
1063     return err;  // this javaVFrame holds no monitors
1064   }
1065 
1066   oop wait_obj = nullptr;
1067   {
1068     // The ObjectMonitor* can't be async deflated since we are either
1069     // at a safepoint or the calling thread is operating on itself so
1070     // it cannot leave the underlying wait() call.
1071     // Save object of current wait() call (if any) for later comparison.
1072     if (target != nullptr) {
1073       ObjectMonitor *mon = target->current_waiting_monitor();
1074       if (mon != nullptr) wait_obj = mon->object();
1075     }
1076   }
1077   oop pending_obj = nullptr;
1078   {
1079     // The ObjectMonitor* can't be async deflated since we are either
1080     // at a safepoint or the calling thread is operating on itself so
1081     // it cannot leave the underlying enter() call.
1082     // Save object of current enter() call (if any) for later comparison.
1083     if (target != nullptr) {
1084       ObjectMonitor *mon = target->current_pending_monitor();
1085       if (mon != nullptr) pending_obj = mon->object();
1086     } else {
1087       assert(vthread != nullptr, "no vthread oop");
1088       oop oopCont = java_lang_VirtualThread::continuation(vthread);
1089       assert(oopCont != nullptr, "vthread with no continuation");
1090       stackChunkOop chunk = jdk_internal_vm_Continuation::tail(oopCont);
1091       assert(chunk != nullptr, "unmounted vthread should have a chunk");
1092       ObjectMonitor *mon = chunk->current_pending_monitor();
1093       if (mon != nullptr) pending_obj = mon->object();
1094     }
1095   }
1096 
1097   for (int i = 0; i < mons->length(); i++) {
1098     MonitorInfo *mi = mons->at(i);
1099 
1100     if (mi->owner_is_scalar_replaced()) continue;
1101 
1102     oop obj = mi->owner();
1103     if (obj == nullptr) {
1104       // this monitor doesn't have an owning object so skip it
1105       continue;
1106     }
1107 
1108     if (wait_obj == obj) {
1109       // the thread is waiting on this monitor so it isn't really owned
1110       continue;
1111     }
1112 
1113     if (pending_obj == obj) {

1522                                 // or to re-enter monitor, in Object.wait()
1523 
1524     // Get the actual set of threads trying to enter, or re-enter, the monitor.
1525     wantList = Threads::get_pending_threads(tlh.list(), nWant + nWait, (address)mon);
1526     nWant = wantList->length();
1527   } else {
1528     // this object has a lightweight monitor
1529   }
1530 
1531   jint skipped = 0;
1532   if (mon != nullptr) {
1533     // Robustness: the actual waiting list can be smaller.
1534     // The nWait count we got from the mon->waiters() may include the re-entering
1535     // the monitor threads after being notified. Here we are correcting the actual
1536     // number of the waiting threads by excluding those re-entering the monitor.
1537     nWait = 0;
1538     for (ObjectWaiter* waiter = mon->first_waiter();
1539          waiter != nullptr && (nWait == 0 || waiter != mon->first_waiter());
1540          waiter = mon->next_waiter(waiter)) {
1541       JavaThread *w = mon->thread_of_waiter(waiter);
1542       if (w == nullptr) {

1543         skipped++;
1544       } else {
1545         oop thread_oop = get_vthread_or_thread_oop(w);
1546         if (thread_oop->is_a(vmClasses::BaseVirtualThread_klass())) {
1547           skipped++;
1548         }
1549       }
1550       nWait++;
1551     }
1552   }
1553   ret.waiter_count = nWant;
1554   ret.notify_waiter_count = nWait - skipped;
1555 
1556   // Allocate memory for heavyweight and lightweight monitor.
1557   jvmtiError err;
1558   err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters);
1559   if (err != JVMTI_ERROR_NONE) {
1560     return err;
1561   }
1562   err = allocate(ret.notify_waiter_count * sizeof(jthread *),
1563                  (unsigned char**)&ret.notify_waiters);
1564   if (err != JVMTI_ERROR_NONE) {
1565     deallocate((unsigned char*)ret.waiters);
1566     return err;
1567   }
1568 

1576     }
1577     if (ret.notify_waiters != nullptr) {
1578       memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
1579     }
1580 
1581     if (ret.waiter_count > 0) { // we have contending threads waiting to enter/re-enter the monitor
1582       // identify threads waiting to enter and re-enter the monitor
1583       // get_pending_threads returns only java thread so we do not need to
1584       // check for non java threads.
1585       for (int i = 0; i < nWant; i++) {
1586         JavaThread *pending_thread = wantList->at(i);
1587         Handle th(current_thread, get_vthread_or_thread_oop(pending_thread));
1588         ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
1589       }
1590     }
1591     if (ret.notify_waiter_count > 0) { // we have threads waiting to be notified in Object.wait()
1592       ObjectWaiter *waiter = mon->first_waiter();
1593       jint skipped = 0;
1594       for (int i = 0; i < nWait; i++) {
1595         JavaThread *w = mon->thread_of_waiter(waiter);
1596         bool is_virtual;
1597         if (w == nullptr) {
1598           is_virtual = true;
1599         } else {
1600           oop thread_oop = get_vthread_or_thread_oop(w);
1601           is_virtual = thread_oop->is_a(vmClasses::BaseVirtualThread_klass());
1602         }
1603         if (is_virtual) {
1604           skipped++;
1605         } else {
1606           // If the thread was found on the ObjectWaiter list, then
1607           // it has not been notified.
1608           Handle th(current_thread, w->threadObj());
1609           ret.notify_waiters[i - skipped] = (jthread)jni_reference(calling_thread, th);
1610         }
1611         waiter = mon->next_waiter(waiter);
1612       }
1613     }
1614   } else {
1615     // this object has a lightweight monitor and we have nothing more
1616     // to do here because the defaults are just fine.
1617   }
1618 
1619   // we don't update return parameter unless everything worked
1620   *info_ptr = ret;
1621 
1622   return JVMTI_ERROR_NONE;
1623 }
1624 
1625 jvmtiError
1626 JvmtiEnvBase::check_thread_list(jint count, const jthread* list) {
1627   if (list == nullptr && count != 0) {
1628     return JVMTI_ERROR_NULL_POINTER;

2507   if (!_self && !JvmtiVTSuspender::is_vthread_suspended(target_h())) {
2508     _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
2509     return;
2510   }
2511   javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h());
2512   _result = ((JvmtiEnvBase*)_env)->set_frame_pop(_state, jvf, _depth);
2513 }
2514 
2515 void
2516 GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
2517   JavaThread *jt = JavaThread::cast(target);
2518   if (!jt->is_exiting() && (jt->threadObj() != nullptr)) {
2519     _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
2520                                                          jt,
2521                                                          _owned_monitors_list);
2522   }
2523 }
2524 
2525 void
2526 GetOwnedMonitorInfoClosure::do_vthread(Handle target_h) {

2527   Thread* current = Thread::current();
2528   ResourceMark rm(current); // vframes are resource allocated
2529   HandleMark hm(current);
2530 
2531   javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h());
2532 
2533   if (_target_jt == nullptr || (!_target_jt->is_exiting() && _target_jt->threadObj() != nullptr)) {
2534     _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
2535                                                          _target_jt,
2536                                                          jvf,
2537                                                          _owned_monitors_list,
2538                                                          target_h());
2539   }
2540 }
2541 
2542 void
2543 GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
2544   JavaThread *jt = JavaThread::cast(target);
2545   if (!jt->is_exiting() && (jt->threadObj() != nullptr)) {
2546     _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,
2547                                                                     jt,
2548                                                                     _owned_monitor_ptr,
2549                                                                     _is_virtual);
2550   }
2551 }
2552 
2553 void
2554 GetCurrentContendedMonitorClosure::do_vthread(Handle target_h) {
2555   if (_target_jt == nullptr) {
2556     oop cont = java_lang_VirtualThread::continuation(target_h());
2557     assert(cont != nullptr, "vthread with no continuation");
2558     stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont);
2559     assert(chunk != nullptr, "unmounted vthread should have a chunk");
2560     if (chunk->current_pending_monitor() != nullptr) {
2561       *_owned_monitor_ptr = JNIHandles::make_local(_calling_thread, chunk->current_pending_monitor()->object());
2562     }
2563     _result = JVMTI_ERROR_NONE; // target virtual thread is unmounted
2564     return;
2565   }
2566   // mounted virtual thread case
2567   do_thread(_target_jt);
2568 }
2569 
2570 void
2571 GetStackTraceClosure::do_thread(Thread *target) {
2572   Thread* current = Thread::current();
2573   ResourceMark rm(current);
2574 
2575   JavaThread *jt = JavaThread::cast(target);
2576   if (!jt->is_exiting() && jt->threadObj() != nullptr) {
2577     _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt,
2578                                                       _start_depth, _max_count,
2579                                                       _frame_buffer, _count_ptr);
2580   }
2581 }
2582 
< prev index next >