hotspot/src/share/vm/classfile/systemDictionary.cpp
changeset 43948 26f3c55e246e
parent 42876 ff8ff9dcccec
child 46327 91576389a517
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Feb 10 20:45:39 2017 +0300
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri Feb 10 17:22:17 2017 +0100
@@ -1152,21 +1152,26 @@
   Symbol* h_name = k->name();
   assert(class_name == NULL || class_name == h_name, "name mismatch");
 
-  bool define_succeeded = false;
   // Add class just loaded
   // If a class loader supports parallel classloading handle parallel define requests
   // find_or_define_instance_class may return a different InstanceKlass
   if (is_parallelCapable(class_loader)) {
-    instanceKlassHandle defined_k = find_or_define_instance_class(h_name, class_loader, k, CHECK_NULL);
-    if (k() == defined_k()) {
-      // we have won over other concurrent threads (if any) that are
-      // competing to define the same class.
-      define_succeeded = true;
+    instanceKlassHandle defined_k = find_or_define_instance_class(h_name, class_loader, k, THREAD);
+    if (!HAS_PENDING_EXCEPTION && defined_k() != k()) {
+      // If a parallel capable class loader already defined this class, register 'k' for cleanup.
+      assert(defined_k.not_null(), "Should have a klass if there's no exception");
+      loader_data->add_to_deallocate_list(k());
+      k = defined_k;
     }
-    k = defined_k;
   } else {
-    define_instance_class(k, CHECK_NULL);
-    define_succeeded = true;
+    define_instance_class(k, THREAD);
+  }
+
+  // If defining the class throws an exception register 'k' for cleanup.
+  if (HAS_PENDING_EXCEPTION) {
+    assert(k.not_null(), "Must have an instance klass here!");
+    loader_data->add_to_deallocate_list(k());
+    return NULL;
   }
 
   // Make sure we have an entry in the SystemDictionary on success
@@ -1518,8 +1523,16 @@
     // find_or_define_instance_class may return a different InstanceKlass
     if (!k.is_null()) {
       instanceKlassHandle defined_k =
-        find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
-      k = defined_k;
+        find_or_define_instance_class(class_name, class_loader, k, THREAD);
+      if (!HAS_PENDING_EXCEPTION && defined_k() != k()) {
+        // If a parallel capable class loader already defined this class, register 'k' for cleanup.
+        assert(defined_k.not_null(), "Should have a klass if there's no exception");
+        loader_data->add_to_deallocate_list(k());
+        k = defined_k;
+      } else if (HAS_PENDING_EXCEPTION) {
+        loader_data->add_to_deallocate_list(k());
+        return nh;
+      }
     }
     return k;
   } else {