460 }
461
462 // NOTE: must use heavy weight monitor to handle jni monitor exit
463 void ObjectSynchronizer::jni_exit(oop obj, TRAPS) {
464 JavaThread* current = THREAD;
465
466 ObjectMonitor* monitor;
467 monitor = LightweightSynchronizer::inflate_locked_or_imse(obj, inflate_cause_jni_exit, CHECK);
468 // If this thread has locked the object, exit the monitor. We
469 // intentionally do not use CHECK on check_owner because we must exit the
470 // monitor even if an exception was already pending.
471 if (monitor->check_owner(THREAD)) {
472 monitor->exit(current);
473 current->dec_held_monitor_count(1, true);
474 }
475 }
476
477 // -----------------------------------------------------------------------------
478 // Internal VM locks on java objects
479 // standard constructor, allows locking failures
480 ObjectLocker::ObjectLocker(Handle obj, JavaThread* thread) : _npm(thread) {
481 _thread = thread;
482 _thread->check_for_valid_safepoint_state();
483 _obj = obj;
484
485 if (_obj() != nullptr) {
486 ObjectSynchronizer::enter(_obj, &_lock, _thread);
487 }
488 }
489
490 ObjectLocker::~ObjectLocker() {
491 if (_obj() != nullptr) {
492 ObjectSynchronizer::exit(_obj(), &_lock, _thread);
493 }
494 }
495
496
497 // -----------------------------------------------------------------------------
498 // Wait/Notify/NotifyAll
499 // NOTE: must use heavy weight monitor to handle wait()
500
501 int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
502 JavaThread* current = THREAD;
503 if (millis < 0) {
504 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
505 }
506
507 ObjectMonitor* monitor;
508 monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_wait, CHECK_0);
509
510 DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), current, millis);
511 monitor->wait(millis, true, THREAD); // Not CHECK as we need following code
512
513 // This dummy call is in place to get around dtrace bug 6254741. Once
514 // that's fixed we can uncomment the following line, remove the call
515 // and change this function back into a "void" func.
516 // DTRACE_MONITOR_PROBE(waited, monitor, obj(), THREAD);
517 int ret_code = dtrace_waited_probe(monitor, obj, THREAD);
518 return ret_code;
519 }
520
521 void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
522 if (millis < 0) {
523 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
524 }
525
526 ObjectMonitor* monitor;
527 monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_wait, CHECK);
528 monitor->wait(millis, false, THREAD);
529 }
530
531
532 void ObjectSynchronizer::notify(Handle obj, TRAPS) {
533 JavaThread* current = THREAD;
534
535 markWord mark = obj->mark();
536 if ((mark.is_fast_locked() && current->lock_stack().contains(obj()))) {
537 // Not inflated so there can't be any waiters to notify.
538 return;
539 }
540 ObjectMonitor* monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_notify, CHECK);
541 monitor->notify(CHECK);
542 }
543
544 // NOTE: see comment of notify()
|
460 }
461
462 // NOTE: must use heavy weight monitor to handle jni monitor exit
463 void ObjectSynchronizer::jni_exit(oop obj, TRAPS) {
464 JavaThread* current = THREAD;
465
466 ObjectMonitor* monitor;
467 monitor = LightweightSynchronizer::inflate_locked_or_imse(obj, inflate_cause_jni_exit, CHECK);
468 // If this thread has locked the object, exit the monitor. We
469 // intentionally do not use CHECK on check_owner because we must exit the
470 // monitor even if an exception was already pending.
471 if (monitor->check_owner(THREAD)) {
472 monitor->exit(current);
473 current->dec_held_monitor_count(1, true);
474 }
475 }
476
477 // -----------------------------------------------------------------------------
478 // Internal VM locks on java objects
479 // standard constructor, allows locking failures
480 ObjectLocker::ObjectLocker(Handle obj, TRAPS) : _thread(THREAD), _obj(obj),
481 _npm(_thread, _thread->at_preemptable_init() /* ignore_mark */), _skip_exit(false) {
482 assert(!_thread->preempting(), "");
483
484 _thread->check_for_valid_safepoint_state();
485
486 if (_obj() != nullptr) {
487 ObjectSynchronizer::enter(_obj, &_lock, _thread);
488
489 if (_thread->preempting()) {
490 // If preemption was cancelled we acquired the monitor after freezing
491 // the frames. Redoing the vm call laterĀ in thaw will require us to
492 // release it since the call should look like the original one. We
493 // do it in ~ObjectLocker to reduce the window of time we hold the
494 // monitor since we can't do anything useful with it now, and would
495 // otherwise just force other vthreads to preempt in case they try
496 // to acquire this monitor.
497 _skip_exit = !_thread->preemption_cancelled();
498 _thread->set_pending_preempted_exception();
499 }
500 }
501 }
502
503 ObjectLocker::~ObjectLocker() {
504 if (_obj() != nullptr && !_skip_exit) {
505 ObjectSynchronizer::exit(_obj(), &_lock, _thread);
506 }
507 }
508
509 void ObjectLocker::wait_uninterruptibly(TRAPS) {
510 ObjectSynchronizer::waitUninterruptibly(_obj, 0, _thread);
511 if (_thread->preempting()) {
512 _skip_exit = true;
513 _thread->set_pending_preempted_exception();
514 }
515 }
516
517 // -----------------------------------------------------------------------------
518 // Wait/Notify/NotifyAll
519 // NOTE: must use heavy weight monitor to handle wait()
520
521 int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
522 JavaThread* current = THREAD;
523 if (millis < 0) {
524 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
525 }
526
527 ObjectMonitor* monitor;
528 monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_wait, CHECK_0);
529
530 DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), current, millis);
531 monitor->wait(millis, true, THREAD); // Not CHECK as we need following code
532
533 // This dummy call is in place to get around dtrace bug 6254741. Once
534 // that's fixed we can uncomment the following line, remove the call
535 // and change this function back into a "void" func.
536 // DTRACE_MONITOR_PROBE(waited, monitor, obj(), THREAD);
537 int ret_code = dtrace_waited_probe(monitor, obj, THREAD);
538 return ret_code;
539 }
540
541 void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
542 assert(millis >= 0, "timeout value is negative");
543
544 ObjectMonitor* monitor;
545 monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_wait, CHECK);
546 monitor->wait(millis, false, THREAD);
547 }
548
549
550 void ObjectSynchronizer::notify(Handle obj, TRAPS) {
551 JavaThread* current = THREAD;
552
553 markWord mark = obj->mark();
554 if ((mark.is_fast_locked() && current->lock_stack().contains(obj()))) {
555 // Not inflated so there can't be any waiters to notify.
556 return;
557 }
558 ObjectMonitor* monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_notify, CHECK);
559 monitor->notify(CHECK);
560 }
561
562 // NOTE: see comment of notify()
|