< prev index next >

src/hotspot/share/runtime/objectMonitor.cpp

Print this page
@@ -332,16 +332,11 @@
      // 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;
-   }
+   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 +1144,29 @@
  // 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
+     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!");
+     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;
-     }
+     return;
    }
  
    if (_recursions != 0) {
      _recursions--;        // this is simple recursive enter
      return;

@@ -1353,15 +1359,11 @@
  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;
-     }
+     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 +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;
    }
-   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,

@@ -2011,16 +2009,10 @@
  // 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
< prev index next >