changeset 9311:3c022633643d

Fix app class dump failure with -Xbootclasspath/a.
author jiangli
date Tue, 13 Oct 2015 16:39:33 -0400
parents 16c18ec6764d
children 4fadf68d6d63
files src/share/vm/classfile/classLoader.cpp src/share/vm/classfile/classLoader.hpp
diffstat 2 files changed, 57 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoader.cpp	Wed Oct 07 11:29:24 2015 +0200
+++ b/src/share/vm/classfile/classLoader.cpp	Tue Oct 13 16:39:33 2015 -0400
@@ -140,13 +140,15 @@
 ClassPathEntry* ClassLoader::_last_entry  = NULL;
 int             ClassLoader::_num_entries = 0;
 ClassPathEntry* ClassLoader::_first_append_entry = NULL;
-ClassPathEntry* ClassLoader::_last_append_entry = NULL;
 PackageHashtable* ClassLoader::_package_hash_table = NULL;
 bool              ClassLoader::_has_bootmodules_jimage = false;
 GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
 GrowableArray<char*>* ClassLoader::_ext_modules_array = NULL;
 
 #if INCLUDE_CDS
+// The _last_append_entry is only set when DumpSharedSpaces is true and there are
+// append path entries.
+ClassPathEntry* ClassLoader::_last_append_entry = NULL;
 SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
 #endif
 // helper routines
@@ -576,15 +578,15 @@
     }
   }
 
+#if INCLUDE_CDS
+  // Mark the last entry corresponding to the -Xbootclasspath/a
   if (DumpSharedSpaces) {
-    // Mark the last entry corresponding to the -Xbootclasspath/a
     if (_first_append_entry != NULL && bootstrap_search) {
-      _last_append_entry = _first_append_entry;
-      while (_last_append_entry->next() != NULL) {
-        _last_append_entry = _last_append_entry->next();
-      }
+      assert(_last_append_entry == NULL, "The _last_append_entry is already set");
+      _last_append_entry = _last_entry;
     }
   }
+#endif
 }
 
 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
@@ -1205,6 +1207,19 @@
   return result();
 }
 
+#if INCLUDE_CDS
+bool ClassLoader::class_in_append_entries(const char* file_name, TRAPS) {
+  ClassPathEntry* tmp_e = _first_append_entry;
+  while ((tmp_e != NULL) && (tmp_e != _last_append_entry->next())) {
+    ClassFileStream* stream = tmp_e->open_stream(file_name, CHECK_NULL);
+    if (stream != NULL) {
+      return true;
+    }
+    tmp_e = tmp_e->next();
+  }
+  return false;
+}
+#endif
 
 instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, bool search_append_only, TRAPS) {
   ResourceMark rm(THREAD);
@@ -1220,28 +1235,43 @@
   const char* file_name = st.as_string();
   ClassLoaderExt::Context context(class_name, file_name, THREAD);
 
+  instanceKlassHandle h;
+
+  PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
+                             ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
+                             PerfClassTraceTime::CLASS_LOAD);
+#if INCLUDE_CDS
+  // Don't archive any class that exists in the append path entries.
+  if (DumpSharedSpaces && class_in_append_entries(file_name, THREAD)) {
+    tty->print_cr("Preload Warning: skipping class from -Xbootclasspath/a %s",
+                  class_name);
+    return h; // NULL
+  }
+#endif
+
   // Lookup stream for parsing .class file
   ClassFileStream* stream = NULL;
   int classpath_index = 0;
-  ClassPathEntry* e = (!search_append_only ? _first_entry : _first_append_entry);
-  ClassPathEntry* last_e = (!search_append_only ? _first_append_entry : NULL);
-  instanceKlassHandle h;
+
+  // If DumpSharedSpaces is true, boot loader visibility boundaries are set
+  // to be _first_entry to the end (all path entries).
+  //
+  // If search_append_only is true, boot loader visibility boundaries are
+  // set to be _fist_append_entry to the end. This includes:
+  //   [-Xbootclasspath/a]; [jvmti appended entries]
+  //
+  // If both DumpSharedSpaces and search_append_only are false, boot loader
+  // visibility boundaries are set to be _first_entry to the entry before
+  // the _first_append_entry.  This would include:
+  //   [-Xpatch:<dirs>];  [exploded build | bootmodules.jimage]
+  //
+  // DumpSharedSpaces and search_append_only are mutually exclusive and cannot
+  // be true at the same time.
+  ClassPathEntry* e = (search_append_only ? _first_append_entry : _first_entry);
+  ClassPathEntry* last_e =
+      (search_append_only || DumpSharedSpaces ? NULL : _first_append_entry);
+
   {
-    PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
-                               ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
-                               PerfClassTraceTime::CLASS_LOAD);
-    if (DumpSharedSpaces) {
-      ClassPathEntry* tmp_e = _first_append_entry;
-      while ((tmp_e != NULL) && (tmp_e != _last_append_entry->next())) {
-        stream = tmp_e->open_stream(file_name, CHECK_NULL);
-        if (stream != NULL) {
-           tty->print_cr("Preload Warning: skipping class from -Xbootclasspath/a %s", class_name);
-           //...close the stream ...
-           return h; // NULL
-        }
-        tmp_e = tmp_e->next();
-      }
-    }
     if (search_append_only) {
       // For the boot loader append path search, must calculate
       // the starting classpath_index prior to attempting to
--- a/src/share/vm/classfile/classLoader.hpp	Wed Oct 07 11:29:24 2015 +0200
+++ b/src/share/vm/classfile/classLoader.hpp	Tue Oct 13 16:39:33 2015 -0400
@@ -207,8 +207,6 @@
   //     [-Xbootclasspath/a]; [jvmti appended entries]
   static ClassPathEntry* _first_append_entry;
 
-  static ClassPathEntry* _last_append_entry;
-
   // Hash table used to keep track of loaded packages
   static PackageHashtable* _package_hash_table;
   static const char* _shared_archive;
@@ -223,6 +221,7 @@
   static GrowableArray<char*>* _ext_modules_array;
 
   // Info used by CDS
+  CDS_ONLY(static ClassPathEntry* _last_append_entry;)
   CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
 
   // Hash function
@@ -373,6 +372,8 @@
   static void* get_shared_paths_misc_info();
   static bool  check_shared_paths_misc_info(void* info, int size);
   static void  exit_with_path_failure(const char* error, const char* message);
+
+  static bool class_in_append_entries(const char* file_name, TRAPS);
 #endif
 
   static void  trace_class_path(const char* msg, const char* name = NULL);