< prev index next >

src/hotspot/share/classfile/classLoader.cpp

Print this page

        

@@ -67,14 +67,16 @@
 #include "runtime/threadCritical.hpp"
 #include "runtime/timer.hpp"
 #include "runtime/vm_version.hpp"
 #include "services/management.hpp"
 #include "services/threadService.hpp"
-#include "utilities/classpathStream.hpp"
 #include "utilities/events.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
+#if INCLUDE_CDS
+#include "classfile/sharedPathsMiscInfo.hpp"
+#endif
 
 // Entry points in zip.dll for loading zip/jar file entries
 
 typedef void * * (*ZipOpen_t)(const char *name, char **pmsg);
 typedef void (*ZipClose_t)(jzfile *zip);

@@ -142,10 +144,11 @@
 #if INCLUDE_CDS
 ClassPathEntry* ClassLoader::_app_classpath_entries = NULL;
 ClassPathEntry* ClassLoader::_last_app_classpath_entry = NULL;
 ClassPathEntry* ClassLoader::_module_path_entries = NULL;
 ClassPathEntry* ClassLoader::_last_module_path_entry = NULL;
+SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
 #endif
 
 // helper routines
 bool string_starts_with(const char* str, const char* str_to_find) {
   size_t str_len = strlen(str);

@@ -244,16 +247,17 @@
   PackageEntryTable* pkgEntryTable = loader_data->packages();
   TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name);
   return pkgEntryTable->lookup_only(pkg_symbol);
 }
 
-const char* ClassPathEntry::copy_path(const char* path) {
-  char* copy = NEW_C_HEAP_ARRAY(char, strlen(path)+1, mtClass);
-  strcpy(copy, path);
-  return copy;
+ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
+  char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
+  strcpy(copy, dir);
+  _dir = copy;
 }
 
+
 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
   // construct full path name
   assert((_dir != NULL) && (name != NULL), "sanity");
   size_t path_len = strlen(_dir) + strlen(name) + strlen(os::file_separator()) + 1;
   char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);

@@ -286,15 +290,15 @@
   }
   FREE_RESOURCE_ARRAY(char, path, path_len);
   return NULL;
 }
 
-ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name,
-                                     bool is_boot_append, bool from_class_path_attr) : ClassPathEntry() {
+ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append) : ClassPathEntry() {
   _zip = zip;
-  _zip_name = copy_path(zip_name);
-  _from_class_path_attr = from_class_path_attr;
+  char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
+  strcpy(copy, zip_name);
+  _zip_name = copy;
 }
 
 ClassPathZipEntry::~ClassPathZipEntry() {
   if (ZipClose != NULL) {
     (*ZipClose)(_zip);

@@ -374,11 +378,12 @@
   guarantee(jimage != NULL, "jimage file is null");
   guarantee(name != NULL, "jimage file name is null");
   assert(_singleton == NULL, "VM supports only one jimage");
   DEBUG_ONLY(_singleton = this);
   size_t len = strlen(name) + 1;
-  _name = copy_path(name);
+  _name = NEW_C_HEAP_ARRAY(const char, len, mtClass);
+  strncpy((char *)_name, name, len);
 }
 
 ClassPathImageEntry::~ClassPathImageEntry() {
   assert(_singleton == this, "must be");
   DEBUG_ONLY(_singleton = NULL);

@@ -527,23 +532,58 @@
     // Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
     // the same as the bootcp of the shared archive.
   } else {
     trace_class_path("bootstrap loader class path=", sys_class_path);
   }
+#if INCLUDE_CDS
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    _shared_paths_misc_info->add_boot_classpath(sys_class_path);
+  }
+#endif
   setup_boot_search_path(sys_class_path);
 }
 
 #if INCLUDE_CDS
+int ClassLoader::get_shared_paths_misc_info_size() {
+  return _shared_paths_misc_info->get_used_bytes();
+}
+
+void* ClassLoader::get_shared_paths_misc_info() {
+  return _shared_paths_misc_info->buffer();
+}
+
+bool ClassLoader::check_shared_paths_misc_info(void *buf, int size, bool is_static) {
+  SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size);
+  bool result = checker->check(is_static);
+  delete checker;
+  return result;
+}
+
 void ClassLoader::setup_app_search_path(const char *class_path) {
+
   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
 
-  ResourceMark rm;
-  ClasspathStream cp_stream(class_path);
+  Thread* THREAD = Thread::current();
+  int len = (int)strlen(class_path);
+  int end = 0;
+
+  // Iterate over class path entries
+  for (int start = 0; start < len; start = end) {
+    while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+      end++;
+    }
+    EXCEPTION_MARK;
+    ResourceMark rm(THREAD);
+    char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
+    strncpy(path, &class_path[start], end - start);
+    path[end - start] = '\0';
 
-  while (cp_stream.has_next()) {
-    const char* path = cp_stream.get_next();
-    update_class_path_entry_list(path, false, false, false);
+    update_class_path_entry_list(path, false, false);
+
+    while (class_path[end] == os::path_separator()[0]) {
+      end++;
+    }
   }
 }
 
 void ClassLoader::add_to_module_path_entries(const char* path,
                                              ClassPathEntry* entry) {

@@ -570,11 +610,11 @@
     vm_exit_during_initialization();
   }
   // File or directory found
   ClassPathEntry* new_entry = NULL;
   new_entry = create_class_path_entry(path, &st, true /* throw_exception */,
-                                      false /*is_boot_append */, false /* from_class_path_attr */, CHECK);
+                                      false /*is_boot_append */, CHECK);
   if (new_entry == NULL) {
     return;
   }
 
   add_to_module_path_entries(path, new_entry);

@@ -599,34 +639,47 @@
 void ClassLoader::setup_patch_mod_entries() {
   Thread* THREAD = Thread::current();
   GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
   int num_of_entries = patch_mod_args->length();
 
+
   // Set up the boot loader's _patch_mod_entries list
   _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
 
   for (int i = 0; i < num_of_entries; i++) {
     const char* module_name = (patch_mod_args->at(i))->module_name();
     Symbol* const module_sym = SymbolTable::new_symbol(module_name);
     assert(module_sym != NULL, "Failed to obtain Symbol for module name");
     ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
 
     char* class_path = (patch_mod_args->at(i))->path_string();
-    ResourceMark rm(THREAD);
-    ClasspathStream cp_stream(class_path);
+    int len = (int)strlen(class_path);
+    int end = 0;
+    // Iterate over the module's class path entries
+    for (int start = 0; start < len; start = end) {
+      while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+        end++;
+      }
+      EXCEPTION_MARK;
+      ResourceMark rm(THREAD);
+      char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
+      strncpy(path, &class_path[start], end - start);
+      path[end - start] = '\0';
 
-    while (cp_stream.has_next()) {
-      const char* path = cp_stream.get_next();
       struct stat st;
       if (os::stat(path, &st) == 0) {
         // File or directory found
-        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK);
+        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
         // If the path specification is valid, enter it into this module's list
         if (new_entry != NULL) {
           module_cpl->add_to_list(new_entry);
         }
       }
+
+      while (class_path[end] == os::path_separator()[0]) {
+        end++;
+      }
     }
 
     // Record the module into the list of --patch-module entries only if
     // valid ClassPathEntrys have been created
     if (module_cpl->module_first_entry() != NULL) {

@@ -650,36 +703,43 @@
   return false;
 }
 
 // Set up the _jrt_entry if present and boot append path
 void ClassLoader::setup_boot_search_path(const char *class_path) {
-  EXCEPTION_MARK;
-  ResourceMark rm(THREAD);
-  ClasspathStream cp_stream(class_path);
+  int len = (int)strlen(class_path);
+  int end = 0;
   bool set_base_piece = true;
 
 #if INCLUDE_CDS
   if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     if (!Arguments::has_jimage()) {
       vm_exit_during_initialization("CDS is not supported in exploded JDK build", NULL);
     }
   }
 #endif
 
-  while (cp_stream.has_next()) {
-    const char* path = cp_stream.get_next();
+  // Iterate over class path entries
+  for (int start = 0; start < len; start = end) {
+    while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+      end++;
+    }
+    EXCEPTION_MARK;
+    ResourceMark rm(THREAD);
+    char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
+    strncpy(path, &class_path[start], end - start);
+    path[end - start] = '\0';
 
     if (set_base_piece) {
       // The first time through the bootstrap_search setup, it must be determined
       // what the base or core piece of the boot loader search is.  Either a java runtime
       // image is present or this is an exploded module build situation.
       assert(string_ends_with(path, MODULES_IMAGE_NAME) || string_ends_with(path, JAVA_BASE_NAME),
              "Incorrect boot loader search path, no java runtime image or " JAVA_BASE_NAME " exploded build");
       struct stat st;
       if (os::stat(path, &st) == 0) {
         // Directory found
-        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK);
+        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
 
         // Check for a jimage
         if (Arguments::has_jimage()) {
           assert(_jrt_entry == NULL, "should not setup bootstrap class search path twice");
           _jrt_entry = new_entry;

@@ -692,11 +752,15 @@
       }
       set_base_piece = false;
     } else {
       // Every entry on the system boot class path after the initial base piece,
       // which is set by os::set_boot_path(), is considered an appended entry.
-      update_class_path_entry_list(path, false, true, false);
+      update_class_path_entry_list(path, false, true);
+    }
+
+    while (class_path[end] == os::path_separator()[0]) {
+      end++;
     }
   }
 }
 
 // During an exploded modules build, each module defined to the boot loader

@@ -716,11 +780,11 @@
   jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
 
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // Directory found
-    ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK);
+    ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
 
     // If the path specification is valid, enter it into this module's list.
     // There is no need to check for duplicate modules in the exploded entry list,
     // since no two modules with the same name can be defined to the boot loader.
     // This is checked at module definition time in Modules::define_module.

@@ -736,13 +800,11 @@
   }
 }
 
 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
                                                      bool throw_exception,
-                                                     bool is_boot_append,
-                                                     bool from_class_path_attr,
-                                                     TRAPS) {
+                                                     bool is_boot_append, TRAPS) {
   JavaThread* thread = JavaThread::current();
   ClassPathEntry* new_entry = NULL;
   if ((st->st_mode & S_IFMT) == S_IFREG) {
     ResourceMark rm(thread);
     // Regular file, should be a zip or jimage file

@@ -768,11 +830,11 @@
         ThreadToNativeFromVM ttn(thread);
         HandleMark hm(thread);
         zip = (*ZipOpen)(canonical_path, &error_msg);
       }
       if (zip != NULL && error_msg == NULL) {
-        new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr);
+        new_entry = new ClassPathZipEntry(zip, path, is_boot_append);
       } else {
         char *msg;
         if (error_msg == NULL) {
           msg = NEW_RESOURCE_ARRAY_IN_THREAD(thread, char, strlen(path) + 128); ;
           jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);

@@ -818,11 +880,11 @@
           HandleMark hm(thread);
           zip = (*ZipOpen)(canonical_path, &error_msg);
         }
         if (zip != NULL && error_msg == NULL) {
           // create using canonical path
-          return new ClassPathZipEntry(zip, canonical_path, is_boot_append, false);
+          return new ClassPathZipEntry(zip, canonical_path, is_boot_append);
         }
       }
     }
   }
   return NULL;

@@ -892,18 +954,17 @@
 
 // Returns true IFF the file/dir exists and the entry was successfully created.
 bool ClassLoader::update_class_path_entry_list(const char *path,
                                                bool check_for_duplicates,
                                                bool is_boot_append,
-                                               bool from_class_path_attr,
                                                bool throw_exception) {
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // File or directory found
     ClassPathEntry* new_entry = NULL;
     Thread* THREAD = Thread::current();
-    new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, from_class_path_attr, CHECK_(false));
+    new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, CHECK_(false));
     if (new_entry == NULL) {
       return false;
     }
 
     // Do not reorder the bootclasspath which would break get_system_package().

@@ -913,10 +974,15 @@
     } else {
       add_to_app_classpath_entries(path, new_entry, check_for_duplicates);
     }
     return true;
   } else {
+#if INCLUDE_CDS
+    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+      _shared_paths_misc_info->add_nonexist_path(path);
+    }
+#endif
     return false;
   }
 }
 
 static void print_module_entry_table(const GrowableArray<ModuleClassPathList*>* const module_list) {

@@ -1532,17 +1598,24 @@
 
   // lookup zip library entry points
   load_zip_library();
   // lookup jimage library entry points
   load_jimage_library();
+#if INCLUDE_CDS
+  // initialize search path
+  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    _shared_paths_misc_info = new SharedPathsMiscInfo();
+  }
+#endif
   setup_bootstrap_search_path();
 }
 
 #if INCLUDE_CDS
 void ClassLoader::initialize_shared_path() {
   if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     ClassLoaderExt::setup_search_paths();
+    _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
   }
 }
 
 void ClassLoader::initialize_module_path(TRAPS) {
   if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
< prev index next >