287 ObjectMonitor::ObjectMonitor(oop object) :
288 _metadata(0),
289 _object(_oop_storage, object),
290 _owner(NO_OWNER),
291 _previous_owner_tid(0),
292 _next_om(nullptr),
293 _recursions(0),
294 _entry_list(nullptr),
295 _entry_list_tail(nullptr),
296 _succ(NO_OWNER),
297 _SpinDuration(ObjectMonitor::Knob_SpinLimit),
298 _contentions(0),
299 _unmounted_vthreads(0),
300 _wait_set(nullptr),
301 _waiters(0),
302 _wait_set_lock(0)
303 { }
304
305 ObjectMonitor::~ObjectMonitor() {
306 _object.release(_oop_storage);
307 }
308
309 oop ObjectMonitor::object() const {
310 check_object_context();
311 return _object.resolve();
312 }
313
314 void ObjectMonitor::ExitOnSuspend::operator()(JavaThread* current) {
315 if (current->is_suspended()) {
316 _om->_recursions = 0;
317 _om->clear_successor();
318 // Don't need a full fence after clearing successor here because of the call to exit().
319 _om->exit(current, false /* not_suspended */);
320 _om_exited = true;
321
322 current->set_current_pending_monitor(_om);
323 }
324 }
325
326 void ObjectMonitor::ClearSuccOnSuspend::operator()(JavaThread* current) {
327 if (current->is_suspended()) {
328 if (_om->has_successor(current)) {
329 _om->clear_successor();
330 OrderAccess::fence(); // always do a full fence when successor is cleared
331 }
332 }
333 }
1796 // consume an unpark() meant for the ParkEvent associated with
1797 // this ObjectMonitor.
1798 }
1799 if (wait_event.should_commit()) {
1800 post_monitor_wait_event(&wait_event, this, 0, millis, false);
1801 }
1802 THROW(vmSymbols::java_lang_InterruptedException());
1803 return;
1804 }
1805
1806 freeze_result result;
1807 ContinuationEntry* ce = current->last_continuation();
1808 bool is_virtual = ce != nullptr && ce->is_virtual_thread();
1809 if (is_virtual) {
1810 if (interruptible && JvmtiExport::should_post_monitor_wait()) {
1811 JvmtiExport::post_monitor_wait(current, object(), millis);
1812 }
1813 current->set_current_waiting_monitor(this);
1814 result = Continuation::try_preempt(current, ce->cont_oop(current));
1815 if (result == freeze_ok) {
1816 vthread_wait(current, millis);
1817 current->set_current_waiting_monitor(nullptr);
1818 return;
1819 }
1820 }
1821 // The jtiows does nothing for non-interruptible.
1822 JavaThreadInObjectWaitState jtiows(current, millis != 0, interruptible);
1823
1824 if (!is_virtual) { // it was already set for virtual thread
1825 if (interruptible && JvmtiExport::should_post_monitor_wait()) {
1826 JvmtiExport::post_monitor_wait(current, object(), millis);
1827
1828 // The current thread already owns the monitor and it has not yet
1829 // been added to the wait queue so the current thread cannot be
1830 // made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
1831 // event handler cannot accidentally consume an unpark() meant for
1832 // the ParkEvent associated with this ObjectMonitor.
1833 }
1834 current->set_current_waiting_monitor(this);
1835 }
1836 // create a node to be put into the queue
2150 quick_notifyAll(current);
2151 }
2152
2153 void ObjectMonitor::quick_notifyAll(JavaThread* current) {
2154 assert(has_owner(current), "Precondition");
2155
2156 EventJavaMonitorNotify event;
2157 DTRACE_MONITOR_PROBE(notifyAll, this, object(), current);
2158 int tally = 0;
2159 while (_wait_set != nullptr) {
2160 if (notify_internal(current)) {
2161 tally++;
2162 }
2163 }
2164
2165 if ((tally > 0) && event.should_commit()) {
2166 post_monitor_notify_event(&event, this, /* notified_count = */ tally);
2167 }
2168 }
2169
2170 void ObjectMonitor::vthread_wait(JavaThread* current, jlong millis) {
2171 oop vthread = current->vthread();
2172 ObjectWaiter* node = new ObjectWaiter(vthread, this);
2173 node->_is_wait = true;
2174 node->TState = ObjectWaiter::TS_WAIT;
2175 java_lang_VirtualThread::set_notified(vthread, false); // Reset notified flag
2176
2177 // Enter the waiting queue, which is a circular doubly linked list in this case
2178 // but it could be a priority queue or any data structure.
2179 // _wait_set_lock protects the wait queue. Normally the wait queue is accessed only
2180 // by the owner of the monitor *except* in the case where park()
2181 // returns because of a timeout or interrupt. Contention is exceptionally rare
2182 // so we use a simple spin-lock instead of a heavier-weight blocking lock.
2183
2184 Thread::SpinAcquire(&_wait_set_lock);
2185 add_waiter(node);
2186 Thread::SpinRelease(&_wait_set_lock);
2187
2188 node->_recursions = _recursions; // record the old recursion count
2189 _recursions = 0; // set the recursion level to be 0
2190 _waiters++; // increment the number of waiters
2191 exit(current); // exit the monitor
2192 guarantee(!has_owner(current), "invariant");
2193
2194 assert(java_lang_VirtualThread::state(vthread) == java_lang_VirtualThread::RUNNING, "wrong state for vthread");
2195 java_lang_VirtualThread::set_state(vthread, millis == 0 ? java_lang_VirtualThread::WAITING : java_lang_VirtualThread::TIMED_WAITING);
2200 }
2201
2202 bool ObjectMonitor::vthread_wait_reenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont) {
2203 // The first time we run after being preempted on Object.wait() we
2204 // need to check if we were interrupted or the wait timed-out, and
2205 // in that case remove ourselves from the _wait_set queue.
2206 if (node->TState == ObjectWaiter::TS_WAIT) {
2207 Thread::SpinAcquire(&_wait_set_lock);
2208 if (node->TState == ObjectWaiter::TS_WAIT) {
2209 dequeue_specific_waiter(node); // unlink from wait_set
2210 node->TState = ObjectWaiter::TS_RUN;
2211 }
2212 Thread::SpinRelease(&_wait_set_lock);
2213 }
2214
2215 // If this was an interrupted case, set the _interrupted boolean so that
2216 // once we re-acquire the monitor we know if we need to throw IE or not.
2217 ObjectWaiter::TStates state = node->TState;
2218 bool was_notified = state == ObjectWaiter::TS_ENTER;
2219 assert(was_notified || state == ObjectWaiter::TS_RUN, "");
2220 node->_interrupted = !was_notified && current->is_interrupted(false);
2221
2222 // Post JFR and JVMTI events.
2223 EventJavaMonitorWait wait_event;
2224 if (wait_event.should_commit() || JvmtiExport::should_post_monitor_waited()) {
2225 vthread_monitor_waited_event(current, node, cont, &wait_event, !was_notified && !node->_interrupted);
2226 }
2227
2228 // Mark that we are at reenter so that we don't call this method again.
2229 node->_at_reenter = true;
2230
2231 if (!was_notified) {
2232 bool acquired = vthread_monitor_enter(current, node);
2233 if (acquired) {
2234 guarantee(_recursions == 0, "invariant");
2235 _recursions = node->_recursions; // restore the old recursion count
2236 _waiters--; // decrement the number of waiters
2237
2238 if (node->_interrupted) {
2239 // We will throw at thaw end after finishing the mount transition.
2240 current->set_pending_interrupted_exception(true);
2241 }
2242
2243 delete node;
2244 // Clear the ObjectWaiter* from the vthread.
|
287 ObjectMonitor::ObjectMonitor(oop object) :
288 _metadata(0),
289 _object(_oop_storage, object),
290 _owner(NO_OWNER),
291 _previous_owner_tid(0),
292 _next_om(nullptr),
293 _recursions(0),
294 _entry_list(nullptr),
295 _entry_list_tail(nullptr),
296 _succ(NO_OWNER),
297 _SpinDuration(ObjectMonitor::Knob_SpinLimit),
298 _contentions(0),
299 _unmounted_vthreads(0),
300 _wait_set(nullptr),
301 _waiters(0),
302 _wait_set_lock(0)
303 { }
304
305 ObjectMonitor::~ObjectMonitor() {
306 _object.release(_oop_storage);
307 _object_strong.release(JavaThread::thread_oop_storage());
308 }
309
310 oop ObjectMonitor::object() const {
311 check_object_context();
312 return _object.resolve();
313 }
314
315 // Keep object protected during ObjectLocker preemption.
316 void ObjectMonitor::set_object_strong() {
317 check_object_context();
318 if (_object_strong.is_empty()) {
319 if (Thread::TrySpinAcquire(&_object_strong_lock)) {
320 if (_object_strong.is_empty()) {
321 assert(_object.resolve() != nullptr, "");
322 _object_strong = OopHandle(JavaThread::thread_oop_storage(), _object.resolve());
323 }
324 Thread::SpinRelease(&_object_strong_lock);
325 }
326 }
327 }
328
329 void ObjectMonitor::ExitOnSuspend::operator()(JavaThread* current) {
330 if (current->is_suspended()) {
331 _om->_recursions = 0;
332 _om->clear_successor();
333 // Don't need a full fence after clearing successor here because of the call to exit().
334 _om->exit(current, false /* not_suspended */);
335 _om_exited = true;
336
337 current->set_current_pending_monitor(_om);
338 }
339 }
340
341 void ObjectMonitor::ClearSuccOnSuspend::operator()(JavaThread* current) {
342 if (current->is_suspended()) {
343 if (_om->has_successor(current)) {
344 _om->clear_successor();
345 OrderAccess::fence(); // always do a full fence when successor is cleared
346 }
347 }
348 }
1811 // consume an unpark() meant for the ParkEvent associated with
1812 // this ObjectMonitor.
1813 }
1814 if (wait_event.should_commit()) {
1815 post_monitor_wait_event(&wait_event, this, 0, millis, false);
1816 }
1817 THROW(vmSymbols::java_lang_InterruptedException());
1818 return;
1819 }
1820
1821 freeze_result result;
1822 ContinuationEntry* ce = current->last_continuation();
1823 bool is_virtual = ce != nullptr && ce->is_virtual_thread();
1824 if (is_virtual) {
1825 if (interruptible && JvmtiExport::should_post_monitor_wait()) {
1826 JvmtiExport::post_monitor_wait(current, object(), millis);
1827 }
1828 current->set_current_waiting_monitor(this);
1829 result = Continuation::try_preempt(current, ce->cont_oop(current));
1830 if (result == freeze_ok) {
1831 vthread_wait(current, millis, interruptible);
1832 current->set_current_waiting_monitor(nullptr);
1833 return;
1834 }
1835 }
1836 // The jtiows does nothing for non-interruptible.
1837 JavaThreadInObjectWaitState jtiows(current, millis != 0, interruptible);
1838
1839 if (!is_virtual) { // it was already set for virtual thread
1840 if (interruptible && JvmtiExport::should_post_monitor_wait()) {
1841 JvmtiExport::post_monitor_wait(current, object(), millis);
1842
1843 // The current thread already owns the monitor and it has not yet
1844 // been added to the wait queue so the current thread cannot be
1845 // made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
1846 // event handler cannot accidentally consume an unpark() meant for
1847 // the ParkEvent associated with this ObjectMonitor.
1848 }
1849 current->set_current_waiting_monitor(this);
1850 }
1851 // create a node to be put into the queue
2165 quick_notifyAll(current);
2166 }
2167
2168 void ObjectMonitor::quick_notifyAll(JavaThread* current) {
2169 assert(has_owner(current), "Precondition");
2170
2171 EventJavaMonitorNotify event;
2172 DTRACE_MONITOR_PROBE(notifyAll, this, object(), current);
2173 int tally = 0;
2174 while (_wait_set != nullptr) {
2175 if (notify_internal(current)) {
2176 tally++;
2177 }
2178 }
2179
2180 if ((tally > 0) && event.should_commit()) {
2181 post_monitor_notify_event(&event, this, /* notified_count = */ tally);
2182 }
2183 }
2184
2185 void ObjectMonitor::vthread_wait(JavaThread* current, jlong millis, bool interruptible) {
2186 oop vthread = current->vthread();
2187 ObjectWaiter* node = new ObjectWaiter(vthread, this);
2188 node->_is_wait = true;
2189 node->_interruptible = interruptible;
2190 node->TState = ObjectWaiter::TS_WAIT;
2191 java_lang_VirtualThread::set_notified(vthread, false); // Reset notified flag
2192 java_lang_VirtualThread::set_interruptible_wait(vthread, interruptible);
2193
2194 // Enter the waiting queue, which is a circular doubly linked list in this case
2195 // but it could be a priority queue or any data structure.
2196 // _wait_set_lock protects the wait queue. Normally the wait queue is accessed only
2197 // by the owner of the monitor *except* in the case where park()
2198 // returns because of a timeout or interrupt. Contention is exceptionally rare
2199 // so we use a simple spin-lock instead of a heavier-weight blocking lock.
2200
2201 Thread::SpinAcquire(&_wait_set_lock);
2202 add_waiter(node);
2203 Thread::SpinRelease(&_wait_set_lock);
2204
2205 node->_recursions = _recursions; // record the old recursion count
2206 _recursions = 0; // set the recursion level to be 0
2207 _waiters++; // increment the number of waiters
2208 exit(current); // exit the monitor
2209 guarantee(!has_owner(current), "invariant");
2210
2211 assert(java_lang_VirtualThread::state(vthread) == java_lang_VirtualThread::RUNNING, "wrong state for vthread");
2212 java_lang_VirtualThread::set_state(vthread, millis == 0 ? java_lang_VirtualThread::WAITING : java_lang_VirtualThread::TIMED_WAITING);
2217 }
2218
2219 bool ObjectMonitor::vthread_wait_reenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont) {
2220 // The first time we run after being preempted on Object.wait() we
2221 // need to check if we were interrupted or the wait timed-out, and
2222 // in that case remove ourselves from the _wait_set queue.
2223 if (node->TState == ObjectWaiter::TS_WAIT) {
2224 Thread::SpinAcquire(&_wait_set_lock);
2225 if (node->TState == ObjectWaiter::TS_WAIT) {
2226 dequeue_specific_waiter(node); // unlink from wait_set
2227 node->TState = ObjectWaiter::TS_RUN;
2228 }
2229 Thread::SpinRelease(&_wait_set_lock);
2230 }
2231
2232 // If this was an interrupted case, set the _interrupted boolean so that
2233 // once we re-acquire the monitor we know if we need to throw IE or not.
2234 ObjectWaiter::TStates state = node->TState;
2235 bool was_notified = state == ObjectWaiter::TS_ENTER;
2236 assert(was_notified || state == ObjectWaiter::TS_RUN, "");
2237 node->_interrupted = node->_interruptible && !was_notified && current->is_interrupted(false);
2238
2239 // Post JFR and JVMTI events. If non-interruptible we are in
2240 // ObjectLocker case so we don't post anything.
2241 EventJavaMonitorWait wait_event;
2242 if (node->_interruptible && (wait_event.should_commit() || JvmtiExport::should_post_monitor_waited())) {
2243 vthread_monitor_waited_event(current, node, cont, &wait_event, !was_notified && !node->_interrupted);
2244 }
2245
2246 // Mark that we are at reenter so that we don't call this method again.
2247 node->_at_reenter = true;
2248
2249 if (!was_notified) {
2250 bool acquired = vthread_monitor_enter(current, node);
2251 if (acquired) {
2252 guarantee(_recursions == 0, "invariant");
2253 _recursions = node->_recursions; // restore the old recursion count
2254 _waiters--; // decrement the number of waiters
2255
2256 if (node->_interrupted) {
2257 // We will throw at thaw end after finishing the mount transition.
2258 current->set_pending_interrupted_exception(true);
2259 }
2260
2261 delete node;
2262 // Clear the ObjectWaiter* from the vthread.
|