changeset 5843:e14a43e8767f

8210094: Better loading of classloader classes Reviewed-by: adinn, andrew
author mbalao
date Thu, 07 Feb 2019 05:28:56 +0000
parents 87cbcaecf4e4
children 7e4523af00b7
files src/share/vm/classfile/classLoaderDependencies.cpp src/share/vm/classfile/classLoaderDependencies.hpp src/share/vm/classfile/dictionary.cpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/verificationType.cpp src/share/vm/classfile/verifier.cpp src/share/vm/prims/jvm.cpp
diffstat 7 files changed, 30 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoaderDependencies.cpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/classfile/classLoaderDependencies.cpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. and/or its affiliates.
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -28,35 +28,30 @@
 #include "memory/oopFactory.hpp"
 #include "utilities/debug.hpp"
 
-void ClassLoaderDependencies::record_dependency(KlassHandle from_klass,
-                                                KlassHandle to_klass,
+void ClassLoaderDependencies::record_dependency(oop from_class_loader,
+                                                oop to_class_loader,
                                                 TRAPS) {
-
-  oop to_class_loader_oop = to_klass->class_loader();
-
   // Dependency to the Null Class Loader doesn't
   // need to be recorded because it never goes away.
-  if (to_class_loader_oop == NULL) {
+  if (to_class_loader == NULL) {
     return;
   }
 
-  oop from_class_loader_oop = from_klass->class_loader();
-
   // The Null Class Loader does not generate dependencies to record.
-  if (from_class_loader_oop == NULL) {
+  if (from_class_loader == NULL) {
     return;
   }
 
-  oop current_class_loader_oop = from_class_loader_oop;
+  oop current_class_loader_oop = from_class_loader;
   do {
-    if (current_class_loader_oop == to_class_loader_oop) {
+    if (current_class_loader_oop == to_class_loader) {
       return; // This class loader is in the parent list, no need to add it.
     }
     current_class_loader_oop = java_lang_ClassLoader::parent(current_class_loader_oop);
   } while (current_class_loader_oop != NULL);
 
-  ClassLoaderDependencies::add(Handle(THREAD, from_class_loader_oop),
-                               Handle(THREAD, to_class_loader_oop),
+  ClassLoaderDependencies::add(Handle(THREAD, from_class_loader),
+                               Handle(THREAD, to_class_loader),
                                CHECK);
 }
 
--- a/src/share/vm/classfile/classLoaderDependencies.hpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/classfile/classLoaderDependencies.hpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. and/or its affiliates.
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -30,7 +30,7 @@
 
 class ClassLoaderDependencies {
 public:
-  static void record_dependency(KlassHandle from_klass, KlassHandle to_klass, TRAPS);
+  static void record_dependency(oop from_class_loader, oop to_class_loader, TRAPS);
 private:
   static void add(Handle from_class_loader_h, Handle dependency, TRAPS);
   static void locked_add(objArrayHandle list_head, objArrayHandle last_handle, objArrayHandle new_dependency, TRAPS);
--- a/src/share/vm/classfile/dictionary.cpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/classfile/dictionary.cpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -230,9 +230,6 @@
         oop k_def_class_loader = ik->class_loader();
 
         // Do we need to delete this system dictionary entry?
-        bool purge_entry = false;
-
-        // Do we need to delete this system dictionary entry?
         if (!is_alive->do_object_b(class_loader)) {
           // If the loader is not live this entry should always be
           // removed (will never be looked up again). Note that this is
@@ -255,28 +252,7 @@
             // Clean up C heap
             ik->release_C_heap_structures();
           }
-          // Also remove this system dictionary entry.
-          purge_entry = true;
-
-        } else {
-          // The loader in this entry is alive. If the klass is dead,
-          // the loader must be an initiating loader (rather than the
-          // defining loader). Remove this entry.
-          if (!is_alive->do_object_b(e)) {
-            guarantee(!is_alive->do_object_b(k_def_class_loader),
-                      "defining loader should not be live if klass is not");
-            // If we get here, the class_loader must not be the defining
-            // loader, it must be an initiating one.
-            assert(k_def_class_loader != class_loader,
-                   "cannot have live defining loader and unreachable klass");
-
-            // Loader is live, but class and its defining loader are dead.
-            // Remove the entry. The class is going away.
-            purge_entry = true;
-          }
-        }
-
-        if (purge_entry) {
+          // Remove this system dictionary entry.
           *p = probe->next();
           if (probe == _current_class_entry) {
             _current_class_entry = NULL;
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderDependencies.hpp"
 #include "classfile/dictionary.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/loaderConstraints.hpp"
@@ -813,7 +814,17 @@
         check_constraints(d_index, d_hash, k, class_loader, false, THREAD);
 
         // Need to check for a PENDING_EXCEPTION again; check_constraints
-        // can throw and doesn't use the CHECK macro.
+        // can throw but we may have to remove entry from the placeholder table below.
+        if (!HAS_PENDING_EXCEPTION) {
+            // Record dependency for non-parent delegation.
+            // This recording keeps the defining class loader of the klass (k) found
+            // from being unloaded while the initiating class loader is loaded
+            // even if the reference to the defining class loader is dropped
+            // before references to the initiating class loader.
+            ClassLoaderDependencies::record_dependency(class_loader(),
+                    k->class_loader(), THREAD);
+        }
+
         if (!HAS_PENDING_EXCEPTION) {
           { // Grabbing the Compile_lock prevents systemDictionary updates
             // during compilations.
--- a/src/share/vm/classfile/verificationType.cpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/classfile/verificationType.cpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -23,7 +23,6 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/classLoaderDependencies.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/verificationType.hpp"
 #include "classfile/verifier.hpp"
@@ -63,8 +62,6 @@
         Handle(THREAD, klass->protection_domain()), true, CHECK_false);
     KlassHandle this_class(THREAD, obj);
 
-    ClassLoaderDependencies::record_dependency(klass, this_class, CHECK_false);
-
     if (this_class->is_interface()) {
       // We treat interfaces as java.lang.Object, including
       // java.lang.Cloneable and java.io.Serializable
@@ -74,7 +71,6 @@
           from.name(), Handle(THREAD, klass->class_loader()),
           Handle(THREAD, klass->protection_domain()), true, CHECK_false);
       KlassHandle from_class_handle(THREAD, from_class);
-      ClassLoaderDependencies::record_dependency(klass, from_class_handle, CHECK_false);
       return instanceKlass::cast(from_class_handle())->is_subclass_of(this_class());
     }
   } else if (is_array() && from.is_array()) {
--- a/src/share/vm/classfile/verifier.cpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/classfile/verifier.cpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -24,7 +24,6 @@
 
 #include "precompiled.hpp"
 #include "classfile/classFileStream.hpp"
-#include "classfile/classLoaderDependencies.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/stackMapTable.hpp"
 #include "classfile/stackMapFrame.hpp"
@@ -1927,11 +1926,9 @@
   oop loader = current_class()->class_loader();
   oop protection_domain = current_class()->protection_domain();
 
-  klassOop kls = SystemDictionary::resolve_or_fail(
+  return SystemDictionary::resolve_or_fail(
     name, Handle(THREAD, loader), Handle(THREAD, protection_domain),
     true, CHECK_NULL);
-  ClassLoaderDependencies::record_dependency(current_class(), kls, CHECK_NULL);
-  return kls;
 }
 
 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
--- a/src/share/vm/prims/jvm.cpp	Thu Feb 07 05:19:56 2019 +0000
+++ b/src/share/vm/prims/jvm.cpp	Thu Feb 07 05:28:56 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -24,7 +24,6 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
-#include "classfile/classLoaderDependencies.hpp"
 #include "classfile/javaAssertions.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/symbolTable.hpp"
@@ -914,14 +913,6 @@
   jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
                                                h_prot, true, thread);
 
-  if (result != NULL) {
-    from_class_oop = JNIHandles::resolve(from);
-    from_class = java_lang_Class::as_klassOop(from_class_oop);
-    oop mirror = JNIHandles::resolve_non_null(result);
-    klassOop to_class = java_lang_Class::as_klassOop(mirror);
-    ClassLoaderDependencies::record_dependency(from_class, to_class, CHECK_NULL);
-  }
-
   if (TraceClassResolution && result != NULL) {
     // this function is generally only used for class loading during verification.
     ResourceMark rm;