< prev index next >

src/hotspot/share/services/threadService.cpp

Print this page
rev 59077 : 8153224.v2.09b.patch combined with 8153224.v2.10.patch; merge with jdk-15+21.
rev 59078 : eosterlund v2.10 CR: reorganize deflate_monitor_using_JT() to use "early exit" style; dcubed - clarify/fix/rearrange a few comments in deflate_monitor_using_JT(); eosterlund v2.10 CR: simplify install_displaced_markword_in_object() and save_om_ptr(); save_om_ptr()'s call to install_displaced_markword_in_object() can race with the deflater thread's clearing of the object field so handle that; fold 8153224.OMHandle_experiment into 8153224.v2.11.patch; merge with jdk-15+21.

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -35,10 +35,11 @@
 #include "prims/jvmtiRawMonitor.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/objectMonitor.inline.hpp"
+#include "runtime/safepointVerifiers.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadSMR.inline.hpp"
 #include "runtime/vframe.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vmOperations.hpp"

@@ -206,23 +207,31 @@
 // FIXME: JVMTI should call this function
 Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
   assert(thread != NULL, "should be non-NULL");
   debug_only(Thread::check_for_dangling_thread_pointer(thread);)
 
+  // This function can be called on a target JavaThread that is not
+  // the caller and we are not at a safepoint. So it is possible for
+  // the waiting or pending condition to be over/stale and for the
+  // first stage of async deflation to clear the object field in
+  // the ObjectMonitor. It is also possible for the object to be
+  // inflated again and to be associated with a completely different
+  // ObjectMonitor by the time this object reference is processed
+  // by the caller.
   ObjectMonitor *wait_obj = thread->current_waiting_monitor();
 
   oop obj = NULL;
   if (wait_obj != NULL) {
     // thread is doing an Object.wait() call
     obj = (oop) wait_obj->object();
-    assert(obj != NULL, "Object.wait() should have an object");
+    assert(AsyncDeflateIdleMonitors || obj != NULL, "Object.wait() should have an object");
   } else {
     ObjectMonitor *enter_obj = thread->current_pending_monitor();
     if (enter_obj != NULL) {
       // thread is trying to enter() an ObjectMonitor.
       obj = (oop) enter_obj->object();
-      assert(obj != NULL, "ObjectMonitor should have an associated object!");
+      assert(AsyncDeflateIdleMonitors || obj != NULL, "ObjectMonitor should have an associated object!");
     }
   }
 
   Handle h(Thread::current(), obj);
   return h;

@@ -389,10 +398,11 @@
     previousThread = jt;
     currentThread = jt;
 
     cycle->reset();
 
+    // The ObjectMonitor* can't be async deflated since we are at a safepoint.
     // When there is a deadlock, all the monitors involved in the dependency
     // cycle must be contended and heavyweight. So we only care about the
     // heavyweight monitor a thread is waiting to lock.
     waitingToLockMonitor = jt->current_pending_monitor();
     // JVM TI raw monitors can also be involved in deadlocks, and we can be

@@ -965,17 +975,17 @@
   st->cr();
   st->print_cr("Found one Java-level deadlock:");
   st->print("=============================");
 
   JavaThread* currentThread;
-  ObjectMonitor* waitingToLockMonitor;
   JvmtiRawMonitor* waitingToLockRawMonitor;
   oop waitingToLockBlocker;
   int len = _threads->length();
   for (int i = 0; i < len; i++) {
     currentThread = _threads->at(i);
-    waitingToLockMonitor = currentThread->current_pending_monitor();
+    // The ObjectMonitor* can't be async deflated since we are at a safepoint.
+    ObjectMonitor* waitingToLockMonitor = currentThread->current_pending_monitor();
     waitingToLockRawMonitor = currentThread->current_pending_raw_monitor();
     waitingToLockBlocker = currentThread->current_park_blocker();
     st->cr();
     st->print_cr("\"%s\":", currentThread->get_thread_name());
     const char* owner_desc = ",\n  which is held by";
< prev index next >