< prev index next >

src/hotspot/share/runtime/objectMonitor.cpp

Print this page
*** 332,16 ***
      // TODO-FIXME: check for integer overflow!  BUGID 6557169.
      _recursions++;
      return true;
    }
  
!   if (current->is_lock_owned((address)cur)) {
-     assert(_recursions == 0, "internal state error");
-     _recursions = 1;
-     set_owner_from_BasicLock(cur, current);  // Convert from BasicLock* to Thread*.
-     return true;
-   }
  
    // We've encountered genuine contention.
    assert(current->_Stalled == 0, "invariant");
    current->_Stalled = intptr_t(this);
  
--- 332,11 ---
      // TODO-FIXME: check for integer overflow!  BUGID 6557169.
      _recursions++;
      return true;
    }
  
!   assert(cur == ANONYMOUS_OWNER || !current->is_lock_owned((address)cur), "precondition");
  
    // We've encountered genuine contention.
    assert(current->_Stalled == 0, "invariant");
    current->_Stalled = intptr_t(this);
  

*** 598,10 ***
--- 593,26 ---
    // We leave owner == DEFLATER_MARKER and contentions < 0
    // to force any racing threads to retry.
    return true;  // Success, ObjectMonitor has been deflated.
  }
  
+ // We might access the dead object headers for parsable heap walk, make sure
+ // headers are in correct shape, e.g. monitors deflated.
+ void ObjectMonitor::maybe_deflate_dead(oop* p) {
+   oop obj = *p;
+   assert(obj != NULL, "must not yet been cleared");
+   markWord mark = obj->mark();
+   if (mark.has_monitor()) {
+     ObjectMonitor* monitor = mark.monitor();
+     if (p == monitor->_object.ptr_raw()) {
+       assert(monitor->object_peek() == obj, "lock object must match");
+       markWord dmw = monitor->header();
+       obj->set_mark(dmw);
+     }
+   }
+ }
+ 
  // Install the displaced mark word (dmw) of a deflating ObjectMonitor
  // into the header of the object associated with the monitor. This
  // idempotent method is called by a thread that is deflating a
  // monitor and by other threads that have detected a race with the
  // deflation process.

*** 1133,34 ***
  // of such futile wakups is low.
  
  void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
    void* cur = owner_raw();
    if (current != cur) {
!     if (current->is_lock_owned((address)cur)) {
!       assert(_recursions == 0, "invariant");
!       set_owner_from_BasicLock(cur, current);  // Convert from BasicLock* to Thread*.
!       _recursions = 0;
!     } else {
!       // Apparent unbalanced locking ...
!       // Naively we'd like to throw IllegalMonitorStateException.
!       // As a practical matter we can neither allocate nor throw an
!       // exception as ::exit() can be called from leaf routines.
!       // see x86_32.ad Fast_Unlock() and the I1 and I2 properties.
-       // Upon deeper reflection, however, in a properly run JVM the only
-       // way we should encounter this situation is in the presence of
-       // unbalanced JNI locking. TODO: CheckJNICalls.
-       // See also: CR4414101
  #ifdef ASSERT
!       LogStreamHandle(Error, monitorinflation) lsh;
!       lsh.print_cr("ERROR: ObjectMonitor::exit(): thread=" INTPTR_FORMAT
!                     " is exiting an ObjectMonitor it does not own.", p2i(current));
!       lsh.print_cr("The imbalance is possibly caused by JNI locking.");
!       print_debug_style_on(&lsh);
!       assert(false, "Non-balanced monitor enter/exit!");
  #endif
!       return;
-     }
    }
  
    if (_recursions != 0) {
      _recursions--;        // this is simple recursive enter
      return;
--- 1144,29 ---
  // of such futile wakups is low.
  
  void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
    void* cur = owner_raw();
    if (current != cur) {
!     assert(!current->is_lock_owned((address)cur), "no stack-locking");
!     // Apparent unbalanced locking ...
!     // Naively we'd like to throw IllegalMonitorStateException.
!     // As a practical matter we can neither allocate nor throw an
!     // exception as ::exit() can be called from leaf routines.
!     // see x86_32.ad Fast_Unlock() and the I1 and I2 properties.
!     // Upon deeper reflection, however, in a properly run JVM the only
!     // way we should encounter this situation is in the presence of
!     // unbalanced JNI locking. TODO: CheckJNICalls.
!     // See also: CR4414101
  #ifdef ASSERT
!     LogStreamHandle(Error, monitorinflation) lsh;
!     lsh.print_cr("ERROR: ObjectMonitor::exit(): thread=" INTPTR_FORMAT
!                   " is exiting an ObjectMonitor it does not own.", p2i(current));
!     lsh.print_cr("The imbalance is possibly caused by JNI locking.");
!     print_debug_style_on(&lsh);
!     assert(false, "Non-balanced monitor enter/exit! " PTR_FORMAT, p2i(object()));
  #endif
!     return;
    }
  
    if (_recursions != 0) {
      _recursions--;        // this is simple recursive enter
      return;

*** 1353,15 ***
  intx ObjectMonitor::complete_exit(JavaThread* current) {
    assert(InitDone, "Unexpectedly not initialized");
  
    void* cur = owner_raw();
    if (current != cur) {
!     if (current->is_lock_owned((address)cur)) {
-       assert(_recursions == 0, "internal state error");
-       set_owner_from_BasicLock(cur, current);  // Convert from BasicLock* to Thread*.
-       _recursions = 0;
-     }
    }
  
    guarantee(current == owner_raw(), "complete_exit not owner");
    intx save = _recursions; // record the old recursion count
    _recursions = 0;         // set the recursion level to be 0
--- 1359,11 ---
  intx ObjectMonitor::complete_exit(JavaThread* current) {
    assert(InitDone, "Unexpectedly not initialized");
  
    void* cur = owner_raw();
    if (current != cur) {
!     assert(!current->is_lock_owned((address)cur), "no stack-locking");
    }
  
    guarantee(current == owner_raw(), "complete_exit not owner");
    intx save = _recursions; // record the old recursion count
    _recursions = 0;         // set the recursion level to be 0

*** 1402,18 ***
  // (IMSE). If there is a pending exception and the specified thread
  // is not the owner, that exception will be replaced by the IMSE.
  bool ObjectMonitor::check_owner(TRAPS) {
    JavaThread* current = THREAD;
    void* cur = owner_raw();
    if (cur == current) {
      return true;
    }
-   if (current->is_lock_owned((address)cur)) {
-     set_owner_from_BasicLock(cur, current);  // Convert from BasicLock* to Thread*.
-     _recursions = 0;
-     return true;
-   }
    THROW_MSG_(vmSymbols::java_lang_IllegalMonitorStateException(),
               "current thread is not owner", false);
  }
  
  static void post_monitor_wait_event(EventJavaMonitorWait* event,
--- 1404,14 ---
  // (IMSE). If there is a pending exception and the specified thread
  // is not the owner, that exception will be replaced by the IMSE.
  bool ObjectMonitor::check_owner(TRAPS) {
    JavaThread* current = THREAD;
    void* cur = owner_raw();
+   assert(cur != ANONYMOUS_OWNER, "no anon owner here");
    if (cur == current) {
      return true;
    }
    THROW_MSG_(vmSymbols::java_lang_IllegalMonitorStateException(),
               "current thread is not owner", false);
  }
  
  static void post_monitor_wait_event(EventJavaMonitorWait* event,

*** 2011,16 ***
  // Because of the lifecycle issues, the _thread_state values
  // observed by NotRunnable() might be garbage.  NotRunnable must
  // tolerate this and consider the observed _thread_state value
  // as advisory.
  //
- // Beware too, that _owner is sometimes a BasicLock address and sometimes
- // a thread pointer.
- // Alternately, we might tag the type (thread pointer vs basiclock pointer)
- // with the LSB of _owner.  Another option would be to probabilistically probe
- // the putative _owner->TypeTag value.
- //
  // Checking _thread_state isn't perfect.  Even if the thread is
  // in_java it might be blocked on a page-fault or have been preempted
  // and sitting on a ready/dispatch queue.
  //
  // The return value from NotRunnable() is *advisory* -- the
--- 2009,10 ---
< prev index next >