< prev index next >

src/hotspot/share/runtime/objectMonitor.cpp

Print this page

 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.
< prev index next >