changeset 51268:c349d409262a

8202605: Standardize on ClassLoaderData::loader_name() throughout the VM to obtain a class loader's name Summary: Introduced ClassLoaderData::name() and ClassLoaderData::name_and_id() for use when obtaining a class loader's name. Reviewed-by: coleenp, goetz, mchung, stuefe
author lfoltan
date Tue, 19 Jun 2018 07:54:11 -0400
parents b8055b38b252
children 5d3c5af82654
files src/hotspot/share/classfile/classFileParser.cpp src/hotspot/share/classfile/classLoaderData.cpp src/hotspot/share/classfile/classLoaderData.hpp src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp src/hotspot/share/classfile/dictionary.cpp src/hotspot/share/classfile/javaClasses.cpp src/hotspot/share/classfile/javaClasses.hpp src/hotspot/share/classfile/loaderConstraints.cpp src/hotspot/share/classfile/moduleEntry.cpp src/hotspot/share/classfile/modules.cpp src/hotspot/share/classfile/systemDictionary.cpp src/hotspot/share/classfile/systemDictionary.hpp src/hotspot/share/gc/serial/defNewGeneration.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp src/hotspot/share/oops/instanceKlass.cpp src/hotspot/share/oops/instanceKlass.hpp src/java.base/share/classes/java/lang/ClassLoader.java test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java
diffstat 27 files changed, 242 insertions(+), 170 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classFileParser.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -4511,7 +4511,7 @@
           vmSymbols::java_lang_IllegalAccessError(),
           "class %s loaded by %s cannot access jdk/internal/reflect superclass %s",
           this_klass->external_name(),
-          this_klass->class_loader_data()->loader_name(),
+          this_klass->class_loader_data()->loader_name_and_id(),
           super->external_name());
         return;
       }
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -105,22 +105,41 @@
   }
 }
 
-// JFR and logging support so that the name and klass are available after the
-// class_loader oop is no longer alive, during unloading.
+// Obtain and set the class loader's name within the ClassLoaderData so
+// it will be available for error messages, logging, JFR, etc.  The name
+// and klass are available after the class_loader oop is no longer alive,
+// during unloading.
 void ClassLoaderData::initialize_name_and_klass(Handle class_loader) {
+  Thread* THREAD = Thread::current();
+  ResourceMark rm(THREAD);
   _class_loader_klass = class_loader->klass();
-  oop class_loader_name = java_lang_ClassLoader::name(class_loader());
-  if (class_loader_name != NULL) {
-    Thread* THREAD = Thread::current();
-    ResourceMark rm(THREAD);
-    const char* class_loader_instance_name =
-      java_lang_String::as_utf8_string(class_loader_name);
 
-    if (class_loader_instance_name != NULL && class_loader_instance_name[0] != '\0') {
+  // Obtain the class loader's name.  If the class loader's name was not
+  // explicitly set during construction, the CLD's _name field will be null.
+  oop cl_name = java_lang_ClassLoader::name(class_loader());
+  if (cl_name != NULL) {
+    const char* cl_instance_name = java_lang_String::as_utf8_string(cl_name);
+
+    if (cl_instance_name != NULL && cl_instance_name[0] != '\0') {
       // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.
-      _class_loader_name = SymbolTable::new_symbol(class_loader_instance_name, CATCH);
+      _name = SymbolTable::new_symbol(cl_instance_name, CATCH);
     }
   }
+
+  // Obtain the class loader's name and identity hash.  If the class loader's
+  // name was not explicitly set during construction, the class loader's name and id
+  // will be set to the qualified class name of the class loader along with its
+  // identity hash.
+  // If for some reason the ClassLoader's constructor has not been run, instead of
+  // leaving the _name_and_id field null, fall back to the external qualified class
+  // name.  Thus CLD's _name_and_id field should never have a null value.
+  oop cl_name_and_id = java_lang_ClassLoader::nameAndId(class_loader());
+  const char* cl_instance_name_and_id =
+                  (cl_name_and_id == NULL) ? _class_loader_klass->external_name() :
+                                             java_lang_String::as_utf8_string(cl_name_and_id);
+  assert(cl_instance_name_and_id != NULL && cl_instance_name_and_id[0] != '\0', "class loader has no name and id");
+  // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.
+  _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH);
 }
 
 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) :
@@ -134,7 +153,7 @@
   _claimed(0), _modified_oops(true), _accumulated_modified_oops(false),
   _jmethod_ids(NULL), _handles(), _deallocate_list(NULL),
   _next(NULL),
-  _class_loader_klass(NULL), _class_loader_name(NULL),
+  _class_loader_klass(NULL), _name(NULL), _name_and_id(NULL),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)) {
 
@@ -911,29 +930,40 @@
   return ClassLoaderDataGraph::add(loader, true);
 }
 
+// Caller needs ResourceMark
+// If the class loader's _name has not been explicitly set, the class loader's
+// qualified class name is returned.
 const char* ClassLoaderData::loader_name() const {
-  if (is_unloading()) {
-    if (_class_loader_klass == NULL) {
-      return "<bootloader>";
-    } else if (_class_loader_name != NULL) {
-      return _class_loader_name->as_C_string();
-    } else {
-      return _class_loader_klass->name()->as_C_string();
-    }
+   if (_class_loader_klass == NULL) {
+     return BOOTSTRAP_LOADER_NAME;
+   } else if (_name != NULL) {
+     return _name->as_C_string();
+   } else {
+     return _class_loader_klass->external_name();
+   }
+}
+
+// Caller needs ResourceMark
+// Format of the _name_and_id is as follows:
+//   If the defining loader has a name explicitly set then '<loader-name>' @<id>
+//   If the defining loader has no name then <qualified-class-name> @<id>
+//   If built-in loader, then omit '@<id>' as there is only one instance.
+const char* ClassLoaderData::loader_name_and_id() const {
+  if (_class_loader_klass == NULL) {
+    return "'" BOOTSTRAP_LOADER_NAME "'";
   } else {
-    // Handles null class loader
-    return SystemDictionary::loader_name(class_loader());
+    assert(_name_and_id != NULL, "encountered a class loader null name and id");
+    return _name_and_id->as_C_string();
   }
 }
 
-
 void ClassLoaderData::print_value_on(outputStream* out) const {
   if (!is_unloading() && class_loader() != NULL) {
     out->print("loader data: " INTPTR_FORMAT " for instance ", p2i(this));
-    class_loader()->print_value_on(out);  // includes loader_name() and address of class loader instance
+    class_loader()->print_value_on(out);  // includes loader_name_and_id() and address of class loader instance
   } else {
-    // loader data: 0xsomeaddr of <bootloader>
-    out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name());
+    // loader data: 0xsomeaddr of 'bootstrap'
+    out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id());
   }
   if (is_anonymous()) {
     out->print(" anonymous");
@@ -943,7 +973,7 @@
 #ifndef PRODUCT
 void ClassLoaderData::print_on(outputStream* out) const {
   out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {",
-              p2i(this), p2i(_class_loader.ptr_raw()), loader_name());
+              p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id());
   if (is_anonymous()) out->print(" anonymous");
   if (claimed()) out->print(" claimed");
   if (is_unloading()) out->print(" unloading");
@@ -1237,7 +1267,7 @@
   FOR_ALL_DICTIONARY(cld) {
     ResourceMark rm;
     stringStream tempst;
-    tempst.print("System Dictionary for %s", cld->loader_name());
+    tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
     cld->dictionary()->print_table_statistics(st, tempst.as_string());
   }
 }
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Tue Jun 19 07:54:11 2018 -0400
@@ -37,6 +37,9 @@
 #include "jfr/support/jfrTraceIdExtension.hpp"
 #endif
 
+// external name (synthetic) for the primordial "bootstrap" class loader instance
+#define BOOTSTRAP_LOADER_NAME "bootstrap"
+#define BOOTSTRAP_LOADER_NAME_LEN 9
 
 //
 // A class loader represents a linkset. Conceptually, a linkset identifies
@@ -258,9 +261,9 @@
   // Support for walking class loader data objects
   ClassLoaderData* _next; /// Next loader_datas created
 
-  // JFR support
   Klass*  _class_loader_klass;
-  Symbol* _class_loader_name;
+  Symbol* _name;
+  Symbol* _name_and_id;
   JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
 
   void set_next(ClassLoaderData* next) { _next = next; }
@@ -362,8 +365,6 @@
 
   void initialize_holder(Handle holder);
 
-  inline unsigned int identity_hash() const { return (unsigned int)(((intptr_t)this) >> 3); }
-
   void oops_do(OopClosure* f, bool must_claim, bool clear_modified_oops = false);
 
   void classes_do(KlassClosure* klass_closure);
@@ -377,7 +378,6 @@
   void print_value()                               { print_value_on(tty); }
   void print_value_on(outputStream* out) const;
   void verify();
-  const char* loader_name() const;
 
   OopHandle add_handle(Handle h);
   void remove_handle(OopHandle h);
@@ -400,15 +400,20 @@
   static ClassLoaderData* class_loader_data_or_null(oop loader);
   static ClassLoaderData* anonymous_class_loader_data(Handle loader);
 
-  // Returns Klass* of associated class loader, or NULL if associated loader is <bootstrap>.
+  // Returns Klass* of associated class loader, or NULL if associated loader is 'bootstrap'.
   // Also works if unloading.
   Klass* class_loader_klass() const { return _class_loader_klass; }
 
-  // Returns Name of associated class loader.
-  // Returns NULL if associated class loader is <bootstrap> or if no name has been set for
-  //   this loader.
-  // Also works if unloading.
-  Symbol* class_loader_name() const { return _class_loader_name; }
+  // Returns the class loader's explict name as specified during
+  // construction or the class loader's qualified class name.
+  // Works during unloading.
+  const char* loader_name() const;
+  // Returns the explicitly specified class loader name or NULL.
+  Symbol* name() const { return _name; }
+
+  // Obtain the class loader's _name_and_id, works during unloading.
+  const char* loader_name_and_id() const;
+  Symbol* name_and_id() const { return _name_and_id; }
 
   JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
 };
--- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -157,7 +157,7 @@
 
     // Retrieve information.
     const Klass* const loader_klass = _cld->class_loader_klass();
-    const Symbol* const loader_name = _cld->class_loader_name();
+    const Symbol* const loader_name = _cld->name();
 
     branchtracker.print(st);
 
--- a/src/hotspot/share/classfile/dictionary.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/dictionary.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -641,6 +641,6 @@
 
   ResourceMark rm;
   stringStream tempst;
-  tempst.print("System Dictionary for %s", cld->loader_name());
+  tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
   verify_table<DictionaryEntry>(tempst.as_string());
 }
--- a/src/hotspot/share/classfile/javaClasses.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -3993,6 +3993,7 @@
 int  java_lang_ClassLoader::_loader_data_offset = -1;
 int  java_lang_ClassLoader::parallelCapable_offset = -1;
 int  java_lang_ClassLoader::name_offset = -1;
+int  java_lang_ClassLoader::nameAndId_offset = -1;
 int  java_lang_ClassLoader::unnamedModule_offset = -1;
 
 ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
@@ -4008,6 +4009,7 @@
 #define CLASSLOADER_FIELDS_DO(macro) \
   macro(parallelCapable_offset, k1, "parallelLockMap",      concurrenthashmap_signature, false); \
   macro(name_offset,            k1, vmSymbols::name_name(), string_signature, false); \
+  macro(nameAndId_offset,       k1, "nameAndId",            string_signature, false); \
   macro(unnamedModule_offset,   k1, "unnamedModule",        module_signature, false); \
   macro(parent_offset,          k1, "parent",               classloader_signature, false)
 
@@ -4033,11 +4035,24 @@
   return loader->obj_field(parent_offset);
 }
 
+// Returns the name field of this class loader.  If the name field has not
+// been set, null will be returned.
 oop java_lang_ClassLoader::name(oop loader) {
   assert(is_instance(loader), "loader must be oop");
   return loader->obj_field(name_offset);
 }
 
+// Returns the nameAndId field of this class loader. The format is
+// as follows:
+//   If the defining loader has a name explicitly set then '<loader-name>' @<id>
+//   If the defining loader has no name then <qualified-class-name> @<id>
+//   If built-in loader, then omit '@<id>' as there is only one instance.
+// Use ClassLoader::loader_name_id() to obtain this String as a char*.
+oop java_lang_ClassLoader::nameAndId(oop loader) {
+  assert(is_instance(loader), "loader must be oop");
+  return loader->obj_field(nameAndId_offset);
+}
+
 bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
   assert(is_instance(loader), "loader must be oop");
   assert(cl == NULL || is_instance(cl), "cl argument must be oop");
@@ -4111,39 +4126,28 @@
 
 // Caller needs ResourceMark.
 const char* java_lang_ClassLoader::describe_external(const oop loader) {
+  ClassLoaderData *cld = ClassLoaderData::class_loader_data(loader);
+  const char* name = cld->loader_name_and_id();
+
+  // bootstrap loader
   if (loader == NULL) {
-    return "<bootstrap>";
+    return name;
   }
 
   bool well_known_loader = SystemDictionary::is_system_class_loader(loader) ||
                            SystemDictionary::is_platform_class_loader(loader);
 
-  const char* name = NULL;
-  oop nameOop = java_lang_ClassLoader::name(loader);
-  if (nameOop != NULL) {
-    name = java_lang_String::as_utf8_string(nameOop);
-  }
-  if (name == NULL) {
-    // Use placeholder for missing name to have fixed message format.
-    name = "<unnamed>";
-  }
-
   stringStream ss;
-  ss.print("\"%s\" (instance of %s", name, loader->klass()->external_name());
+  ss.print("%s (instance of %s", name, loader->klass()->external_name());
   if (!well_known_loader) {
-    const char* parentName = NULL;
     oop pl = java_lang_ClassLoader::parent(loader);
+    ClassLoaderData *pl_cld = ClassLoaderData::class_loader_data(pl);
+    const char* parentName = pl_cld->loader_name_and_id();
     if (pl != NULL) {
-      oop parentNameOop = java_lang_ClassLoader::name(pl);
-      if (parentNameOop != NULL) {
-        parentName = java_lang_String::as_utf8_string(parentNameOop);
-      }
-      if (parentName == NULL) {
-        parentName = "<unnamed>";
-      }
-      ss.print(", child of \"%s\" %s", parentName, pl->klass()->external_name());
+      ss.print(", child of %s %s", parentName, pl->klass()->external_name());
     } else {
-      ss.print(", child of <bootstrap>");
+      // bootstrap loader
+      ss.print(", child of %s", parentName);
     }
   }
   ss.print(")");
--- a/src/hotspot/share/classfile/javaClasses.hpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Tue Jun 19 07:54:11 2018 -0400
@@ -1272,6 +1272,7 @@
   static int parent_offset;
   static int parallelCapable_offset;
   static int name_offset;
+  static int nameAndId_offset;
   static int unnamedModule_offset;
 
  public:
@@ -1283,6 +1284,7 @@
 
   static oop parent(oop loader);
   static oop name(oop loader);
+  static oop nameAndId(oop loader);
   static bool isAncestor(oop loader, oop cl);
 
   // Support for parallelCapable field
--- a/src/hotspot/share/classfile/loaderConstraints.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/loaderConstraints.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -108,7 +108,7 @@
                      probe->name()->as_C_string());
           for (int i = 0; i < probe->num_loaders(); i++) {
             lt.print("    [%d]: %s", i,
-                          probe->loader_data(i)->loader_name());
+                          probe->loader_data(i)->loader_name_and_id());
           }
         }
       }
@@ -119,7 +119,7 @@
           if (lt.is_enabled()) {
             ResourceMark rm;
             lt.print("purging loader %s from constraint for name %s",
-                     probe->loader_data(n)->loader_name(),
+                     probe->loader_data(n)->loader_name_and_id(),
                      probe->name()->as_C_string()
                      );
           }
@@ -135,7 +135,7 @@
             lt.print("new loader list:");
             for (int i = 0; i < probe->num_loaders(); i++) {
               lt.print("    [%d]: %s", i,
-                            probe->loader_data(i)->loader_name());
+                            probe->loader_data(i)->loader_name_and_id());
             }
           }
 
@@ -177,8 +177,8 @@
     lt.print("Failed to add constraint for name: %s, loader[0]: %s,"
                 " loader[1]: %s, Reason: %s",
                   class_name->as_C_string(),
-                  SystemDictionary::loader_name(class_loader1()),
-                  SystemDictionary::loader_name(class_loader2()),
+                  ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
+                  ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id(),
                   reason);
   }
 }
@@ -247,8 +247,8 @@
       lt.print("adding new constraint for name: %s, loader[0]: %s,"
                     " loader[1]: %s",
                     class_name->as_C_string(),
-                    SystemDictionary::loader_name(class_loader1()),
-                    SystemDictionary::loader_name(class_loader2())
+                    ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id(),
+                    ClassLoaderData::class_loader_data(class_loader2())->loader_name_and_id()
                     );
     }
   } else if (*pp1 == *pp2) {
@@ -260,7 +260,7 @@
         lt.print("setting class object in existing constraint for"
                       " name: %s and loader %s",
                       class_name->as_C_string(),
-                      SystemDictionary::loader_name(class_loader1())
+                      ClassLoaderData::class_loader_data(class_loader1())->loader_name_and_id()
                       );
       }
     } else {
@@ -291,7 +291,7 @@
       lt.print("constraint check failed for name %s, loader %s: "
                  "the presented class object differs from that stored",
                  name->as_C_string(),
-                 SystemDictionary::loader_name(loader()));
+                 ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
     }
     return false;
   } else {
@@ -302,7 +302,7 @@
         lt.print("updating constraint for name %s, loader %s, "
                    "by setting class object",
                    name->as_C_string(),
-                   SystemDictionary::loader_name(loader()));
+                   ClassLoaderData::class_loader_data(loader())->loader_name_and_id());
       }
     }
     return true;
@@ -353,7 +353,7 @@
     lt.print("extending constraint for name %s by adding loader[%d]: %s %s",
                p->name()->as_C_string(),
                num,
-               SystemDictionary::loader_name(loader()),
+               ClassLoaderData::class_loader_data(loader())->loader_name_and_id(),
                (p->klass() == NULL ? " and setting class object" : "")
                );
   }
@@ -396,7 +396,7 @@
 
     for (int i = 0; i < p1->num_loaders(); i++) {
       lt.print("    [%d]: %s", i,
-                    p1->loader_data(i)->loader_name());
+                    p1->loader_data(i)->loader_name_and_id());
     }
     if (p1->klass() == NULL) {
       lt.print("... and setting class object");
--- a/src/hotspot/share/classfile/moduleEntry.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/moduleEntry.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -260,7 +260,7 @@
   ResourceMark rm;
   guarantee(java_lang_Module::is_instance(module),
             "The unnamed module for ClassLoader %s, is null or not an instance of java.lang.Module. The class loader has not been initialized correctly.",
-            cld->loader_name());
+            cld->loader_name_and_id());
 
   ModuleEntry* unnamed_module = new_unnamed_module_entry(Handle(Thread::current(), module), cld);
 
@@ -522,7 +522,7 @@
                p2i(this),
                name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
                p2i(module()),
-               loader_data()->loader_name(),
+               loader_data()->loader_name_and_id(),
                version() != NULL ? version()->as_C_string() : "NULL",
                location() != NULL ? location()->as_C_string() : "NULL",
                BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
--- a/src/hotspot/share/classfile/modules.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/modules.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -312,6 +312,10 @@
               "Class loader is an invalid delegating class loader");
   }
   Handle h_loader = Handle(THREAD, loader);
+  // define_module can be called during start-up, before the class loader's ClassLoaderData
+  // has been created.  SystemDictionary::register_loader ensures creation, if needed.
+  ClassLoaderData* loader_data = SystemDictionary::register_loader(h_loader);
+  assert(loader_data != NULL, "class loader data shouldn't be null");
 
   // Check that the list of packages has no duplicates and that the
   // packages are syntactically ok.
@@ -329,7 +333,7 @@
         !SystemDictionary::is_platform_class_loader(h_loader()) &&
         (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 &&
           (package_name[JAVAPKG_LEN] == '/' || package_name[JAVAPKG_LEN] == '\0'))) {
-      const char* class_loader_name = SystemDictionary::loader_name(h_loader());
+      const char* class_loader_name = loader_data->loader_name_and_id();
       size_t pkg_len = strlen(package_name);
       char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len);
       strncpy(pkg_name, package_name, pkg_len);
@@ -373,9 +377,6 @@
     }
   }
 
-  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(h_loader());
-  assert(loader_data != NULL, "class loader data shouldn't be null");
-
   PackageEntryTable* package_table = NULL;
   PackageEntry* existing_pkg = NULL;
   {
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -3012,18 +3012,6 @@
   NOT_PRODUCT(SystemDictionary::verify());
 }
 
-// caller needs ResourceMark
-const char* SystemDictionary::loader_name(const oop loader) {
-  return ((loader) == NULL ? "<bootloader>" :
-          InstanceKlass::cast((loader)->klass())->name()->as_C_string());
-}
-
-// caller needs ResourceMark
-const char* SystemDictionary::loader_name(const ClassLoaderData* loader_data) {
-  return (loader_data->class_loader() == NULL ? "<bootloader>" :
-          SystemDictionary::loader_name(loader_data->class_loader()));
-}
-
 void SystemDictionary::initialize_oop_storage() {
   _vm_weak_oop_storage =
     new OopStorage("VM Weak Oop Handles",
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Tue Jun 19 07:54:11 2018 -0400
@@ -570,10 +570,6 @@
                                                      Handle *method_type_result,
                                                      TRAPS);
 
-  // Utility for printing loader "name" as part of tracing constraints
-  static const char* loader_name(const oop loader);
-  static const char* loader_name(const ClassLoaderData* loader_data);
-
   // Record the error when the first attempt to resolve a reference from a constant
   // pool entry to a class fails.
   static void add_resolution_error(const constantPoolHandle& pool, int which, Symbol* error,
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -128,7 +128,7 @@
   NOT_PRODUCT(ResourceMark rm);
   log_develop_trace(gc, scavenge)("CLDScanClosure::do_cld " PTR_FORMAT ", %s, dirty: %s",
                                   p2i(cld),
-                                  cld->loader_name(),
+                                  cld->loader_name_and_id(),
                                   cld->has_modified_oops() ? "true" : "false");
 
   // If the cld has not been dirtied we know that there's
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -238,9 +238,9 @@
     // (primordial) boot class loader
     writer->write(cld_id); // class loader instance id
     writer->write((traceid)0);  // class loader type id (absence of)
-    writer->write((traceid)CREATE_SYMBOL_ID(1)); // 1 maps to synthetic name -> "boot"
+    writer->write((traceid)CREATE_SYMBOL_ID(1)); // 1 maps to synthetic name -> "bootstrap"
   } else {
-    Symbol* symbol_name = cld->class_loader_name();
+    Symbol* symbol_name = cld->name();
     const traceid symbol_name_id = symbol_name != NULL ? artifacts->mark(symbol_name) : 0;
     writer->write(cld_id); // class loader instance id
     writer->write(TRACE_ID(class_loader_klass)); // class loader type id
@@ -441,13 +441,13 @@
     CStringEntryPtr entry = this->_artifacts->map_cstring(0);
     assert(entry != NULL, "invariant");
     assert(strncmp(entry->literal(),
-      boot_class_loader_name,
-      strlen(boot_class_loader_name)) == 0, "invariant");
+      BOOTSTRAP_LOADER_NAME,
+      BOOTSTRAP_LOADER_NAME_LEN) == 0, "invariant");
     if (_unique_predicate(entry->id())) {
       count += write__artifact__cstring__entry__(this->_writer, entry);
     }
   } else {
-    const Symbol* class_loader_name = cld->class_loader_name();
+    const Symbol* class_loader_name = cld->name();
     if (class_loader_name != NULL) {
       SymbolEntryPtr entry = this->_artifacts->map_symbol(class_loader_name);
       assert(entry != NULL, "invariant");
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -208,7 +208,7 @@
   assert(_symbol_id != NULL, "invariant");
   _symbol_id->initialize();
   assert(!_symbol_id->has_entries(), "invariant");
-  _symbol_id->mark(boot_class_loader_name, 0); // pre-load "boot"
+  _symbol_id->mark(BOOTSTRAP_LOADER_NAME, 0); // pre-load "bootstrap"
   _class_unload = class_unload;
   // resource allocation
   _klass_list = new GrowableArray<const Klass*>(initial_class_list_size, false, mtTracing);
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp	Tue Jun 19 07:54:11 2018 -0400
@@ -295,9 +295,6 @@
   bool has_cstring_entries() const { return _cstring_table->has_entries(); }
 };
 
-// external name (synthetic) for the primordial "boot" class loader instance
-const char* const boot_class_loader_name = "boot";
-
 /**
  * When processing a set of artifacts, there will be a need
  * to track transitive dependencies originating with each artifact.
--- a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -88,7 +88,7 @@
     Klass* k = cld->class_loader_klass();
     if (k != NULL) {
       class_name = k->external_name();
-      Symbol* s = cld->class_loader_name();
+      Symbol* s = cld->name();
       if (s != NULL) {
         name = s->as_C_string();
       }
--- a/src/hotspot/share/oops/instanceKlass.cpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Tue Jun 19 07:54:11 2018 -0400
@@ -2328,8 +2328,7 @@
 void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
 
   // ensure java/ packages only loaded by boot or platform builtin loaders
-  Handle class_loader(THREAD, loader_data->class_loader());
-  check_prohibited_package(name(), class_loader, CHECK);
+  check_prohibited_package(name(), loader_data, CHECK);
 
   TempNewSymbol pkg_name = package_from_name(name(), CHECK);
 
@@ -2359,7 +2358,7 @@
 
       // A package should have been successfully created
       assert(_package_entry != NULL, "Package entry for class %s not found, loader %s",
-             name()->as_C_string(), loader_data->loader_name());
+             name()->as_C_string(), loader_data->loader_name_and_id());
     }
 
     if (log_is_enabled(Debug, module)) {
@@ -2368,14 +2367,14 @@
       log_trace(module)("Setting package: class: %s, package: %s, loader: %s, module: %s",
                         external_name(),
                         pkg_name->as_C_string(),
-                        loader_data->loader_name(),
+                        loader_data->loader_name_and_id(),
                         (m->is_named() ? m->name()->as_C_string() : UNNAMED_MODULE));
     }
   } else {
     ResourceMark rm;
     log_trace(module)("Setting package: class: %s, package: unnamed, loader: %s, module: %s",
                       external_name(),
-                      (loader_data != NULL) ? loader_data->loader_name() : "NULL",
+                      (loader_data != NULL) ? loader_data->loader_name_and_id() : "NULL",
                       UNNAMED_MODULE);
   }
 }
@@ -2471,10 +2470,10 @@
 
 // Only boot and platform class loaders can define classes in "java/" packages.
 void InstanceKlass::check_prohibited_package(Symbol* class_name,
-                                             Handle class_loader,
+                                             ClassLoaderData* loader_data,
                                              TRAPS) {
-  if (!class_loader.is_null() &&
-      !SystemDictionary::is_platform_class_loader(class_loader()) &&
+  if (!loader_data->is_boot_class_loader_data() &&
+      !loader_data->is_platform_class_loader_data() &&
       class_name != NULL) {
     ResourceMark rm(THREAD);
     char* name = class_name->as_C_string();
@@ -2482,7 +2481,7 @@
       TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK);
       assert(pkg_name != NULL, "Error in parsing package name starting with 'java/'");
       name = pkg_name->as_C_string();
-      const char* class_loader_name = SystemDictionary::loader_name(class_loader());
+      const char* class_loader_name = loader_data->loader_name_and_id();
       StringUtils::replace_no_expand(name, "/", ".");
       const char* msg_text1 = "Class loader (instance of): ";
       const char* msg_text2 = " tried to load prohibited package name: ";
--- a/src/hotspot/share/oops/instanceKlass.hpp	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Tue Jun 19 07:54:11 2018 -0400
@@ -471,7 +471,7 @@
  private:
   // Check prohibited package ("java/" only loadable by boot or platform loaders)
   static void check_prohibited_package(Symbol* class_name,
-                                       Handle class_loader,
+                                       ClassLoaderData* loader_data,
                                        TRAPS);
  public:
   // tell if two classes have the same enclosing class (at package level)
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Tue Jun 19 07:54:11 2018 -0400
@@ -59,6 +59,7 @@
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
+import jdk.internal.loader.BuiltinClassLoader;
 import jdk.internal.perf.PerfCounter;
 import jdk.internal.loader.BootLoader;
 import jdk.internal.loader.ClassLoaders;
@@ -246,6 +247,9 @@
     // the unnamed module for this ClassLoader
     private final Module unnamedModule;
 
+    // a string for exception message printing
+    private final String nameAndId;
+
     /**
      * Encapsulates the set of parallel capable loader types.
      */
@@ -381,6 +385,24 @@
             package2certs = new Hashtable<>();
             assertionLock = this;
         }
+        this.nameAndId = nameAndId(this);
+    }
+
+    /**
+     * If the defining loader has a name explicitly set then
+     *       '<loader-name>' @<id>
+     * If the defining loader has no name then
+     *       <qualified-class-name> @<id>
+     * If it's built-in loader then omit `@<id>` as there is only one instance.
+     */
+    private static String nameAndId(ClassLoader ld) {
+        String nid = ld.getName() != null ? "\'" + ld.getName() + "\'"
+                                          : ld.getClass().getName();
+        if (!(ld instanceof BuiltinClassLoader)) {
+            String id = Integer.toHexString(System.identityHashCode(ld));
+            nid = nid + " @" + id;
+        }
+        return nid;
     }
 
     /**
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java	Tue Jun 19 07:54:11 2018 -0400
@@ -75,11 +75,13 @@
     // Then it loads the D2 variant of D from the current working directory and it's
     // superclass C. This fails as D1 is already loaded with the same superclass.
 
-    static String expectedErrorMessage =
-        "loader constraint violation: loader \"<unnamed>\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) wants to load " +
+    // Break the expectedErrorMessage into 2 pieces since the loader name will include
+    // its identity hash and can not be compared against.
+    static String expectedErrorMessage_part1 = "loader constraint violation: loader PreemptingClassLoader @";
+    static String expectedErrorMessage_part2 = " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) wants to load " +
         "class test.D_ambgs. A different class with the same name was previously loaded " +
-        "by \"app\" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader).";
+        "by 'app' (instance of jdk.internal.loader.ClassLoaders$AppClassLoader).";
 
     public static void test_access() throws Exception {
         try {
@@ -101,8 +103,9 @@
             throw new RuntimeException("Expected LinkageError was not thrown.");
         } catch (LinkageError jle) {
             String errorMsg = jle.getMessage();
-            if (!errorMsg.equals(expectedErrorMessage)) {
-                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+            if (!errorMsg.contains(expectedErrorMessage_part1) ||
+                !errorMsg.contains(expectedErrorMessage_part2)) {
+                System.out.println("Expected: " + expectedErrorMessage_part1 + "<id>" + expectedErrorMessage_part2 + "\n" +
                                    "but got:  " + errorMsg);
                 throw new RuntimeException("Wrong error message of LinkageError.");
             } else {
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java	Tue Jun 19 07:54:11 2018 -0400
@@ -37,23 +37,28 @@
 
     // Check that all names have external formatting ('.' and not '/' in package names).
     // Check for parent of class loader.
-    static String expectedErrorMessage1 =
-        "loader \"<unnamed>\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+    // Break each expectedErrorMessage into 2 parts due to the class loader name containing
+    // the unique @<id> identity hash which cannot be compared against.
+    static String expectedErrorMessage1_part1 = "loader PreemptingClassLoader @";
+    static String expectedErrorMessage1_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "attempted duplicate class definition for test.Foo.";
 
     // Check that all names have external formatting ('.' and not '/' in package names).
     // Check for name and parent of class loader.
-    static String expectedErrorMessage2 =
-        "loader \"DuplicateLE_Test_Loader\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+    static String expectedErrorMessage2_part1 = "loader 'DuplicateLE_Test_Loader' @";
+    static String expectedErrorMessage2_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "attempted duplicate class definition for test.Foo.";
 
     // Check that all names have external formatting ('.' and not '/' in package names).
     // Check for name and parent of class loader. Type should be mentioned as 'interface'.
-    static String expectedErrorMessage3 =
-        "loader \"DuplicateLE_Test_Loader_IF\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+    static String expectedErrorMessage3_part1 = "loader 'DuplicateLE_Test_Loader_IF' @";
+    static String expectedErrorMessage3_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "attempted duplicate interface definition for test.J.";
 
     // Test that the error message is correct when a loader constraint error is
@@ -63,7 +68,8 @@
     // overrides "J.m()LFoo;".  But, Task's class Foo and super type J's class Foo
     // are different.  So, a LinkageError exception should be thrown because the
     // loader constraint check will fail.
-    public static void test(String loaderName, String expectedErrorMessage, String testType) throws Exception {
+    public static void test(String loaderName, String expectedErrorMessage_part1,
+                            String expectedErrorMessage_part2, String testType) throws Exception {
         String[] classNames = {testType};
         ClassLoader l = new PreemptingClassLoader(loaderName, classNames, false);
         l.loadClass(testType);
@@ -72,8 +78,9 @@
             throw new RuntimeException("Expected LinkageError exception not thrown");
         } catch (LinkageError e) {
             String errorMsg = e.getMessage();
-            if (!errorMsg.equals(expectedErrorMessage)) {
-                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+            if (!errorMsg.contains(expectedErrorMessage_part1) ||
+                !errorMsg.contains(expectedErrorMessage_part2)) {
+                System.out.println("Expected: " + expectedErrorMessage_part1 + "<id>" + expectedErrorMessage_part2 + "\n" +
                                    "but got:  " + errorMsg);
                 throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg);
             }
@@ -82,9 +89,9 @@
     }
 
     public static void main(String args[]) throws Exception {
-        test(null, expectedErrorMessage1, "test.Foo");
-        test("DuplicateLE_Test_Loader", expectedErrorMessage2, "test.Foo");
-        test("DuplicateLE_Test_Loader_IF", expectedErrorMessage3, "test.J");
+        test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2, "test.Foo");
+        test("DuplicateLE_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2, "test.Foo");
+        test("DuplicateLE_Test_Loader_IF", expectedErrorMessage3_part1, expectedErrorMessage3_part2, "test.J");
     }
 }
 
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java	Tue Jun 19 07:54:11 2018 -0400
@@ -35,22 +35,28 @@
 
 public class Test {
 
-    static String expectedErrorMessage1 =
+    // Break expected error messages into 2 parts since the loader name includes its identity
+    // hash which is unique and can't be compared against.
+    static String expectedErrorMessage1_part1 =
         "loader constraint violation in interface itable initialization for class test.C: " +
         "when selecting method test.I.m()Ltest/Foo; " +
-        "the class loader \"<unnamed>\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
-        "for super interface test.I, and the class loader \"app\" " +
+        "the class loader PreemptingClassLoader @";
+    static String expectedErrorMessage1_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "for super interface test.I, and the class loader 'app' " +
         "(instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "of the selected method's type, test.J have different Class objects " +
         "for the type test.Foo used in the signature";
 
-    static String expectedErrorMessage2 =
+    static String expectedErrorMessage2_part1 =
         "loader constraint violation in interface itable initialization for class test.C: " +
         "when selecting method test.I.m()Ltest/Foo; " +
-        "the class loader \"ItableLdrCnstrnt_Test_Loader\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
-        "for super interface test.I, and the class loader \"app\" " +
+        "the class loader 'ItableLdrCnstrnt_Test_Loader' @";
+    static String expectedErrorMessage2_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "for super interface test.I, and the class loader 'app' " +
         "(instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "of the selected method's type, test.J have different Class objects " +
         "for the type test.Foo used in the signature";
@@ -63,7 +69,9 @@
     // type super interface J.  The selected method is not an overpass method nor
     // otherwise excluded from loader constraint checking.  So, a LinkageError
     // exception should be thrown because the loader constraint check will fail.
-    public static void test(String loaderName, String expectedErrorMessage) throws Exception {
+    public static void test(String loaderName,
+                            String expectedErrorMessage_part1,
+                            String expectedErrorMessage_part2) throws Exception {
         Class<?> c = test.Foo.class; // Forces standard class loader to load Foo.
         String[] classNames = {"test.Task", "test.Foo", "test.C", "test.I"};
         ClassLoader l = new PreemptingClassLoader(loaderName, classNames);
@@ -73,8 +81,9 @@
             throw new RuntimeException("Expected LinkageError exception not thrown");
         } catch (LinkageError e) {
             String errorMsg = e.getMessage();
-            if (!errorMsg.equals(expectedErrorMessage)) {
-                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+            if (!errorMsg.contains(expectedErrorMessage_part1) ||
+                !errorMsg.contains(expectedErrorMessage_part2)) {
+                System.out.println("Expected: " + expectedErrorMessage_part1 + "<id>" + expectedErrorMessage_part2 + "\n" +
                                    "but got:  " + errorMsg);
                 throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg);
             }
@@ -83,7 +92,7 @@
     }
 
     public static void main(String... args) throws Exception {
-        test(null, expectedErrorMessage1);
-        test("ItableLdrCnstrnt_Test_Loader", expectedErrorMessage2);
+        test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2);
+        test("ItableLdrCnstrnt_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2);
     }
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java	Tue Jun 19 07:54:11 2018 -0400
@@ -35,23 +35,29 @@
 
 public class Test {
 
-    static String expectedErrorMessage1 =
+    // Break expected error messages into 2 parts since the loader name includes its identity
+    // hash which is unique and can't be compared against.
+    static String expectedErrorMessage1_part1 =
         "loader constraint violation for class test.Task: " +
         "when selecting overriding method test.Task.m()Ltest/Foo; " +
-        "the class loader \"<unnamed>\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "the class loader PreemptingClassLoader @";
+    static String expectedErrorMessage1_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "of the selected method's type test.Task, " +
-        "and the class loader \"app\" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "and the class loader 'app' (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "for its super type test.J " +
         "have different Class objects for the type test.Foo used in the signature";
 
-    static String expectedErrorMessage2 =
+    static String expectedErrorMessage2_part1 =
         "loader constraint violation for class test.Task: " +
         "when selecting overriding method test.Task.m()Ltest/Foo; " +
-        "the class loader \"VtableLdrCnstrnt_Test_Loader\" (instance of PreemptingClassLoader, " +
-        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "the class loader 'VtableLdrCnstrnt_Test_Loader' @";
+    static String expectedErrorMessage2_part2 =
+        " (instance of PreemptingClassLoader, " +
+        "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "of the selected method's type test.Task, " +
-        "and the class loader \"app\" (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "and the class loader 'app' (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " +
         "for its super type test.J " +
         "have different Class objects for the type test.Foo used in the signature";
 
@@ -62,7 +68,9 @@
     // overrides "J.m()LFoo;".  But, Task's class Foo and super type J's class Foo
     // are different.  So, a LinkageError exception should be thrown because the
     // loader constraint check will fail.
-    public static void test(String loaderName, String expectedErrorMessage) throws Exception {
+    public static void test(String loaderName,
+                            String expectedErrorMessage_part1,
+                            String expectedErrorMessage_part2) throws Exception {
         Class<?> c = test.Foo.class; // Forces standard class loader to load Foo.
         String[] classNames = {"test.Task", "test.Foo", "test.I"};
         ClassLoader l = new PreemptingClassLoader(loaderName, classNames);
@@ -72,8 +80,9 @@
             throw new RuntimeException("Expected LinkageError exception not thrown");
         } catch (LinkageError e) {
             String errorMsg = e.getMessage();
-            if (!errorMsg.equals(expectedErrorMessage)) {
-                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+            if (!errorMsg.contains(expectedErrorMessage_part1) ||
+                !errorMsg.contains(expectedErrorMessage_part2)) {
+                System.out.println("Expected: " + expectedErrorMessage_part1 + "<id>" + expectedErrorMessage_part2 + "\n" +
                                    "but got:  " + errorMsg);
                 throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg);
             }
@@ -82,8 +91,8 @@
     }
 
     public static void main(String args[]) throws Exception {
-        test(null, expectedErrorMessage1);
-        test("VtableLdrCnstrnt_Test_Loader", expectedErrorMessage2);
+        test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2);
+        test("VtableLdrCnstrnt_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2);
     }
 }
 
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java	Tue Jun 19 07:54:11 2018 -0400
@@ -60,7 +60,7 @@
         pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.systemdictionary"});
         output = CDSTestUtils.executeAndLog(pb, "jcmd-systemdictionary");
         try {
-            output.shouldContain("System Dictionary for jdk/internal/loader/ClassLoaders$AppClassLoader statistics:");
+            output.shouldContain("System Dictionary for 'app' class loader statistics:");
             output.shouldContain("Number of buckets");
             output.shouldContain("Number of entries");
             output.shouldContain("Maximum bucket size");
--- a/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/hotspot/jtreg/runtime/logging/LoaderConstraintsTest.java	Tue Jun 19 07:54:11 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018 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
@@ -67,12 +67,12 @@
         pb = exec("-XX:+TraceLoaderConstraints");
         out = new OutputAnalyzer(pb.start());
         out.getOutput();
-        out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: jdk/internal/loader/ClassLoaders$AppClassLoader, loader[1]: <bootloader>");
+        out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: 'app', loader[1]: 'bootstrap'");
 
         // -Xlog:class+loader+constraints=info
         pb = exec("-Xlog:class+loader+constraints=info");
         out = new OutputAnalyzer(pb.start());
-        out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: jdk/internal/loader/ClassLoaders$AppClassLoader, loader[1]: <bootloader>");
+        out.shouldContain("[class,loader,constraints] adding new constraint for name: java/lang/Class, loader[0]: 'app', loader[1]: 'bootstrap'");
 
         // -XX:-TraceLoaderConstraints
         pb = exec("-XX:-TraceLoaderConstraints");
--- a/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java	Fri Jun 15 12:31:28 2018 +0200
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java	Tue Jun 19 07:54:11 2018 -0400
@@ -47,7 +47,7 @@
 public final class TestClassLoadEvent {
 
     private final static String TEST_CLASS_NAME = "jdk.jfr.event.runtime.TestClasses";
-    private final static String BOOT_CLASS_LOADER_NAME = "boot";
+    private final static String BOOT_CLASS_LOADER_NAME = "bootstrap";
     private final static String SEARCH_CLASS_NAME = "java.lang.Object";
     private final static String SEARCH_PACKAGE_NAME = "java/lang";
     private final static String SEARCH_MODULE_NAME = "java.base";