< prev index next >

src/hotspot/share/runtime/synchronizer.cpp

Print this page
*** 711,26 ***
  }
  
  // -----------------------------------------------------------------------------
  // Internal VM locks on java objects
  // standard constructor, allows locking failures
! ObjectLocker::ObjectLocker(Handle obj, JavaThread* thread) : _npm(thread) {
!   _thread = thread;
    _thread->check_for_valid_safepoint_state();
-   _obj = obj;
  
    if (_obj() != nullptr) {
      ObjectSynchronizer::enter(_obj, &_lock, _thread);
    }
  }
  
  ObjectLocker::~ObjectLocker() {
!   if (_obj() != nullptr) {
      ObjectSynchronizer::exit(_obj(), &_lock, _thread);
    }
  }
  
  
  // -----------------------------------------------------------------------------
  //  Wait/Notify/NotifyAll
  // NOTE: must use heavy weight monitor to handle wait()
  
--- 711,47 ---
  }
  
  // -----------------------------------------------------------------------------
  // Internal VM locks on java objects
  // standard constructor, allows locking failures
! ObjectLocker::ObjectLocker(Handle obj, TRAPS) : _thread(THREAD), _obj(obj),
!   _npm(_thread, _thread->at_preemptable_init() /* ignore_mark */), _skip_exit(false) {
+   assert(!_thread->preempting(), "");
+ 
    _thread->check_for_valid_safepoint_state();
  
    if (_obj() != nullptr) {
      ObjectSynchronizer::enter(_obj, &_lock, _thread);
+ 
+     if (_thread->preempting()) {
+       // If preemption was cancelled we acquired the monitor after freezing
+       // the frames. Redoing the vm call laterĀ in thaw will require us to
+       // release it since the call should look like the original one. We
+       // do it in ~ObjectLocker to reduce the window of time we hold the
+       // monitor since we can't do anything useful with it now, and would
+       // otherwise just force other vthreads to preempt in case they try
+       // to acquire this monitor.
+       _skip_exit = !_thread->preemption_cancelled();
+       _thread->set_pending_preempted_exception();
+     }
    }
  }
  
  ObjectLocker::~ObjectLocker() {
!   if (_obj() != nullptr && !_skip_exit) {
      ObjectSynchronizer::exit(_obj(), &_lock, _thread);
    }
  }
  
+ void ObjectLocker::wait_uninterruptibly(TRAPS) {
+   ObjectSynchronizer::waitUninterruptibly(_obj, 0, _thread);
+   if (_thread->preempting()) {
+     _skip_exit = true;
+     _thread->set_pending_preempted_exception();
+     _thread->set_class_to_be_initialized(nullptr);
+   }
+ }
  
  // -----------------------------------------------------------------------------
  //  Wait/Notify/NotifyAll
  // NOTE: must use heavy weight monitor to handle wait()
  

*** 760,13 ***
    int ret_code = dtrace_waited_probe(monitor, obj, THREAD);
    return ret_code;
  }
  
  void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
!   if (millis < 0) {
-     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
-   }
  
    ObjectMonitor* monitor;
    if (LockingMode == LM_LIGHTWEIGHT) {
      monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_wait, CHECK);
    } else {
--- 781,11 ---
    int ret_code = dtrace_waited_probe(monitor, obj, THREAD);
    return ret_code;
  }
  
  void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
!   assert(millis >= 0, "timeout value is negative");
  
    ObjectMonitor* monitor;
    if (LockingMode == LM_LIGHTWEIGHT) {
      monitor = LightweightSynchronizer::inflate_locked_or_imse(obj(), inflate_cause_wait, CHECK);
    } else {
< prev index next >