8199882: compiler/uncommontrap/TestDeoptOOM.java failed w/ fatal error: ExceptionMark constructor expects no pending exceptions
authordholmes
Tue, 05 Jun 2018 19:58:20 -0400
changeset 50419 146c60525d4a
parent 50418 c35f0c531c6c
child 50420 912c5c042c19
8199882: compiler/uncommontrap/TestDeoptOOM.java failed w/ fatal error: ExceptionMark constructor expects no pending exceptions Summary: Pre-load AbstractOwnableSynchronizer class instead of lazy loading it. Reviewed-by: sspitsyn, cjplummer, coleenp
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/classfile/systemDictionary.cpp
src/hotspot/share/classfile/systemDictionary.hpp
src/hotspot/share/runtime/vm_operations.cpp
src/hotspot/share/runtime/vm_operations.hpp
src/hotspot/share/services/management.cpp
src/hotspot/share/services/threadService.cpp
--- a/src/hotspot/share/classfile/javaClasses.cpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Tue Jun 05 19:58:20 2018 -0400
@@ -4257,7 +4257,7 @@
 int java_lang_AssertionStatusDirectives::packageEnabled_offset;
 int java_lang_AssertionStatusDirectives::deflt_offset;
 int java_nio_Buffer::_limit_offset;
-int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset = 0;
+int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset;
 int reflect_ConstantPool::_oop_offset;
 int reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
 
@@ -4399,13 +4399,12 @@
 }
 #endif
 
-void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
-  if (_owner_offset != 0) return;
-
-  SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK);
-  InstanceKlass* k = SystemDictionary::abstract_ownable_synchronizer_klass();
-  compute_offset(_owner_offset, k,
-                 "exclusiveOwnerThread", vmSymbols::thread_signature());
+#define AOS_FIELDS_DO(macro) \
+  macro(_owner_offset, k, "exclusiveOwnerThread", thread_signature, false)
+
+void java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets() {
+  InstanceKlass* k = SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass();
+  AOS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
 }
 
 oop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(oop obj) {
@@ -4473,6 +4472,7 @@
   java_lang_StackTraceElement::compute_offsets();
   java_lang_StackFrameInfo::compute_offsets();
   java_lang_LiveStackFrameInfo::compute_offsets();
+  java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets();
 
   // generated interpreter code wants to know about the offsets we just computed:
   AbstractAssembler::update_delayed_values();
--- a/src/hotspot/share/classfile/javaClasses.hpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Tue Jun 05 19:58:20 2018 -0400
@@ -1483,7 +1483,7 @@
  private:
   static int  _owner_offset;
  public:
-  static void initialize(TRAPS);
+  static void compute_offsets();
   static oop  get_owner_threadObj(oop obj);
 };
 
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue Jun 05 19:58:20 2018 -0400
@@ -110,9 +110,6 @@
 
 bool        SystemDictionary::_has_checkPackageAccess     =  false;
 
-// lazily initialized klass variables
-InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
-
 // Default ProtectionDomainCacheSize value
 
 const int defaultProtectionDomainCacheSize = 1009;
@@ -1897,22 +1894,6 @@
 }
 
 // ----------------------------------------------------------------------------
-// Lazily load klasses
-
-void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
-  // if multiple threads calling this function, only one thread will load
-  // the class.  The other threads will find the loaded version once the
-  // class is loaded.
-  Klass* aos = _abstract_ownable_synchronizer_klass;
-  if (aos == NULL) {
-    Klass* k = resolve_or_fail(vmSymbols::java_util_concurrent_locks_AbstractOwnableSynchronizer(), true, CHECK);
-    // Force a fence to prevent any read before the write completes
-    OrderAccess::fence();
-    _abstract_ownable_synchronizer_klass = InstanceKlass::cast(k);
-  }
-}
-
-// ----------------------------------------------------------------------------
 // Initialization
 
 void SystemDictionary::initialize(TRAPS) {
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Tue Jun 05 19:58:20 2018 -0400
@@ -199,6 +199,9 @@
   do_klass(StackFrameInfo_klass,                        java_lang_StackFrameInfo,                  Opt                 ) \
   do_klass(LiveStackFrameInfo_klass,                    java_lang_LiveStackFrameInfo,              Opt                 ) \
                                                                                                                          \
+  /* support for stack dump lock analysis */                                                                             \
+  do_klass(java_util_concurrent_locks_AbstractOwnableSynchronizer_klass, java_util_concurrent_locks_AbstractOwnableSynchronizer, Pre ) \
+                                                                                                                         \
   /* Preload boxing klasses */                                                                                           \
   do_klass(Boolean_klass,                               java_lang_Boolean,                         Pre                 ) \
   do_klass(Character_klass,                             java_lang_Character,                       Pre                 ) \
@@ -449,12 +452,6 @@
   }
   static BasicType box_klass_type(Klass* k);  // inverse of box_klass
 
-  // methods returning lazily loaded klasses
-  // The corresponding method to load the class must be called before calling them.
-  static InstanceKlass* abstract_ownable_synchronizer_klass() { return check_klass(_abstract_ownable_synchronizer_klass); }
-
-  static void load_abstract_ownable_synchronizer_klass(TRAPS);
-
 protected:
   // Returns the class loader data to be used when looking up/updating the
   // system dictionary.
@@ -729,9 +726,6 @@
   // Variables holding commonly used klasses (preloaded)
   static InstanceKlass* _well_known_klasses[];
 
-  // Lazily loaded klasses
-  static InstanceKlass* volatile _abstract_ownable_synchronizer_klass;
-
   // table of box klasses (int_klass, etc.)
   static InstanceKlass* _box_klasses[T_VOID+1];
 
--- a/src/hotspot/share/runtime/vm_operations.cpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/runtime/vm_operations.cpp	Tue Jun 05 19:58:20 2018 -0400
@@ -204,13 +204,6 @@
 }
 
 bool VM_PrintThreads::doit_prologue() {
-  // Make sure AbstractOwnableSynchronizer is loaded
-  JavaThread* jt = JavaThread::current();
-  java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
-  if (jt->has_pending_exception()) {
-    return false;
-  }
-
   // Get Heap_lock if concurrent locks will be dumped
   if (_print_concurrent_locks) {
     Heap_lock->lock();
@@ -248,19 +241,6 @@
   }
 }
 
-bool VM_FindDeadlocks::doit_prologue() {
-  if (_concurrent_locks) {
-    // Make sure AbstractOwnableSynchronizer is loaded
-    JavaThread* jt = JavaThread::current();
-    java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
-    if (jt->has_pending_exception()) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 void VM_FindDeadlocks::doit() {
   // Update the hazard ptr in the originating thread to the current
   // list of threads. This VM operation needs the current list of
@@ -316,13 +296,6 @@
 }
 
 bool VM_ThreadDump::doit_prologue() {
-  // Make sure AbstractOwnableSynchronizer is loaded
-  JavaThread* jt = JavaThread::current();
-  java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(jt);
-  if (jt->has_pending_exception()) {
-    return false;
-  }
-
   if (_with_locked_synchronizers) {
     // Acquire Heap_lock to dump concurrent locks
     Heap_lock->lock();
--- a/src/hotspot/share/runtime/vm_operations.hpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/runtime/vm_operations.hpp	Tue Jun 05 19:58:20 2018 -0400
@@ -421,7 +421,6 @@
   DeadlockCycle* result()      { return _deadlocks; };
   VMOp_Type type() const       { return VMOp_FindDeadlocks; }
   void doit();
-  bool doit_prologue();
 };
 
 class ThreadDumpResult;
--- a/src/hotspot/share/services/management.cpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/services/management.cpp	Tue Jun 05 19:58:20 2018 -0400
@@ -1081,9 +1081,6 @@
                "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
   }
 
-  // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
-  java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
-
   // Must use ThreadDumpResult to store the ThreadSnapshot.
   // GC may occur after the thread snapshots are taken but before
   // this function returns. The threadObj and other oops kept
@@ -1154,9 +1151,6 @@
                                         jboolean locked_synchronizers, jint maxDepth))
   ResourceMark rm(THREAD);
 
-  // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
-  java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
-
   typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
   int num_threads = (ta != NULL ? ta->length() : 0);
   typeArrayHandle ids_ah(THREAD, ta);
--- a/src/hotspot/share/services/threadService.cpp	Tue Jun 05 21:38:38 2018 +0200
+++ b/src/hotspot/share/services/threadService.cpp	Tue Jun 05 19:58:20 2018 -0400
@@ -369,7 +369,7 @@
         }
       } else {
         if (concurrent_locks) {
-          if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
+          if (waitingToLockBlocker->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
             oop threadObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
             // This JavaThread (if there is one) is protected by the
             // ThreadsListSetter in VM_FindDeadlocks::doit().
@@ -678,8 +678,8 @@
   GrowableArray<oop>* aos_objects = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true /* C_heap */);
 
   // Find all instances of AbstractOwnableSynchronizer
-  HeapInspection::find_instances_at_safepoint(SystemDictionary::abstract_ownable_synchronizer_klass(),
-                                                aos_objects);
+  HeapInspection::find_instances_at_safepoint(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass(),
+                                              aos_objects);
   // Build a map of thread to its owned AQS locks
   build_map(aos_objects);
 
@@ -832,7 +832,7 @@
          _thread_status == java_lang_Thread::PARKED_TIMED)) {
 
     _blocker_object = thread->current_park_blocker();
-    if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) {
+    if (_blocker_object != NULL && _blocker_object->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
       _blocker_object_owner = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(_blocker_object);
     }
   }
@@ -923,7 +923,7 @@
       st->print("  waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
                 p2i(waitingToLockBlocker),
                 waitingToLockBlocker->klass()->external_name());
-      assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
+      assert(waitingToLockBlocker->is_a(SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass()),
              "Must be an AbstractOwnableSynchronizer");
       oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
       currentThread = java_lang_Thread::thread(ownerObj);