8197954: Remove unnecessary intermediary APIs from AppCDS implementation
authoriklam
Thu, 26 Apr 2018 13:40:58 -0700
changeset 50039 9fec54fe663d
parent 50038 3db7884546a1
child 50040 a7d4b4d78c37
8197954: Remove unnecessary intermediary APIs from AppCDS implementation Reviewed-by: jiangli, ccheung
src/hotspot/share/classfile/classListParser.cpp
src/hotspot/share/classfile/classLoader.cpp
src/hotspot/share/classfile/classLoader.hpp
src/hotspot/share/classfile/classLoaderExt.cpp
src/hotspot/share/classfile/classLoaderExt.hpp
src/hotspot/share/classfile/dictionary.cpp
src/hotspot/share/classfile/klassFactory.cpp
src/hotspot/share/classfile/sharedClassUtil.cpp
src/hotspot/share/classfile/sharedClassUtil.hpp
src/hotspot/share/classfile/sharedPathsMiscInfo.cpp
src/hotspot/share/classfile/sharedPathsMiscInfo.hpp
src/hotspot/share/classfile/systemDictionary.cpp
src/hotspot/share/classfile/systemDictionary.hpp
src/hotspot/share/classfile/systemDictionaryShared.cpp
src/hotspot/share/classfile/systemDictionary_ext.hpp
src/hotspot/share/memory/filemap.cpp
src/hotspot/share/memory/filemap.hpp
src/hotspot/share/memory/metaspaceShared.cpp
src/hotspot/share/memory/metaspaceShared.hpp
src/hotspot/share/memory/universe.cpp
src/hotspot/share/oops/klass.hpp
src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/classfile/classListParser.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classListParser.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -27,7 +27,6 @@
 #include "jimage.hpp"
 #include "classfile/classListParser.hpp"
 #include "classfile/classLoaderExt.hpp"
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
--- a/src/hotspot/share/classfile/classLoader.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoader.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -72,7 +72,6 @@
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/sharedPathsMiscInfo.hpp"
 #endif
 
@@ -660,7 +659,7 @@
 }
 
 bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
-  SharedPathsMiscInfo* checker = SharedClassUtil::allocate_shared_paths_misc_info((char*)buf, size);
+  SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size);
   bool result = checker->check();
   delete checker;
   return result;
@@ -1406,8 +1405,6 @@
                                                          name->utf8_length());
   assert(file_name != NULL, "invariant");
 
-  ClassLoaderExt::Context context(class_name, file_name, THREAD);
-
   // Lookup stream for parsing .class file
   ClassFileStream* stream = NULL;
   s2 classpath_index = 0;
@@ -1480,7 +1477,7 @@
     return NULL;
   }
 
-  stream->set_verify(context.should_verify(classpath_index));
+  stream->set_verify(ClassLoaderExt::should_verify(classpath_index));
 
   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   Handle protection_domain;
@@ -1628,8 +1625,7 @@
                                                          ik->name()->utf8_length());
   assert(file_name != NULL, "invariant");
 
-  ClassLoaderExt::Context context(class_name, file_name, CATCH);
-  context.record_result(ik->name(), classpath_index, ik, THREAD);
+  ClassLoaderExt::record_result(classpath_index, ik, THREAD);
 }
 #endif // INCLUDE_CDS
 
@@ -1699,7 +1695,7 @@
 #if INCLUDE_CDS
   // initialize search path
   if (DumpSharedSpaces) {
-    _shared_paths_misc_info = SharedClassUtil::allocate_shared_paths_misc_info();
+    _shared_paths_misc_info = new SharedPathsMiscInfo();
   }
 #endif
   setup_bootstrap_search_path();
--- a/src/hotspot/share/classfile/classLoader.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoader.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -426,8 +426,6 @@
   static int   get_shared_paths_misc_info_size();
   static void* get_shared_paths_misc_info();
   static bool  check_shared_paths_misc_info(void* info, int size);
-  static int   get_module_paths_misc_info_size();
-  static void* get_module_paths_misc_info();
   static void  exit_with_path_failure(const char* error, const char* message);
   static char* skip_uri_protocol(char* source);
   static void  record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS);
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -31,7 +31,6 @@
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/klassFactory.hpp"
 #include "classfile/modules.hpp"
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/sharedPathsMiscInfo.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -57,8 +56,7 @@
 void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
 #if INCLUDE_CDS
   warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended");
-  FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
-  header->set_has_platform_or_app_classes(false);
+  FileMapInfo::current_info()->header()->set_has_platform_or_app_classes(false);
 #endif
   ClassLoader::add_to_boot_append_entries(new_entry);
 }
@@ -228,11 +226,7 @@
   ClassLoaderExt::setup_app_search_path();
 }
 
-Thread* ClassLoaderExt::Context::_dump_thread = NULL;
-
-void ClassLoaderExt::record_result(ClassLoaderExt::Context *context,
-                                   Symbol* class_name,
-                                   const s2 classpath_index,
+void ClassLoaderExt::record_result(const s2 classpath_index,
                                    InstanceKlass* result,
                                    TRAPS) {
   assert(DumpSharedSpaces, "Sanity");
--- a/src/hotspot/share/classfile/classLoaderExt.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -29,74 +29,21 @@
 #include "classfile/moduleEntry.hpp"
 #include "utilities/macros.hpp"
 
-CDS_ONLY(class SharedPathsMiscInfoExt;)
-CDS_ONLY(class ClassListParser;)
+class ClassListParser;
 
 class ClassLoaderExt: public ClassLoader { // AllStatic
 public:
   enum SomeConstants {
     max_classpath_index = 0x7fff
   };
-  // ClassLoaderExt::Context --
-  //
-  // This is used by DumpSharedSpaces only - it enforces the same classloader
-  // delegation model as would be in run-time. I.e.,
-  // + classes defined by the NULL class loader cannot load classes in the PLATFORM or APP paths.
-  // + classes defined by the PLATFORM class loader cannot load classes in the APP paths.
-  class Context {
-    static Thread* _dump_thread;
-    const char* _class_name;
-    const char* _file_name;
-  public:
-    const char* class_name() {
-      return _class_name;
-    }
-    const char* file_name() {
-      return _file_name;
-    }
-
-    Context(const char* class_name, const char* file_name, TRAPS) {
-      _class_name = class_name;
-      _file_name = file_name;
-#if INCLUDE_CDS
-      if (!DumpSharedSpaces && !UseSharedSpaces) {
-        // Must not modify _app_class_paths_start_index if we're not using CDS.
-        assert(_app_class_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
-      }
-#endif
-    }
-
-    bool should_verify(int classpath_index) {
-      CDS_ONLY(return (classpath_index >= _app_class_paths_start_index);)
-      NOT_CDS(return false;)
-    }
-
-    void record_result(Symbol* class_name,
-                       const s2 classpath_index,
-                       InstanceKlass* result,
-                       TRAPS) {
-#if INCLUDE_CDS
-      ClassLoaderExt::record_result(this, class_name, classpath_index, result, THREAD);
-#endif
-    }
-
-    ~Context() {
-#if INCLUDE_CDS
-      if (!DumpSharedSpaces && !UseSharedSpaces) {
-        // Must not modify app_class_paths_start_index if we're not using CDS.
-        assert(_app_class_paths_start_index == ClassLoaderExt::max_classpath_index, "must be");
-      }
-#endif
-    }
-  }; // end ClassLoaderExt::Context
 
 private:
 #if INCLUDE_CDS
   static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
   static void setup_app_search_path(); // Only when -Xshare:dump
   static void process_module_table(ModuleEntryTable* met, TRAPS);
-  static SharedPathsMiscInfoExt* shared_paths_misc_info() {
-    return (SharedPathsMiscInfoExt*)_shared_paths_misc_info;
+  static SharedPathsMiscInfo* shared_paths_misc_info() {
+    return (SharedPathsMiscInfo*)_shared_paths_misc_info;
   }
   // index of first app JAR in shared classpath entry table
   static jshort _app_class_paths_start_index;
@@ -110,6 +57,10 @@
 public:
   CDS_ONLY(static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates);)
 
+  static bool should_verify(int classpath_index) {
+    CDS_ONLY(return (classpath_index >= _app_class_paths_start_index);)
+    NOT_CDS(return false;)
+  }
   // Called by JVMTI code to add boot classpath
   static void append_boot_classpath(ClassPathEntry* new_entry);
 
@@ -156,9 +107,7 @@
     return _has_app_classes || _has_platform_classes;
   }
 
-  static void record_result(class ClassLoaderExt::Context *context,
-                            Symbol* class_name,
-                            const s2 classpath_index,
+  static void record_result(const s2 classpath_index,
                             InstanceKlass* result, TRAPS);
   static InstanceKlass* load_class(Symbol* h_name, const char* path, TRAPS);
   static Klass* load_one_class(ClassListParser* parser, TRAPS);
--- a/src/hotspot/share/classfile/dictionary.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/dictionary.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -24,7 +24,6 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoaderData.inline.hpp"
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/dictionary.inline.hpp"
 #include "classfile/protectionDomainCache.hpp"
 #include "classfile/systemDictionary.hpp"
--- a/src/hotspot/share/classfile/klassFactory.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/klassFactory.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -29,7 +29,7 @@
 #include "classfile/classLoaderData.hpp"
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/klassFactory.hpp"
-#include "classfile/sharedClassUtil.hpp"
+#include "memory/filemap.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "prims/jvmtiEnvBase.hpp"
--- a/src/hotspot/share/classfile/sharedClassUtil.cpp	Mon May 07 20:42:36 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/classLoader.hpp"
-#include "classfile/classLoaderExt.hpp"
-#include "classfile/dictionary.hpp"
-#include "classfile/javaClasses.hpp"
-#include "classfile/sharedClassUtil.hpp"
-#include "classfile/stringTable.hpp"
-#include "classfile/symbolTable.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/systemDictionaryShared.hpp"
-#include "memory/filemap.hpp"
-#include "memory/metadataFactory.hpp"
-#include "memory/resourceArea.hpp"
-#include "oops/instanceKlass.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/java.hpp"
-#include "runtime/os.inline.hpp"
-
-class ManifestStream: public ResourceObj {
-  private:
-  u1*   _buffer_start; // Buffer bottom
-  u1*   _buffer_end;   // Buffer top (one past last element)
-  u1*   _current;      // Current buffer position
-
- public:
-  // Constructor
-  ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
-                                           _current(buffer) {
-    _buffer_end = buffer + length;
-  }
-
-  static bool is_attr(u1* attr, const char* name) {
-    return strncmp((const char*)attr, name, strlen(name)) == 0;
-  }
-
-  static char* copy_attr(u1* value, size_t len) {
-    char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
-    strncpy(buf, (char*)value, len);
-    buf[len] = 0;
-    return buf;
-  }
-
-  // The return value indicates if the JAR is signed or not
-  bool check_is_signed() {
-    u1* attr = _current;
-    bool isSigned = false;
-    while (_current < _buffer_end) {
-      if (*_current == '\n') {
-        *_current = '\0';
-        u1* value = (u1*)strchr((char*)attr, ':');
-        if (value != NULL) {
-          assert(*(value+1) == ' ', "Unrecognized format" );
-          if (strstr((char*)attr, "-Digest") != NULL) {
-            isSigned = true;
-            break;
-          }
-        }
-        *_current = '\n'; // restore
-        attr = _current + 1;
-      }
-      _current ++;
-    }
-    return isSigned;
-  }
-};
-
-void SharedPathsMiscInfoExt::print_path(outputStream* out, int type, const char* path) {
-  switch(type) {
-  case APP:
-    ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
-    break;
-  case MODULE:
-    ClassLoader::trace_class_path("Checking module path: ", path);
-    break;
-  default:
-    SharedPathsMiscInfo::print_path(out, type, path);
-  }
-}
-
-bool SharedPathsMiscInfoExt::check(jint type, const char* path) {
-
-  switch (type) {
-  case APP:
-    {
-      // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
-      size_t len = strlen(path);
-      const char *appcp = Arguments::get_appclasspath();
-      assert(appcp != NULL, "NULL app classpath");
-      size_t appcp_len = strlen(appcp);
-      if (appcp_len < len) {
-        return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
-      }
-      ResourceMark rm;
-      char* tmp_path;
-      if (len == appcp_len) {
-        tmp_path = (char*)appcp;
-      } else {
-        tmp_path = NEW_RESOURCE_ARRAY(char, len + 1);
-        strncpy(tmp_path, appcp, len);
-        tmp_path[len] = 0;
-      }
-      if (os::file_name_strcmp(path, tmp_path) != 0) {
-        return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
-      }
-      if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
-        return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
-      }
-    }
-    break;
-  default:
-    return SharedPathsMiscInfo::check(type, path);
-  }
-
-  return true;
-}
-
-void SharedClassUtil::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* e, TRAPS) {
-  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
-  SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)e;
-  ResourceMark rm(THREAD);
-  jint manifest_size;
-  bool isSigned;
-
-  if (cpe->is_jar_file()) {
-    char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
-    if (manifest != NULL) {
-      ManifestStream* stream = new ManifestStream((u1*)manifest,
-                                                  manifest_size);
-      isSigned = stream->check_is_signed();
-      if (isSigned) {
-        ent->_is_signed = true;
-      } else {
-        // Copy the manifest into the shared archive
-        manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
-        Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
-                                                        manifest_size,
-                                                        THREAD);
-        char* p = (char*)(buf->data());
-        memcpy(p, manifest, manifest_size);
-        ent->set_manifest(buf);
-        ent->_is_signed = false;
-      }
-    }
-  }
-}
-
-void SharedClassUtil::initialize(TRAPS) {
-  if (UseSharedSpaces) {
-    int size = FileMapInfo::get_number_of_shared_paths();
-    if (size > 0) {
-      SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
-      FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
-      ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
-      ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
-    }
-  }
-
-  if (DumpSharedSpaces) {
-    if (SharedArchiveConfigFile) {
-      read_extra_data(SharedArchiveConfigFile, THREAD);
-    }
-  }
-}
-
-void SharedClassUtil::read_extra_data(const char* filename, TRAPS) {
-  HashtableTextDump reader(filename);
-  reader.check_version("VERSION: 1.0");
-
-  while (reader.remain() > 0) {
-    int utf8_length;
-    int prefix_type = reader.scan_prefix(&utf8_length);
-    ResourceMark rm(THREAD);
-    char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
-    reader.get_utf8(utf8_buffer, utf8_length);
-
-    if (prefix_type == HashtableTextDump::SymbolPrefix) {
-      SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
-    } else{
-      assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
-      utf8_buffer[utf8_length] = '\0';
-      oop s = StringTable::intern(utf8_buffer, THREAD);
-    }
-  }
-}
-
-bool SharedClassUtil::is_classpath_entry_signed(int classpath_index) {
-  assert(classpath_index >= 0, "Sanity");
-  SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)
-    FileMapInfo::shared_path(classpath_index);
-  return ent->_is_signed;
-}
-
-void FileMapHeaderExt::populate(FileMapInfo* mapinfo, size_t alignment) {
-  FileMapInfo::FileMapHeader::populate(mapinfo, alignment);
-
-  ClassLoaderExt::finalize_shared_paths_misc_info();
-  _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
-  _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
-
-  _verify_local = BytecodeVerificationLocal;
-  _verify_remote = BytecodeVerificationRemote;
-  _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
-}
-
-bool FileMapHeaderExt::validate() {
-  if (!FileMapInfo::FileMapHeader::validate()) {
-    return false;
-  }
-
-  // This must be done after header validation because it might change the
-  // header data
-  const char* prop = Arguments::get_property("java.system.class.loader");
-  if (prop != NULL) {
-    warning("Archived non-system classes are disabled because the "
-            "java.system.class.loader property is specified (value = \"%s\"). "
-            "To use archived non-system classes, this property must be not be set", prop);
-    _has_platform_or_app_classes = false;
-  }
-
-  // For backwards compatibility, we don't check the verification setting
-  // if the archive only contains system classes.
-  if (_has_platform_or_app_classes &&
-      ((!_verify_local && BytecodeVerificationLocal) ||
-       (!_verify_remote && BytecodeVerificationRemote))) {
-    FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
-                  "verification setting than the current setting.");
-    return false;
-  }
-
-  return true;
-}
--- a/src/hotspot/share/classfile/sharedClassUtil.hpp	Mon May 07 20:42:36 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
-#define SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
-
-#include "classfile/sharedPathsMiscInfo.hpp"
-#include "memory/filemap.hpp"
-#include "classfile/classLoaderExt.hpp"
-#include "classfile/dictionary.hpp"
-#include "classfile/systemDictionaryShared.hpp"
-#include "oops/klass.hpp"
-
-class FileMapHeaderExt: public FileMapInfo::FileMapHeader {
-public:
-  jshort _app_class_paths_start_index;  // Index of first app classpath entry
-  jshort _app_module_paths_start_index; // Index of first module path entry
-  bool   _verify_local;                 // BytecodeVerificationLocal setting
-  bool   _verify_remote;                // BytecodeVerificationRemote setting
-  bool   _has_platform_or_app_classes;  // Archive contains app classes
-
-  FileMapHeaderExt() {
-    _has_platform_or_app_classes = true;
-  }
-  void set_has_platform_or_app_classes(bool v) {
-    _has_platform_or_app_classes = v;
-  }
-  bool has_platform_or_app_classes() { return _has_platform_or_app_classes; }
-  virtual void populate(FileMapInfo* mapinfo, size_t alignment);
-  virtual bool validate();
-};
-
-// In addition to SharedPathsMiscInfo, the following information is also stored
-//
-//
-// + The value of Arguments::get_appclasspath() used during dumping.
-//
-class SharedPathsMiscInfoExt : public SharedPathsMiscInfo {
-private:
-  int   _app_offset;
-public:
-  enum {
-    APP       = 5,
-    MODULE    = 6
-  };
-
-  virtual const char* type_name(int type) {
-    switch (type) {
-    case APP:     return "APP";
-    case MODULE:  return "MODULE";
-    default:      return SharedPathsMiscInfo::type_name(type);
-    }
-  }
-
-  virtual void print_path(outputStream* out, int type, const char* path);
-
-  SharedPathsMiscInfoExt() : SharedPathsMiscInfo() {
-    _app_offset = 0;
-  }
-  SharedPathsMiscInfoExt(char* buf, int size) : SharedPathsMiscInfo(buf, size) {
-    _app_offset = 0;
-  }
-
-  virtual bool check(jint type, const char* path);
-
-  void add_app_classpath(const char* path) {
-    add_path(path, APP);
-  }
-
-  void record_app_offset() {
-    _app_offset = get_used_bytes();
-  }
-  void pop_app() {
-    _cur_ptr = _buf_start + _app_offset;
-    write_jint(0);
-  }
-};
-
-class SharedClassPathEntryExt: public SharedClassPathEntry {
-public:
-  //Maniest attributes
-  bool _is_signed;
-  void set_manifest(Array<u1>* manifest) {
-    _manifest = manifest;
-  }
-};
-
-class SharedClassUtil : AllStatic {
-public:
-  static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
-    return new SharedPathsMiscInfoExt();
-  }
-
-  static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
-    return new SharedPathsMiscInfoExt(buf, size);
-  }
-
-  static FileMapInfo::FileMapHeader* allocate_file_map_header() {
-    return new FileMapHeaderExt();
-  }
-
-  static size_t file_map_header_size() {
-    return sizeof(FileMapHeaderExt);
-  }
-
-  static size_t shared_class_path_entry_size() {
-    return sizeof(SharedClassPathEntryExt);
-  }
-
-  static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
-  static void initialize(TRAPS);
-
-private:
-  static void read_extra_data(const char* filename, TRAPS);
-
-public:
-  static bool is_classpath_entry_signed(int classpath_index);
-};
-
-#endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -24,7 +24,6 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
-#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/sharedPathsMiscInfo.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
@@ -36,6 +35,7 @@
 #include "utilities/ostream.hpp"
 
 SharedPathsMiscInfo::SharedPathsMiscInfo() {
+  _app_offset = 0;
   _buf_size = INITIAL_BUF_SIZE;
   _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
   _allocated = true;
@@ -89,12 +89,15 @@
 
 void SharedPathsMiscInfo::print_path(outputStream* out, int type, const char* path) {
   switch (type) {
-  case BOOT:
+  case BOOT_PATH:
     out->print("Expecting BOOT path=%s", path);
     break;
   case NON_EXIST:
     out->print("Expecting that %s does not exist", path);
     break;
+  case APP_PATH:
+    ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
+    break;
   default:
     ShouldNotReachHere();
   }
@@ -139,7 +142,7 @@
 
 bool SharedPathsMiscInfo::check(jint type, const char* path) {
   switch (type) {
-  case BOOT:
+  case BOOT_PATH:
     // In the future we should perform the check based on the content of the mapped archive.
     if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
       return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
@@ -155,6 +158,33 @@
       }
     }
     break;
+  case APP_PATH:
+    {
+      // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
+      size_t len = strlen(path);
+      const char *appcp = Arguments::get_appclasspath();
+      assert(appcp != NULL, "NULL app classpath");
+      size_t appcp_len = strlen(appcp);
+      if (appcp_len < len) {
+        return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
+      }
+      ResourceMark rm;
+      char* tmp_path;
+      if (len == appcp_len) {
+        tmp_path = (char*)appcp;
+      } else {
+        tmp_path = NEW_RESOURCE_ARRAY(char, len + 1);
+        strncpy(tmp_path, appcp, len);
+        tmp_path[len] = 0;
+      }
+      if (os::file_name_strcmp(path, tmp_path) != 0) {
+        return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
+      }
+      if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
+        return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
+      }
+    }
+    break;
   default:
     return fail("Corrupted archive file header");
   }
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -35,8 +35,6 @@
 //
 // + The values of Arguments::get_sysclasspath() used during dumping.
 //
-// + The meta-index file(s) used during dumping (incl modification time and size)
-//
 // + The class path elements specified during dumping but did not exist --
 //   these elements must also be specified at run time, and they also must not
 //   exist at run time.
@@ -53,6 +51,8 @@
 // two situations. See below.
 
 class SharedPathsMiscInfo : public CHeapObj<mtClass> {
+private:
+  int   _app_offset;
 protected:
   char* _buf_start;
   char* _cur_ptr;
@@ -67,7 +67,7 @@
 
 protected:
   static bool fail(const char* msg, const char* name = NULL);
-  virtual bool check(jint type, const char* path);
+  bool check(jint type, const char* path);
 
 public:
   enum {
@@ -77,6 +77,7 @@
   SharedPathsMiscInfo();
   // This constructor is used when validating the misc info (during run time)
   SharedPathsMiscInfo(char *buff, int size) {
+    _app_offset = 0;
     _cur_ptr = _buf_start = buff;
     _end_ptr = _buf_start + size;
     _buf_size = size;
@@ -100,8 +101,20 @@
 
   // The path must exist, and must contain exactly <num_entries> files/dirs
   void add_boot_classpath(const char* path) {
-    add_path(path, BOOT);
+    add_path(path, BOOT_PATH);
+  }
+
+  void add_app_classpath(const char* path) {
+    add_path(path, APP_PATH);
   }
+  void record_app_offset() {
+    _app_offset = get_used_bytes();
+  }
+  void pop_app() {
+    _cur_ptr = _buf_start + _app_offset;
+    write_jint(0);
+  }
+
   int write_jint(jint num) {
     write(&num, sizeof(num));
     return 0;
@@ -120,22 +133,24 @@
 
   // reading --
 
+private:
   enum {
-    BOOT      = 1,
-    NON_EXIST = 2
+    BOOT_PATH      = 1,
+    APP_PATH       = 2,
+    NON_EXIST      = 3
   };
 
-  virtual const char* type_name(int type) {
+  const char* type_name(int type) {
     switch (type) {
-    case BOOT:      return "BOOT";
-    case NON_EXIST: return "NON_EXIST";
-    default:        ShouldNotReachHere(); return "?";
+    case BOOT_PATH:   return "BOOT";
+    case APP_PATH:    return "APP";
+    case NON_EXIST:   return "NON_EXIST";
+    default:          ShouldNotReachHere(); return "?";
     }
   }
 
-  virtual void print_path(outputStream* os, int type, const char* path);
+  void print_path(outputStream* os, int type, const char* path);
 
-  bool check();
   bool read_jint(jint *ptr) {
     return read(ptr, sizeof(jint));
   }
@@ -145,6 +160,9 @@
   bool read_time(time_t *ptr) {
     return read(ptr, sizeof(time_t));
   }
+
+public:
+  bool check();
 };
 
 #endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -84,7 +84,6 @@
 #include "trace/tracing.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #endif
 #if INCLUDE_JVMCI
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -26,7 +26,6 @@
 #define SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_HPP
 
 #include "classfile/classLoader.hpp"
-#include "classfile/systemDictionary_ext.hpp"
 #include "jvmci/systemDictionary_jvmci.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/symbol.hpp"
@@ -186,6 +185,7 @@
   do_klass(File_klass,                                  java_io_File,                              Pre                 ) \
   do_klass(URL_klass,                                   java_net_URL,                              Pre                 ) \
   do_klass(Jar_Manifest_klass,                          java_util_jar_Manifest,                    Pre                 ) \
+  do_klass(jdk_internal_loader_ClassLoaders_klass,      jdk_internal_loader_ClassLoaders,          Pre                 ) \
   do_klass(jdk_internal_loader_ClassLoaders_AppClassLoader_klass,      jdk_internal_loader_ClassLoaders_AppClassLoader,       Pre ) \
   do_klass(jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass, jdk_internal_loader_ClassLoaders_PlatformClassLoader,  Pre ) \
   do_klass(CodeSource_klass,                            java_security_CodeSource,                  Pre                 ) \
@@ -212,8 +212,6 @@
   do_klass(Integer_klass,                               java_lang_Integer,                         Pre                 ) \
   do_klass(Long_klass,                                  java_lang_Long,                            Pre                 ) \
                                                                                                                          \
-  /* Extensions */                                                                                                       \
-  WK_KLASSES_DO_EXT(do_klass)                                                                                            \
   /* JVMCI classes. These are loaded on-demand. */                                                                       \
   JVMCI_WK_KLASSES_DO(do_klass)                                                                                          \
                                                                                                                          \
@@ -223,7 +221,6 @@
 class SystemDictionary : AllStatic {
   friend class VMStructs;
   friend class SystemDictionaryHandles;
-  friend class SharedClassUtil;
 
  public:
   enum WKID {
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -31,7 +31,6 @@
 #include "classfile/compactHashtable.inline.hpp"
 #include "classfile/dictionary.hpp"
 #include "classfile/javaClasses.hpp"
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
@@ -92,7 +91,7 @@
   Handle empty;
   Handle manifest ;
   if (shared_jar_manifest(shared_path_index) == NULL) {
-    SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_path(shared_path_index);
+    SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index);
     long size = ent->manifest_size();
     if (size <= 0) {
       return empty; // No manifest - return NULL handle
@@ -303,8 +302,7 @@
   if (ik != NULL) {
     int index = ik->shared_classpath_index();
     assert(index >= 0, "Sanity");
-    SharedClassPathEntryExt* ent =
-            (SharedClassPathEntryExt*)FileMapInfo::shared_path(index);
+    SharedClassPathEntry* ent = FileMapInfo::shared_path(index);
     Symbol* class_name = ik->name();
 
     if (ent->is_modules_image()) {
@@ -476,41 +474,38 @@
 //   [1] JVM_FindLoadedClass
 //   [2] java.lang.ClassLoader.findLoadedClass0()
 //   [3] java.lang.ClassLoader.findLoadedClass()
-//   [4] java.lang.ClassLoader.loadClass()
-//   [5] jdk.internal.loader.ClassLoaders$AppClassLoader_klass.loadClass()
-//
-// Because AppCDS supports only the PlatformClassLoader and AppClassLoader, we make the following
-// assumptions (based on the JDK 8.0 source code):
+//   [4] jdk.internal.loader.BuiltinClassLoader.loadClassOrNull()
+//   [5] jdk.internal.loader.BuiltinClassLoader.loadClass()
+//   [6] jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(), or
+//       jdk.internal.loader.ClassLoaders$PlatformClassLoader.loadClass()
 //
-// [a] these two loaders use the default implementation of
-//     ClassLoader.loadClass(String name, boolean resolve), which
-// [b] calls findLoadedClass(name), immediately followed by parent.loadClass(),
-//     immediately followed by findClass(name).
-// [c] If the requested class is a shared class of the current class loader, parent.loadClass()
-//     always returns null, and
-// [d] if AppCDS is not enabled, the class would be loaded by findClass() by decoding it from a
-//     JAR file and then parsed.
+// AppCDS supports fast class loading for these 2 built-in class loaders:
+//    jdk.internal.loader.ClassLoaders$PlatformClassLoader
+//    jdk.internal.loader.ClassLoaders$AppClassLoader
+// with the following assumptions (based on the JDK core library source code):
+//
+// [a] these two loaders use the BuiltinClassLoader.loadClassOrNull() to
+//     load the named class.
+// [b] BuiltinClassLoader.loadClassOrNull() first calls findLoadedClass(name).
+// [c] At this point, if we can find the named class inside the
+//     shared_dictionary, we can perform further checks (see
+//     is_shared_class_visible_for_classloader() to ensure that this class
+//     was loaded by the same class loader during dump time.
 //
 // Given these assumptions, we intercept the findLoadedClass() call to invoke
 // SystemDictionaryShared::find_or_load_shared_class() to load the shared class from
-// the archive. The reasons are:
-//
-// + Because AppCDS is a commercial feature, we want to hide the implementation. There
-//   is currently no easy way to hide Java code, so we did it with native code.
-// + Start-up is improved because we avoid decoding the JAR file, and avoid delegating
-//   to the parent (since we know the parent will not find this class).
+// the archive for the 2 built-in class loaders. This way,
+// we can improve start-up because we avoid decoding the classfile,
+// and avoid delegating to the parent loader.
 //
 // NOTE: there's a lot of assumption about the Java code. If any of that change, this
 // needs to be redesigned.
-//
-// An alternative is to modify the Java code of AppClassLoader.loadClass().
-//
+
 InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
                  Symbol* name, Handle class_loader, TRAPS) {
   InstanceKlass* k = NULL;
   if (UseSharedSpaces) {
-    FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
-    if (!header->has_platform_or_app_classes()) {
+    if (!FileMapInfo::current_info()->header()->has_platform_or_app_classes()) {
       return NULL;
     }
 
--- a/src/hotspot/share/classfile/systemDictionary_ext.hpp	Mon May 07 20:42:36 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015, 2017 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
-#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
-
-#if INCLUDE_CDS
-
-#define WK_KLASSES_DO_EXT(do_klass) \
-  /* well-known classes */                                                                                            \
-  do_klass(jdk_internal_loader_ClassLoaders_klass,         jdk_internal_loader_ClassLoaders,            Pre )         \
-  /*end*/
-
-#else
-
-#define WK_KLASSES_DO_EXT(do_klass)
-
-#endif // INCLUDE_CDS
-
-#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARY_EXT_HPP
--- a/src/hotspot/share/memory/filemap.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/filemap.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -25,8 +25,8 @@
 #include "precompiled.hpp"
 #include "jvm.h"
 #include "classfile/classLoader.inline.hpp"
+#include "classfile/classLoaderExt.hpp"
 #include "classfile/compactHashtable.inline.hpp"
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionaryShared.hpp"
@@ -159,8 +159,9 @@
   memset((void*)this, 0, sizeof(FileMapInfo));
   _file_offset = 0;
   _file_open = false;
-  _header = SharedClassUtil::allocate_file_map_header();
+  _header = new FileMapHeader();
   _header->_version = _invalid_version;
+  _header->_has_platform_or_app_classes = true;
 }
 
 FileMapInfo::~FileMapInfo() {
@@ -172,10 +173,6 @@
   _header->populate(this, alignment);
 }
 
-size_t FileMapInfo::FileMapHeader::data_size() {
-  return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
-}
-
 void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
   _magic = 0xf00baba2;
   _version = _current_version;
@@ -198,6 +195,14 @@
 
   // JVM version string ... changes on each build.
   get_header_version(_jvm_ident);
+
+  ClassLoaderExt::finalize_shared_paths_misc_info();
+  _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
+  _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
+
+  _verify_local = BytecodeVerificationLocal;
+  _verify_remote = BytecodeVerificationRemote;
+  _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
 }
 
 void SharedClassPathEntry::init(const char* name, TRAPS) {
@@ -278,7 +283,7 @@
   assert(jrt != NULL,
          "No modular java runtime image present when allocating the CDS classpath entry table");
 
-  size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
+  size_t entry_size = sizeof(SharedClassPathEntry); // assert ( should be 8 byte aligned??)
   int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
   int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
   int num_module_path_entries = ClassLoader::num_module_path_entries();
@@ -299,7 +304,7 @@
     ent->init(cpe->name(), THREAD);
     if (cpe != jrt) { // No need to do jimage.
       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
-      SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
+      update_shared_classpath(cpe, ent, THREAD);
     }
     cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
     i++;
@@ -314,7 +319,7 @@
     SharedClassPathEntry* ent = shared_path(i);
     ent->init(acpe->name(), THREAD);
     EXCEPTION_MARK;
-    SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
+    update_shared_classpath(acpe, ent, THREAD);
     acpe = acpe->next();
     i++;
   }
@@ -326,7 +331,7 @@
     SharedClassPathEntry* ent = shared_path(i);
     ent->init(mpe->name(), THREAD);
     EXCEPTION_MARK;
-    SharedClassUtil::update_shared_classpath(mpe, ent, THREAD);
+    update_shared_classpath(mpe, ent, THREAD);
     mpe = mpe->next();
     i++;
   }
@@ -360,6 +365,84 @@
   }
 }
 
+class ManifestStream: public ResourceObj {
+  private:
+  u1*   _buffer_start; // Buffer bottom
+  u1*   _buffer_end;   // Buffer top (one past last element)
+  u1*   _current;      // Current buffer position
+
+ public:
+  // Constructor
+  ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
+                                           _current(buffer) {
+    _buffer_end = buffer + length;
+  }
+
+  static bool is_attr(u1* attr, const char* name) {
+    return strncmp((const char*)attr, name, strlen(name)) == 0;
+  }
+
+  static char* copy_attr(u1* value, size_t len) {
+    char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+    strncpy(buf, (char*)value, len);
+    buf[len] = 0;
+    return buf;
+  }
+
+  // The return value indicates if the JAR is signed or not
+  bool check_is_signed() {
+    u1* attr = _current;
+    bool isSigned = false;
+    while (_current < _buffer_end) {
+      if (*_current == '\n') {
+        *_current = '\0';
+        u1* value = (u1*)strchr((char*)attr, ':');
+        if (value != NULL) {
+          assert(*(value+1) == ' ', "Unrecognized format" );
+          if (strstr((char*)attr, "-Digest") != NULL) {
+            isSigned = true;
+            break;
+          }
+        }
+        *_current = '\n'; // restore
+        attr = _current + 1;
+      }
+      _current ++;
+    }
+    return isSigned;
+  }
+};
+
+void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  ResourceMark rm(THREAD);
+  jint manifest_size;
+  bool isSigned;
+
+  if (cpe->is_jar_file()) {
+    char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
+    if (manifest != NULL) {
+      ManifestStream* stream = new ManifestStream((u1*)manifest,
+                                                  manifest_size);
+      isSigned = stream->check_is_signed();
+      if (isSigned) {
+        ent->set_is_signed(true);
+      } else {
+        // Copy the manifest into the shared archive
+        manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
+        Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+                                                        manifest_size,
+                                                        THREAD);
+        char* p = (char*)(buf->data());
+        memcpy(p, manifest, manifest_size);
+        ent->set_manifest(buf);
+        ent->set_is_signed(false);
+      }
+    }
+  }
+}
+
+
 bool FileMapInfo::validate_shared_path_table() {
   assert(UseSharedSpaces, "runtime only");
 
@@ -368,14 +451,13 @@
   _shared_path_entry_size = _header->_shared_path_entry_size;
   _shared_path_table_size = _header->_shared_path_table_size;
 
-  FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
-  int module_paths_start_index = header->_app_module_paths_start_index;
+  int module_paths_start_index = _header->_app_module_paths_start_index;
 
   // If the shared archive contain app or platform classes, validate all entries
   // in the shared path table. Otherwise, only validate the boot path entries (with
   // entry index < _app_class_paths_start_index).
-  int count = header->has_platform_or_app_classes() ?
-              _shared_path_table_size : header->_app_class_paths_start_index;
+  int count = _header->has_platform_or_app_classes() ?
+              _shared_path_table_size : _header->_app_class_paths_start_index;
 
   for (int i=0; i<count; i++) {
     if (i < module_paths_start_index) {
@@ -1078,6 +1160,26 @@
     return false;
   }
 
+  // This must be done after header validation because it might change the
+  // header data
+  const char* prop = Arguments::get_property("java.system.class.loader");
+  if (prop != NULL) {
+    warning("Archived non-system classes are disabled because the "
+            "java.system.class.loader property is specified (value = \"%s\"). "
+            "To use archived non-system classes, this property must be not be set", prop);
+    _has_platform_or_app_classes = false;
+  }
+
+  // For backwards compatibility, we don't check the verification setting
+  // if the archive only contains system classes.
+  if (_has_platform_or_app_classes &&
+      ((!_verify_local && BytecodeVerificationLocal) ||
+       (!_verify_remote && BytecodeVerificationRemote))) {
+    FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
+                  "verification setting than the current setting.");
+    return false;
+  }
+
   return true;
 }
 
--- a/src/hotspot/share/memory/filemap.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/filemap.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -49,6 +49,7 @@
   long   _filesize;           // jar/jimage file size, -1 if is directory, -2 if other
   Array<char>* _name;
   Array<u1>*   _manifest;
+  bool _is_signed;
 
 public:
   void init(const char* name, TRAPS);
@@ -70,6 +71,15 @@
   int manifest_size() const {
     return (_manifest == NULL) ? 0 : _manifest->length();
   }
+  void set_manifest(Array<u1>* manifest) {
+    _manifest = manifest;
+  }
+  void set_is_signed(bool s) {
+    _is_signed = s;
+  }
+  bool is_signed() {
+    return _is_signed;
+  }
 };
 
 class FileMapInfo : public CHeapObj<mtInternal> {
@@ -97,13 +107,16 @@
 
 public:
   struct FileMapHeaderBase : public CHeapObj<mtClass> {
-    virtual bool validate() = 0;
-    virtual void populate(FileMapInfo* info, size_t alignment) = 0;
+    // Need to put something here. Otherwise, in product build, because CHeapObj has no virtual
+    // methods, we would get sizeof(FileMapHeaderBase) == 1 with gcc.
+    intx _dummy;
   };
   struct FileMapHeader : FileMapHeaderBase {
     // Use data() and data_size() to memcopy to/from the FileMapHeader. We need to
     // avoid read/writing the C++ vtable pointer.
-    static size_t data_size();
+    static size_t data_size() {
+      return sizeof(FileMapHeader) - sizeof(FileMapInfo::FileMapHeaderBase);
+    }
     char* data() {
       return ((char*)this) + sizeof(FileMapHeaderBase);
     }
@@ -146,7 +159,7 @@
 
     // The _paths_misc_info is a variable-size structure that records "miscellaneous"
     // information during dumping. It is generated and validated by the
-    // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp and sharedClassUtil.hpp for
+    // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp for
     // detailed description.
     //
     // The _paths_misc_info data is stored as a byte array in the archive file header,
@@ -172,10 +185,21 @@
     size_t _shared_path_entry_size;
     Array<u8>* _shared_path_table;
 
+    jshort _app_class_paths_start_index;  // Index of first app classpath entry
+    jshort _app_module_paths_start_index; // Index of first module path entry
+    bool   _verify_local;                 // BytecodeVerificationLocal setting
+    bool   _verify_remote;                // BytecodeVerificationRemote setting
+    bool   _has_platform_or_app_classes;  // Archive contains app classes
+
+    void set_has_platform_or_app_classes(bool v) {
+      _has_platform_or_app_classes = v;
+    }
+    bool has_platform_or_app_classes() { return _has_platform_or_app_classes; }
+
     char* region_addr(int idx);
 
-    virtual bool validate();
-    virtual void populate(FileMapInfo* info, size_t alignment);
+    bool validate();
+    void populate(FileMapInfo* info, size_t alignment);
     int compute_crc();
   };
 
@@ -274,6 +298,7 @@
   static void allocate_shared_path_table();
   static void check_nonempty_dir_in_shared_path_table();
   bool validate_shared_path_table();
+  static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
 
   static SharedClassPathEntry* shared_path(int index) {
     if (index < 0) {
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -29,7 +29,6 @@
 #include "classfile/dictionary.hpp"
 #include "classfile/loaderConstraints.hpp"
 #include "classfile/placeholders.hpp"
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
@@ -323,6 +322,46 @@
                 _shared_rs.size(), p2i(_shared_rs.base()));
 }
 
+// Called by universe_post_init()
+void MetaspaceShared::post_initialize(TRAPS) {
+  if (UseSharedSpaces) {
+    int size = FileMapInfo::get_number_of_shared_paths();
+    if (size > 0) {
+      SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
+      FileMapInfo::FileMapHeader* header = FileMapInfo::current_info()->header();
+      ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
+      ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
+    }
+  }
+
+  if (DumpSharedSpaces) {
+    if (SharedArchiveConfigFile) {
+      read_extra_data(SharedArchiveConfigFile, THREAD);
+    }
+  }
+}
+
+void MetaspaceShared::read_extra_data(const char* filename, TRAPS) {
+  HashtableTextDump reader(filename);
+  reader.check_version("VERSION: 1.0");
+
+  while (reader.remain() > 0) {
+    int utf8_length;
+    int prefix_type = reader.scan_prefix(&utf8_length);
+    ResourceMark rm(THREAD);
+    char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
+    reader.get_utf8(utf8_buffer, utf8_length);
+
+    if (prefix_type == HashtableTextDump::SymbolPrefix) {
+      SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
+    } else{
+      assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
+      utf8_buffer[utf8_length] = '\0';
+      oop s = StringTable::intern(utf8_buffer, THREAD);
+    }
+  }
+}
+
 void MetaspaceShared::commit_shared_space_to(char* newtop) {
   assert(DumpSharedSpaces, "dump-time only");
   char* base = _shared_rs.base();
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -147,6 +147,7 @@
   }
   static void initialize_dumptime_shared_and_meta_spaces() NOT_CDS_RETURN;
   static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN;
+  static void post_initialize(TRAPS) NOT_CDS_RETURN;
 
   // Delta of this object from the bottom of the archive.
   static uintx object_delta(void* obj) {
@@ -250,5 +251,8 @@
   static void relocate_klass_ptr(oop o);
 
   static Klass* get_relocated_klass(Klass *k);
+
+private:
+  static void read_extra_data(const char* filename, TRAPS) NOT_CDS_RETURN;
 };
 #endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
--- a/src/hotspot/share/memory/universe.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/memory/universe.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -81,9 +81,6 @@
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
 #include "utilities/preserveException.hpp"
-#if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
-#endif
 
 // Known objects
 Klass* Universe::_boolArrayKlassObj                 = NULL;
@@ -1094,7 +1091,7 @@
 
   MemoryService::set_universe_heap(Universe::heap());
 #if INCLUDE_CDS
-  SharedClassUtil::initialize(CHECK_false);
+  MetaspaceShared::post_initialize(CHECK_false);
 #endif
   return true;
 }
--- a/src/hotspot/share/oops/klass.hpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/oops/klass.hpp	Thu Apr 26 13:40:58 2018 -0700
@@ -168,7 +168,6 @@
   // in the open archive heap region when archiving java object is supported.
   CDS_JAVA_HEAP_ONLY(narrowOop _archived_mirror;)
 
-  friend class SharedClassUtil;
 protected:
 
   // Constructor
--- a/src/hotspot/share/prims/jvm.cpp	Mon May 07 20:42:36 2018 +0200
+++ b/src/hotspot/share/prims/jvm.cpp	Thu Apr 26 13:40:58 2018 -0700
@@ -84,7 +84,6 @@
 #include "utilities/macros.hpp"
 #include "utilities/utf8.hpp"
 #if INCLUDE_CDS
-#include "classfile/sharedClassUtil.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #endif