Merge

Wed, 03 Sep 2014 09:25:44 +0200

author
tschatzl
date
Wed, 03 Sep 2014 09:25:44 +0200
changeset 7097
14b8221771dc
parent 7096
b1266b08b994
parent 7090
bb239308be67
child 7099
c35aec39d08e

Merge

src/share/vm/oops/instanceKlass.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/make/excludeSrc.make	Wed Sep 03 09:24:07 2014 +0200
     1.2 +++ b/make/excludeSrc.make	Wed Sep 03 09:25:44 2014 +0200
     1.3 @@ -70,7 +70,8 @@
     1.4        CXXFLAGS += -DINCLUDE_CDS=0
     1.5        CFLAGS += -DINCLUDE_CDS=0
     1.6  
     1.7 -      Src_Files_EXCLUDE += filemap.cpp metaspaceShared.cpp
     1.8 +      Src_Files_EXCLUDE += filemap.cpp metaspaceShared*.cpp sharedPathsMiscInfo.cpp \
     1.9 +        systemDictionaryShared.cpp classLoaderExt.cpp sharedClassUtil.cpp
    1.10  endif
    1.11  
    1.12  ifeq ($(INCLUDE_ALL_GCS), false)
     2.1 --- a/src/os/linux/vm/os_linux.cpp	Wed Sep 03 09:24:07 2014 +0200
     2.2 +++ b/src/os/linux/vm/os_linux.cpp	Wed Sep 03 09:25:44 2014 +0200
     2.3 @@ -2244,7 +2244,7 @@
     2.4    const siginfo_t* si = (const siginfo_t*)siginfo;
     2.5  
     2.6    os::Posix::print_siginfo_brief(st, si);
     2.7 -
     2.8 +#if INCLUDE_CDS
     2.9    if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
    2.10        UseSharedSpaces) {
    2.11      FileMapInfo* mapinfo = FileMapInfo::current_info();
    2.12 @@ -2254,6 +2254,7 @@
    2.13                  " possible disk/network problem.");
    2.14      }
    2.15    }
    2.16 +#endif
    2.17    st->cr();
    2.18  }
    2.19  
     3.1 --- a/src/share/vm/classfile/classFileParser.cpp	Wed Sep 03 09:24:07 2014 +0200
     3.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Wed Sep 03 09:25:44 2014 +0200
     3.3 @@ -31,6 +31,9 @@
     3.4  #include "classfile/javaClasses.hpp"
     3.5  #include "classfile/symbolTable.hpp"
     3.6  #include "classfile/systemDictionary.hpp"
     3.7 +#if INCLUDE_CDS
     3.8 +#include "classfile/systemDictionaryShared.hpp"
     3.9 +#endif
    3.10  #include "classfile/verificationType.hpp"
    3.11  #include "classfile/verifier.hpp"
    3.12  #include "classfile/vmSymbols.hpp"
    3.13 @@ -60,6 +63,7 @@
    3.14  #include "services/threadService.hpp"
    3.15  #include "utilities/array.hpp"
    3.16  #include "utilities/globalDefinitions.hpp"
    3.17 +#include "utilities/ostream.hpp"
    3.18  
    3.19  // We generally try to create the oops directly when parsing, rather than
    3.20  // allocating temporary data structures and copying the bytes twice. A
    3.21 @@ -3737,7 +3741,15 @@
    3.22    instanceKlassHandle nullHandle;
    3.23  
    3.24    // Figure out whether we can skip format checking (matching classic VM behavior)
    3.25 -  _need_verify = Verifier::should_verify_for(class_loader(), verify);
    3.26 +  if (DumpSharedSpaces) {
    3.27 +    // verify == true means it's a 'remote' class (i.e., non-boot class)
    3.28 +    // Verification decision is based on BytecodeVerificationRemote flag
    3.29 +    // for those classes.
    3.30 +    _need_verify = (verify) ? BytecodeVerificationRemote :
    3.31 +                              BytecodeVerificationLocal;
    3.32 +  } else {
    3.33 +    _need_verify = Verifier::should_verify_for(class_loader(), verify);
    3.34 +  }
    3.35  
    3.36    // Set the verify flag in stream
    3.37    cfs->set_verify(_need_verify);
    3.38 @@ -3756,6 +3768,18 @@
    3.39    u2 minor_version = cfs->get_u2_fast();
    3.40    u2 major_version = cfs->get_u2_fast();
    3.41  
    3.42 +  if (DumpSharedSpaces && major_version < JAVA_1_5_VERSION) {
    3.43 +    ResourceMark rm;
    3.44 +    warning("Pre JDK 1.5 class not supported by CDS: %u.%u %s",
    3.45 +            major_version,  minor_version, name->as_C_string());
    3.46 +    Exceptions::fthrow(
    3.47 +      THREAD_AND_LOCATION,
    3.48 +      vmSymbols::java_lang_UnsupportedClassVersionError(),
    3.49 +      "Unsupported major.minor version for dump time %u.%u",
    3.50 +      major_version,
    3.51 +      minor_version);
    3.52 +  }
    3.53 +
    3.54    // Check version numbers - we check this even with verifier off
    3.55    if (!is_supported_version(major_version, minor_version)) {
    3.56      if (name == NULL) {
    3.57 @@ -3863,6 +3887,18 @@
    3.58        if (cfs->source() != NULL) tty->print(" from %s", cfs->source());
    3.59        tty->print_cr("]");
    3.60      }
    3.61 +#if INCLUDE_CDS
    3.62 +    if (DumpLoadedClassList != NULL && cfs->source() != NULL && classlist_file->is_open()) {
    3.63 +      // Only dump the classes that can be stored into CDS archive
    3.64 +      if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
    3.65 +        if (name != NULL) {
    3.66 +          ResourceMark rm(THREAD);
    3.67 +          classlist_file->print_cr("%s", name->as_C_string());
    3.68 +          classlist_file->flush();
    3.69 +        }
    3.70 +      }
    3.71 +    }
    3.72 +#endif
    3.73  
    3.74      u2 super_class_index = cfs->get_u2_fast();
    3.75      instanceKlassHandle super_klass = parse_super_class(super_class_index,
     4.1 --- a/src/share/vm/classfile/classFileStream.cpp	Wed Sep 03 09:24:07 2014 +0200
     4.2 +++ b/src/share/vm/classfile/classFileStream.cpp	Wed Sep 03 09:25:44 2014 +0200
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -30,7 +30,7 @@
    4.11    THROW_MSG(vmSymbols::java_lang_ClassFormatError(), "Truncated class file");
    4.12  }
    4.13  
    4.14 -ClassFileStream::ClassFileStream(u1* buffer, int length, char* source) {
    4.15 +ClassFileStream::ClassFileStream(u1* buffer, int length, const char* source) {
    4.16    _buffer_start = buffer;
    4.17    _buffer_end   = buffer + length;
    4.18    _current      = buffer;
     5.1 --- a/src/share/vm/classfile/classFileStream.hpp	Wed Sep 03 09:24:07 2014 +0200
     5.2 +++ b/src/share/vm/classfile/classFileStream.hpp	Wed Sep 03 09:25:44 2014 +0200
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -53,20 +53,20 @@
    5.11    u1*   _buffer_start; // Buffer bottom
    5.12    u1*   _buffer_end;   // Buffer top (one past last element)
    5.13    u1*   _current;      // Current buffer position
    5.14 -  char* _source;       // Source of stream (directory name, ZIP/JAR archive name)
    5.15 +  const char* _source; // Source of stream (directory name, ZIP/JAR archive name)
    5.16    bool  _need_verify;  // True if verification is on for the class file
    5.17  
    5.18    void truncated_file_error(TRAPS);
    5.19   public:
    5.20    // Constructor
    5.21 -  ClassFileStream(u1* buffer, int length, char* source);
    5.22 +  ClassFileStream(u1* buffer, int length, const char* source);
    5.23  
    5.24    // Buffer access
    5.25    u1* buffer() const           { return _buffer_start; }
    5.26    int length() const           { return _buffer_end - _buffer_start; }
    5.27    u1* current() const          { return _current; }
    5.28    void set_current(u1* pos)    { _current = pos; }
    5.29 -  char* source() const         { return _source; }
    5.30 +  const char* source() const   { return _source; }
    5.31    void set_verify(bool flag)   { _need_verify = flag; }
    5.32  
    5.33    void check_truncated_file(bool b, TRAPS) {
     6.1 --- a/src/share/vm/classfile/classLoader.cpp	Wed Sep 03 09:24:07 2014 +0200
     6.2 +++ b/src/share/vm/classfile/classLoader.cpp	Wed Sep 03 09:25:44 2014 +0200
     6.3 @@ -26,8 +26,13 @@
     6.4  #include "classfile/classFileParser.hpp"
     6.5  #include "classfile/classFileStream.hpp"
     6.6  #include "classfile/classLoader.hpp"
     6.7 +#include "classfile/classLoaderExt.hpp"
     6.8  #include "classfile/classLoaderData.inline.hpp"
     6.9  #include "classfile/javaClasses.hpp"
    6.10 +#if INCLUDE_CDS
    6.11 +#include "classfile/sharedPathsMiscInfo.hpp"
    6.12 +#include "classfile/sharedClassUtil.hpp"
    6.13 +#endif
    6.14  #include "classfile/systemDictionary.hpp"
    6.15  #include "classfile/vmSymbols.hpp"
    6.16  #include "compiler/compileBroker.hpp"
    6.17 @@ -35,6 +40,7 @@
    6.18  #include "interpreter/bytecodeStream.hpp"
    6.19  #include "interpreter/oopMapCache.hpp"
    6.20  #include "memory/allocation.inline.hpp"
    6.21 +#include "memory/filemap.hpp"
    6.22  #include "memory/generation.hpp"
    6.23  #include "memory/oopFactory.hpp"
    6.24  #include "memory/universe.inline.hpp"
    6.25 @@ -129,8 +135,12 @@
    6.26  
    6.27  ClassPathEntry* ClassLoader::_first_entry         = NULL;
    6.28  ClassPathEntry* ClassLoader::_last_entry          = NULL;
    6.29 +int             ClassLoader::_num_entries         = 0;
    6.30  PackageHashtable* ClassLoader::_package_hash_table = NULL;
    6.31  
    6.32 +#if INCLUDE_CDS
    6.33 +SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
    6.34 +#endif
    6.35  // helper routines
    6.36  bool string_starts_with(const char* str, const char* str_to_find) {
    6.37    size_t str_len = strlen(str);
    6.38 @@ -194,9 +204,10 @@
    6.39    return false;
    6.40  }
    6.41  
    6.42 -ClassPathDirEntry::ClassPathDirEntry(char* dir) : ClassPathEntry() {
    6.43 -  _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
    6.44 -  strcpy(_dir, dir);
    6.45 +ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
    6.46 +  char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
    6.47 +  strcpy(copy, dir);
    6.48 +  _dir = copy;
    6.49  }
    6.50  
    6.51  
    6.52 @@ -209,6 +220,14 @@
    6.53    // check if file exists
    6.54    struct stat st;
    6.55    if (os::stat(path, &st) == 0) {
    6.56 +#if INCLUDE_CDS
    6.57 +    if (DumpSharedSpaces) {
    6.58 +      // We have already check in ClassLoader::check_shared_classpath() that the directory is empty, so
    6.59 +      // we should never find a file underneath it -- unless user has added a new file while we are running
    6.60 +      // the dump, in which case let's quit!
    6.61 +      ShouldNotReachHere();
    6.62 +    }
    6.63 +#endif
    6.64      // found file, open it
    6.65      int file_handle = os::open(path, 0, 0);
    6.66      if (file_handle != -1) {
    6.67 @@ -232,8 +251,9 @@
    6.68  
    6.69  ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name) : ClassPathEntry() {
    6.70    _zip = zip;
    6.71 -  _zip_name = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
    6.72 -  strcpy(_zip_name, zip_name);
    6.73 +  char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
    6.74 +  strcpy(copy, zip_name);
    6.75 +  _zip_name = copy;
    6.76  }
    6.77  
    6.78  ClassPathZipEntry::~ClassPathZipEntry() {
    6.79 @@ -243,13 +263,13 @@
    6.80    FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
    6.81  }
    6.82  
    6.83 -ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
    6.84 -  // enable call to C land
    6.85 +u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
    6.86 +    // enable call to C land
    6.87    JavaThread* thread = JavaThread::current();
    6.88    ThreadToNativeFromVM ttn(thread);
    6.89    // check whether zip archive contains name
    6.90 -  jint filesize, name_len;
    6.91 -  jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len);
    6.92 +  jint name_len;
    6.93 +  jzentry* entry = (*FindEntry)(_zip, name, filesize, &name_len);
    6.94    if (entry == NULL) return NULL;
    6.95    u1* buffer;
    6.96    char name_buf[128];
    6.97 @@ -260,19 +280,33 @@
    6.98      filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
    6.99    }
   6.100  
   6.101 -  // file found, get pointer to class in mmaped jar file.
   6.102 +  // file found, get pointer to the entry in mmapped jar file.
   6.103    if (ReadMappedEntry == NULL ||
   6.104        !(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
   6.105 -      // mmaped access not available, perhaps due to compression,
   6.106 +      // mmapped access not available, perhaps due to compression,
   6.107        // read contents into resource array
   6.108 -      buffer     = NEW_RESOURCE_ARRAY(u1, filesize);
   6.109 +      int size = (*filesize) + ((nul_terminate) ? 1 : 0);
   6.110 +      buffer = NEW_RESOURCE_ARRAY(u1, size);
   6.111        if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
   6.112    }
   6.113 +
   6.114 +  // return result
   6.115 +  if (nul_terminate) {
   6.116 +    buffer[*filesize] = 0;
   6.117 +  }
   6.118 +  return buffer;
   6.119 +}
   6.120 +
   6.121 +ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
   6.122 +  jint filesize;
   6.123 +  u1* buffer = open_entry(name, &filesize, false, CHECK_NULL);
   6.124 +  if (buffer == NULL) {
   6.125 +    return NULL;
   6.126 +  }
   6.127    if (UsePerfData) {
   6.128      ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
   6.129    }
   6.130 -  // return result
   6.131 -  return new ClassFileStream(buffer, filesize, _zip_name);    // Resource allocated
   6.132 +  return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
   6.133  }
   6.134  
   6.135  // invoke function for each entry in the zip file
   6.136 @@ -287,12 +321,13 @@
   6.137    }
   6.138  }
   6.139  
   6.140 -LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() {
   6.141 +LazyClassPathEntry::LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception) : ClassPathEntry() {
   6.142    _path = strdup(path);
   6.143    _st = *st;
   6.144    _meta_index = NULL;
   6.145    _resolved_entry = NULL;
   6.146    _has_error = false;
   6.147 +  _throw_exception = throw_exception;
   6.148  }
   6.149  
   6.150  bool LazyClassPathEntry::is_jar_file() {
   6.151 @@ -304,7 +339,11 @@
   6.152      return (ClassPathEntry*) _resolved_entry;
   6.153    }
   6.154    ClassPathEntry* new_entry = NULL;
   6.155 -  new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL);
   6.156 +  new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, _throw_exception, CHECK_NULL);
   6.157 +  if (!_throw_exception && new_entry == NULL) {
   6.158 +    assert(!HAS_PENDING_EXCEPTION, "must be");
   6.159 +    return NULL;
   6.160 +  }
   6.161    {
   6.162      ThreadCritical tc;
   6.163      if (_resolved_entry == NULL) {
   6.164 @@ -338,6 +377,23 @@
   6.165    return true;
   6.166  }
   6.167  
   6.168 +u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
   6.169 +  if (_has_error) {
   6.170 +    return NULL;
   6.171 +  }
   6.172 +  ClassPathEntry* cpe = resolve_entry(THREAD);
   6.173 +  if (cpe == NULL) {
   6.174 +    _has_error = true;
   6.175 +    return NULL;
   6.176 +  } else if (cpe->is_jar_file()) {
   6.177 +    return ((ClassPathZipEntry*)cpe)->open_entry(name, filesize, nul_terminate,THREAD);
   6.178 +  } else {
   6.179 +    ShouldNotReachHere();
   6.180 +    *filesize = 0;
   6.181 +    return NULL;
   6.182 +  }
   6.183 +}
   6.184 +
   6.185  static void print_meta_index(LazyClassPathEntry* entry,
   6.186                               GrowableArray<char*>& meta_packages) {
   6.187    tty->print("[Meta index for %s=", entry->name());
   6.188 @@ -348,15 +404,62 @@
   6.189    tty->print_cr("]");
   6.190  }
   6.191  
   6.192 +#if INCLUDE_CDS
   6.193 +void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
   6.194 +  assert(DumpSharedSpaces, "only called at dump time");
   6.195 +  tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure");
   6.196 +  vm_exit_during_initialization(error, message);
   6.197 +}
   6.198 +#endif
   6.199  
   6.200 -void ClassLoader::setup_meta_index() {
   6.201 +void ClassLoader::trace_class_path(const char* msg, const char* name) {
   6.202 +  if (!TraceClassPaths) {
   6.203 +    return;
   6.204 +  }
   6.205 +
   6.206 +  if (msg) {
   6.207 +    tty->print("%s", msg);
   6.208 +  }
   6.209 +  if (name) {
   6.210 +    if (strlen(name) < 256) {
   6.211 +      tty->print("%s", name);
   6.212 +    } else {
   6.213 +      // For very long paths, we need to print each character separately,
   6.214 +      // as print_cr() has a length limit
   6.215 +      while (name[0] != '\0') {
   6.216 +        tty->print("%c", name[0]);
   6.217 +        name++;
   6.218 +      }
   6.219 +    }
   6.220 +  }
   6.221 +  if (msg && msg[0] == '[') {
   6.222 +    tty->print_cr("]");
   6.223 +  } else {
   6.224 +    tty->cr();
   6.225 +  }
   6.226 +}
   6.227 +
   6.228 +void ClassLoader::setup_bootstrap_meta_index() {
   6.229    // Set up meta index which allows us to open boot jars lazily if
   6.230    // class data sharing is enabled
   6.231 +  const char* meta_index_path = Arguments::get_meta_index_path();
   6.232 +  const char* meta_index_dir  = Arguments::get_meta_index_dir();
   6.233 +  setup_meta_index(meta_index_path, meta_index_dir, 0);
   6.234 +}
   6.235 +
   6.236 +void ClassLoader::setup_meta_index(const char* meta_index_path, const char* meta_index_dir, int start_index) {
   6.237    const char* known_version = "% VERSION 2";
   6.238 -  char* meta_index_path = Arguments::get_meta_index_path();
   6.239 -  char* meta_index_dir  = Arguments::get_meta_index_dir();
   6.240    FILE* file = fopen(meta_index_path, "r");
   6.241    int line_no = 0;
   6.242 +#if INCLUDE_CDS
   6.243 +  if (DumpSharedSpaces) {
   6.244 +    if (file != NULL) {
   6.245 +      _shared_paths_misc_info->add_required_file(meta_index_path);
   6.246 +    } else {
   6.247 +      _shared_paths_misc_info->add_nonexist_path(meta_index_path);
   6.248 +    }
   6.249 +  }
   6.250 +#endif
   6.251    if (file != NULL) {
   6.252      ResourceMark rm;
   6.253      LazyClassPathEntry* cur_entry = NULL;
   6.254 @@ -391,7 +494,7 @@
   6.255            // Hand off current packages to current lazy entry (if any)
   6.256            if ((cur_entry != NULL) &&
   6.257                (boot_class_path_packages.length() > 0)) {
   6.258 -            if (TraceClassLoading && Verbose) {
   6.259 +            if ((TraceClassLoading || TraceClassPaths) && Verbose) {
   6.260                print_meta_index(cur_entry, boot_class_path_packages);
   6.261              }
   6.262              MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
   6.263 @@ -402,8 +505,10 @@
   6.264            boot_class_path_packages.clear();
   6.265  
   6.266            // Find lazy entry corresponding to this jar file
   6.267 -          for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next()) {
   6.268 -            if (entry->is_lazy() &&
   6.269 +          int count = 0;
   6.270 +          for (ClassPathEntry* entry = _first_entry; entry != NULL; entry = entry->next(), count++) {
   6.271 +            if (count >= start_index &&
   6.272 +                entry->is_lazy() &&
   6.273                  string_starts_with(entry->name(), meta_index_dir) &&
   6.274                  string_ends_with(entry->name(), &package_name[2])) {
   6.275                cur_entry = (LazyClassPathEntry*) entry;
   6.276 @@ -440,7 +545,7 @@
   6.277      // Hand off current packages to current lazy entry (if any)
   6.278      if ((cur_entry != NULL) &&
   6.279          (boot_class_path_packages.length() > 0)) {
   6.280 -      if (TraceClassLoading && Verbose) {
   6.281 +      if ((TraceClassLoading || TraceClassPaths) && Verbose) {
   6.282          print_meta_index(cur_entry, boot_class_path_packages);
   6.283        }
   6.284        MetaIndex* index = new MetaIndex(boot_class_path_packages.adr_at(0),
   6.285 @@ -451,36 +556,90 @@
   6.286    }
   6.287  }
   6.288  
   6.289 +#if INCLUDE_CDS
   6.290 +void ClassLoader::check_shared_classpath(const char *path) {
   6.291 +  if (strcmp(path, "") == 0) {
   6.292 +    exit_with_path_failure("Cannot have empty path in archived classpaths", NULL);
   6.293 +  }
   6.294 +
   6.295 +  struct stat st;
   6.296 +  if (os::stat(path, &st) == 0) {
   6.297 +    if ((st.st_mode & S_IFREG) != S_IFREG) { // is directory
   6.298 +      if (!os::dir_is_empty(path)) {
   6.299 +        tty->print_cr("Error: non-empty directory '%s'", path);
   6.300 +        exit_with_path_failure("CDS allows only empty directories in archived classpaths", NULL);
   6.301 +      }
   6.302 +    }
   6.303 +  }
   6.304 +}
   6.305 +#endif
   6.306 +
   6.307  void ClassLoader::setup_bootstrap_search_path() {
   6.308    assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
   6.309 -  char* sys_class_path = os::strdup(Arguments::get_sysclasspath());
   6.310 -  if (TraceClassLoading && Verbose) {
   6.311 -    tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path);
   6.312 +  const char* sys_class_path = Arguments::get_sysclasspath();
   6.313 +  if (PrintSharedArchiveAndExit) {
   6.314 +    // Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
   6.315 +    // the same as the bootcp of the shared archive.
   6.316 +  } else {
   6.317 +    trace_class_path("[Bootstrap loader class path=", sys_class_path);
   6.318    }
   6.319 +#if INCLUDE_CDS
   6.320 +  if (DumpSharedSpaces) {
   6.321 +    _shared_paths_misc_info->add_boot_classpath(sys_class_path);
   6.322 +  }
   6.323 +#endif
   6.324 +  setup_search_path(sys_class_path);
   6.325 +}
   6.326  
   6.327 -  int len = (int)strlen(sys_class_path);
   6.328 +#if INCLUDE_CDS
   6.329 +int ClassLoader::get_shared_paths_misc_info_size() {
   6.330 +  return _shared_paths_misc_info->get_used_bytes();
   6.331 +}
   6.332 +
   6.333 +void* ClassLoader::get_shared_paths_misc_info() {
   6.334 +  return _shared_paths_misc_info->buffer();
   6.335 +}
   6.336 +
   6.337 +bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
   6.338 +  SharedPathsMiscInfo* checker = SharedClassUtil::allocate_shared_paths_misc_info((char*)buf, size);
   6.339 +  bool result = checker->check();
   6.340 +  delete checker;
   6.341 +  return result;
   6.342 +}
   6.343 +#endif
   6.344 +
   6.345 +void ClassLoader::setup_search_path(const char *class_path) {
   6.346 +  int offset = 0;
   6.347 +  int len = (int)strlen(class_path);
   6.348    int end = 0;
   6.349  
   6.350    // Iterate over class path entries
   6.351    for (int start = 0; start < len; start = end) {
   6.352 -    while (sys_class_path[end] && sys_class_path[end] != os::path_separator()[0]) {
   6.353 +    while (class_path[end] && class_path[end] != os::path_separator()[0]) {
   6.354        end++;
   6.355      }
   6.356 -    char* path = NEW_C_HEAP_ARRAY(char, end-start+1, mtClass);
   6.357 -    strncpy(path, &sys_class_path[start], end-start);
   6.358 -    path[end-start] = '\0';
   6.359 +    EXCEPTION_MARK;
   6.360 +    ResourceMark rm(THREAD);
   6.361 +    char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
   6.362 +    strncpy(path, &class_path[start], end - start);
   6.363 +    path[end - start] = '\0';
   6.364      update_class_path_entry_list(path, false);
   6.365 -    FREE_C_HEAP_ARRAY(char, path, mtClass);
   6.366 -    while (sys_class_path[end] == os::path_separator()[0]) {
   6.367 +#if INCLUDE_CDS
   6.368 +    if (DumpSharedSpaces) {
   6.369 +      check_shared_classpath(path);
   6.370 +    }
   6.371 +#endif
   6.372 +    while (class_path[end] == os::path_separator()[0]) {
   6.373        end++;
   6.374      }
   6.375    }
   6.376  }
   6.377  
   6.378 -ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
   6.379 +ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
   6.380 +                                                     bool lazy, bool throw_exception, TRAPS) {
   6.381    JavaThread* thread = JavaThread::current();
   6.382    if (lazy) {
   6.383 -    return new LazyClassPathEntry(path, st);
   6.384 +    return new LazyClassPathEntry(path, st, throw_exception);
   6.385    }
   6.386    ClassPathEntry* new_entry = NULL;
   6.387    if ((st->st_mode & S_IFREG) == S_IFREG) {
   6.388 @@ -489,7 +648,11 @@
   6.389      char canonical_path[JVM_MAXPATHLEN];
   6.390      if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
   6.391        // This matches the classic VM
   6.392 -      THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
   6.393 +      if (throw_exception) {
   6.394 +        THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
   6.395 +      } else {
   6.396 +        return NULL;
   6.397 +      }
   6.398      }
   6.399      char* error_msg = NULL;
   6.400      jzfile* zip;
   6.401 @@ -501,7 +664,7 @@
   6.402      }
   6.403      if (zip != NULL && error_msg == NULL) {
   6.404        new_entry = new ClassPathZipEntry(zip, path);
   6.405 -      if (TraceClassLoading) {
   6.406 +      if (TraceClassLoading || TraceClassPaths) {
   6.407          tty->print_cr("[Opened %s]", path);
   6.408        }
   6.409      } else {
   6.410 @@ -515,12 +678,16 @@
   6.411          msg = NEW_RESOURCE_ARRAY(char, len); ;
   6.412          jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
   6.413        }
   6.414 -      THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
   6.415 +      if (throw_exception) {
   6.416 +        THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
   6.417 +      } else {
   6.418 +        return NULL;
   6.419 +      }
   6.420      }
   6.421    } else {
   6.422      // Directory
   6.423      new_entry = new ClassPathDirEntry(path);
   6.424 -    if (TraceClassLoading) {
   6.425 +    if (TraceClassLoading || TraceClassPaths) {
   6.426        tty->print_cr("[Path %s]", path);
   6.427      }
   6.428    }
   6.429 @@ -535,11 +702,8 @@
   6.430    struct stat st;
   6.431    if (os::stat(path, &st) == 0) {
   6.432      if ((st.st_mode & S_IFREG) == S_IFREG) {
   6.433 -      char orig_path[JVM_MAXPATHLEN];
   6.434        char canonical_path[JVM_MAXPATHLEN];
   6.435 -
   6.436 -      strcpy(orig_path, path);
   6.437 -      if (get_canonical_path(orig_path, canonical_path, JVM_MAXPATHLEN)) {
   6.438 +      if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
   6.439          char* error_msg = NULL;
   6.440          jzfile* zip;
   6.441          {
   6.442 @@ -581,23 +745,37 @@
   6.443        _last_entry = new_entry;
   6.444      }
   6.445    }
   6.446 +  _num_entries ++;
   6.447  }
   6.448  
   6.449 -void ClassLoader::update_class_path_entry_list(char *path,
   6.450 -                                               bool check_for_duplicates) {
   6.451 +// Returns true IFF the file/dir exists and the entry was successfully created.
   6.452 +bool ClassLoader::update_class_path_entry_list(const char *path,
   6.453 +                                               bool check_for_duplicates,
   6.454 +                                               bool throw_exception) {
   6.455    struct stat st;
   6.456    if (os::stat(path, &st) == 0) {
   6.457      // File or directory found
   6.458      ClassPathEntry* new_entry = NULL;
   6.459      Thread* THREAD = Thread::current();
   6.460 -    new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK);
   6.461 +    new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, throw_exception, CHECK_(false));
   6.462 +    if (new_entry == NULL) {
   6.463 +      return false;
   6.464 +    }
   6.465      // The kernel VM adds dynamically to the end of the classloader path and
   6.466      // doesn't reorder the bootclasspath which would break java.lang.Package
   6.467      // (see PackageInfo).
   6.468      // Add new entry to linked list
   6.469      if (!check_for_duplicates || !contains_entry(new_entry)) {
   6.470 -      add_to_list(new_entry);
   6.471 +      ClassLoaderExt::add_class_path_entry(path, check_for_duplicates, new_entry);
   6.472      }
   6.473 +    return true;
   6.474 +  } else {
   6.475 +#if INCLUDE_CDS
   6.476 +    if (DumpSharedSpaces) {
   6.477 +      _shared_paths_misc_info->add_nonexist_path(path);
   6.478 +    }
   6.479 +#endif
   6.480 +    return false;
   6.481    }
   6.482  }
   6.483  
   6.484 @@ -749,10 +927,10 @@
   6.485      assert(n == number_of_entries(), "just checking");
   6.486    }
   6.487  
   6.488 -  void copy_table(char** top, char* end, PackageHashtable* table);
   6.489 +  CDS_ONLY(void copy_table(char** top, char* end, PackageHashtable* table);)
   6.490  };
   6.491  
   6.492 -
   6.493 +#if INCLUDE_CDS
   6.494  void PackageHashtable::copy_table(char** top, char* end,
   6.495                                    PackageHashtable* table) {
   6.496    // Copy (relocate) the table to the shared space.
   6.497 @@ -760,33 +938,30 @@
   6.498  
   6.499    // Calculate the space needed for the package name strings.
   6.500    int i;
   6.501 -  int n = 0;
   6.502 -  for (i = 0; i < table_size(); ++i) {
   6.503 -    for (PackageInfo* pp = table->bucket(i);
   6.504 -                      pp != NULL;
   6.505 -                      pp = pp->next()) {
   6.506 -      n += (int)(strlen(pp->pkgname()) + 1);
   6.507 -    }
   6.508 -  }
   6.509 -  if (*top + n + sizeof(intptr_t) >= end) {
   6.510 -    report_out_of_shared_space(SharedMiscData);
   6.511 -  }
   6.512 -
   6.513 -  // Copy the table data (the strings) to the shared space.
   6.514 -  n = align_size_up(n, sizeof(HeapWord));
   6.515 -  *(intptr_t*)(*top) = n;
   6.516 -  *top += sizeof(intptr_t);
   6.517 +  intptr_t* tableSize = (intptr_t*)(*top);
   6.518 +  *top += sizeof(intptr_t);  // For table size
   6.519 +  char* tableStart = *top;
   6.520  
   6.521    for (i = 0; i < table_size(); ++i) {
   6.522      for (PackageInfo* pp = table->bucket(i);
   6.523                        pp != NULL;
   6.524                        pp = pp->next()) {
   6.525        int n1 = (int)(strlen(pp->pkgname()) + 1);
   6.526 +      if (*top + n1 >= end) {
   6.527 +        report_out_of_shared_space(SharedMiscData);
   6.528 +      }
   6.529        pp->set_pkgname((char*)memcpy(*top, pp->pkgname(), n1));
   6.530        *top += n1;
   6.531      }
   6.532    }
   6.533    *top = (char*)align_size_up((intptr_t)*top, sizeof(HeapWord));
   6.534 +  if (*top >= end) {
   6.535 +    report_out_of_shared_space(SharedMiscData);
   6.536 +  }
   6.537 +
   6.538 +  // Write table size
   6.539 +  intptr_t len = *top - (char*)tableStart;
   6.540 +  *tableSize = len;
   6.541  }
   6.542  
   6.543  
   6.544 @@ -797,7 +972,7 @@
   6.545  void ClassLoader::copy_package_info_table(char** top, char* end) {
   6.546    _package_hash_table->copy_table(top, end, _package_hash_table);
   6.547  }
   6.548 -
   6.549 +#endif
   6.550  
   6.551  PackageInfo* ClassLoader::lookup_package(const char *pkgname) {
   6.552    const char *cp = strrchr(pkgname, '/');
   6.553 @@ -890,7 +1065,8 @@
   6.554  
   6.555  instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
   6.556    ResourceMark rm(THREAD);
   6.557 -  EventMark m("loading class %s", h_name->as_C_string());
   6.558 +  const char* class_name = h_name->as_C_string();
   6.559 +  EventMark m("loading class %s", class_name);
   6.560    ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
   6.561  
   6.562    stringStream st;
   6.563 @@ -898,18 +1074,24 @@
   6.564    // st.print("%s.class", h_name->as_utf8());
   6.565    st.print_raw(h_name->as_utf8());
   6.566    st.print_raw(".class");
   6.567 -  char* name = st.as_string();
   6.568 +  const char* file_name = st.as_string();
   6.569 +  ClassLoaderExt::Context context(class_name, file_name, THREAD);
   6.570  
   6.571    // Lookup stream for parsing .class file
   6.572    ClassFileStream* stream = NULL;
   6.573    int classpath_index = 0;
   6.574 +  ClassPathEntry* e = NULL;
   6.575 +  instanceKlassHandle h;
   6.576    {
   6.577      PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
   6.578                                 ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
   6.579                                 PerfClassTraceTime::CLASS_LOAD);
   6.580 -    ClassPathEntry* e = _first_entry;
   6.581 +    e = _first_entry;
   6.582      while (e != NULL) {
   6.583 -      stream = e->open_stream(name, CHECK_NULL);
   6.584 +      stream = e->open_stream(file_name, CHECK_NULL);
   6.585 +      if (!context.check(stream, classpath_index)) {
   6.586 +        return h; // NULL
   6.587 +      }
   6.588        if (stream != NULL) {
   6.589          break;
   6.590        }
   6.591 @@ -918,9 +1100,7 @@
   6.592      }
   6.593    }
   6.594  
   6.595 -  instanceKlassHandle h;
   6.596    if (stream != NULL) {
   6.597 -
   6.598      // class file found, parse it
   6.599      ClassFileParser parser(stream);
   6.600      ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   6.601 @@ -930,12 +1110,19 @@
   6.602                                                         loader_data,
   6.603                                                         protection_domain,
   6.604                                                         parsed_name,
   6.605 -                                                       false,
   6.606 -                                                       CHECK_(h));
   6.607 -
   6.608 -    // add to package table
   6.609 -    if (add_package(name, classpath_index, THREAD)) {
   6.610 -      h = result;
   6.611 +                                                       context.should_verify(classpath_index),
   6.612 +                                                       THREAD);
   6.613 +    if (HAS_PENDING_EXCEPTION) {
   6.614 +      ResourceMark rm;
   6.615 +      if (DumpSharedSpaces) {
   6.616 +        tty->print_cr("Preload Error: Failed to load %s", class_name);
   6.617 +      }
   6.618 +      return h;
   6.619 +    }
   6.620 +    h = context.record_result(classpath_index, e, result, THREAD);
   6.621 +  } else {
   6.622 +    if (DumpSharedSpaces) {
   6.623 +      tty->print_cr("Preload Error: Cannot find %s", class_name);
   6.624      }
   6.625    }
   6.626  
   6.627 @@ -1030,14 +1217,27 @@
   6.628  
   6.629    // lookup zip library entry points
   6.630    load_zip_library();
   6.631 +#if INCLUDE_CDS
   6.632    // initialize search path
   6.633 +  if (DumpSharedSpaces) {
   6.634 +    _shared_paths_misc_info = SharedClassUtil::allocate_shared_paths_misc_info();
   6.635 +  }
   6.636 +#endif
   6.637    setup_bootstrap_search_path();
   6.638    if (LazyBootClassLoader) {
   6.639      // set up meta index which makes boot classpath initialization lazier
   6.640 -    setup_meta_index();
   6.641 +    setup_bootstrap_meta_index();
   6.642    }
   6.643  }
   6.644  
   6.645 +#if INCLUDE_CDS
   6.646 +void ClassLoader::initialize_shared_path() {
   6.647 +  if (DumpSharedSpaces) {
   6.648 +    ClassLoaderExt::setup_search_paths();
   6.649 +    _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
   6.650 +  }
   6.651 +}
   6.652 +#endif
   6.653  
   6.654  jlong ClassLoader::classloader_time_ms() {
   6.655    return UsePerfData ?
   6.656 @@ -1081,11 +1281,17 @@
   6.657  }
   6.658  
   6.659  
   6.660 -bool ClassLoader::get_canonical_path(char* orig, char* out, int len) {
   6.661 +bool ClassLoader::get_canonical_path(const char* orig, char* out, int len) {
   6.662    assert(orig != NULL && out != NULL && len > 0, "bad arguments");
   6.663    if (CanonicalizeEntry != NULL) {
   6.664 -    JNIEnv* env = JavaThread::current()->jni_environment();
   6.665 -    if ((CanonicalizeEntry)(env, os::native_path(orig), out, len) < 0) {
   6.666 +    JavaThread* THREAD = JavaThread::current();
   6.667 +    JNIEnv* env = THREAD->jni_environment();
   6.668 +    ResourceMark rm(THREAD);
   6.669 +
   6.670 +    // os::native_path writes into orig_copy
   6.671 +    char* orig_copy = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(orig)+1);
   6.672 +    strcpy(orig_copy, orig);
   6.673 +    if ((CanonicalizeEntry)(env, os::native_path(orig_copy), out, len) < 0) {
   6.674        return false;
   6.675      }
   6.676    } else {
     7.1 --- a/src/share/vm/classfile/classLoader.hpp	Wed Sep 03 09:24:07 2014 +0200
     7.2 +++ b/src/share/vm/classfile/classLoader.hpp	Wed Sep 03 09:25:44 2014 +0200
     7.3 @@ -72,11 +72,11 @@
     7.4  
     7.5  class ClassPathDirEntry: public ClassPathEntry {
     7.6   private:
     7.7 -  char* _dir;           // Name of directory
     7.8 +  const char* _dir;           // Name of directory
     7.9   public:
    7.10    bool is_jar_file()  { return false;  }
    7.11    const char* name()  { return _dir; }
    7.12 -  ClassPathDirEntry(char* dir);
    7.13 +  ClassPathDirEntry(const char* dir);
    7.14    ClassFileStream* open_stream(const char* name, TRAPS);
    7.15    // Debugging
    7.16    NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
    7.17 @@ -100,13 +100,14 @@
    7.18  
    7.19  class ClassPathZipEntry: public ClassPathEntry {
    7.20   private:
    7.21 -  jzfile* _zip;        // The zip archive
    7.22 -  char*   _zip_name;   // Name of zip archive
    7.23 +  jzfile* _zip;              // The zip archive
    7.24 +  const char*   _zip_name;   // Name of zip archive
    7.25   public:
    7.26    bool is_jar_file()  { return true;  }
    7.27    const char* name()  { return _zip_name; }
    7.28    ClassPathZipEntry(jzfile* zip, const char* zip_name);
    7.29    ~ClassPathZipEntry();
    7.30 +  u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
    7.31    ClassFileStream* open_stream(const char* name, TRAPS);
    7.32    void contents_do(void f(const char* name, void* context), void* context);
    7.33    // Debugging
    7.34 @@ -122,16 +123,18 @@
    7.35  // For lazier loading of boot class path entries
    7.36  class LazyClassPathEntry: public ClassPathEntry {
    7.37   private:
    7.38 -  char* _path; // dir or file
    7.39 +  const char* _path; // dir or file
    7.40    struct stat _st;
    7.41    MetaIndex* _meta_index;
    7.42    bool _has_error;
    7.43 +  bool _throw_exception;
    7.44    volatile ClassPathEntry* _resolved_entry;
    7.45    ClassPathEntry* resolve_entry(TRAPS);
    7.46   public:
    7.47    bool is_jar_file();
    7.48    const char* name()  { return _path; }
    7.49 -  LazyClassPathEntry(char* path, const struct stat* st);
    7.50 +  LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
    7.51 +  u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
    7.52    ClassFileStream* open_stream(const char* name, TRAPS);
    7.53    void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; }
    7.54    virtual bool is_lazy();
    7.55 @@ -142,6 +145,7 @@
    7.56  
    7.57  class PackageHashtable;
    7.58  class PackageInfo;
    7.59 +class SharedPathsMiscInfo;
    7.60  template <MEMFLAGS F> class HashtableBucket;
    7.61  
    7.62  class ClassLoader: AllStatic {
    7.63 @@ -149,7 +153,7 @@
    7.64    enum SomeConstants {
    7.65      package_hash_table_size = 31  // Number of buckets
    7.66    };
    7.67 - private:
    7.68 + protected:
    7.69    friend class LazyClassPathEntry;
    7.70  
    7.71    // Performance counters
    7.72 @@ -191,10 +195,15 @@
    7.73    static ClassPathEntry* _first_entry;
    7.74    // Last entry in linked list of ClassPathEntry instances
    7.75    static ClassPathEntry* _last_entry;
    7.76 +  static int _num_entries;
    7.77 +
    7.78    // Hash table used to keep track of loaded packages
    7.79    static PackageHashtable* _package_hash_table;
    7.80    static const char* _shared_archive;
    7.81  
    7.82 +  // Info used by CDS
    7.83 +  CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
    7.84 +
    7.85    // Hash function
    7.86    static unsigned int hash(const char *s, int n);
    7.87    // Returns the package file name corresponding to the specified package
    7.88 @@ -205,19 +214,23 @@
    7.89    static bool add_package(const char *pkgname, int classpath_index, TRAPS);
    7.90  
    7.91    // Initialization
    7.92 -  static void setup_meta_index();
    7.93 +  static void setup_bootstrap_meta_index();
    7.94 +  static void setup_meta_index(const char* meta_index_path, const char* meta_index_dir,
    7.95 +                               int start_index);
    7.96    static void setup_bootstrap_search_path();
    7.97 +  static void setup_search_path(const char *class_path);
    7.98 +
    7.99    static void load_zip_library();
   7.100 -  static ClassPathEntry* create_class_path_entry(char *path, const struct stat* st,
   7.101 -                                                 bool lazy, TRAPS);
   7.102 +  static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
   7.103 +                                                 bool lazy, bool throw_exception, TRAPS);
   7.104  
   7.105    // Canonicalizes path names, so strcmp will work properly. This is mainly
   7.106    // to avoid confusing the zip library
   7.107 -  static bool get_canonical_path(char* orig, char* out, int len);
   7.108 +  static bool get_canonical_path(const char* orig, char* out, int len);
   7.109   public:
   7.110 -  // Used by the kernel jvm.
   7.111 -  static void update_class_path_entry_list(char *path,
   7.112 -                                           bool check_for_duplicates);
   7.113 +  static bool update_class_path_entry_list(const char *path,
   7.114 +                                           bool check_for_duplicates,
   7.115 +                                           bool throw_exception=true);
   7.116    static void print_bootclasspath();
   7.117  
   7.118    // Timing
   7.119 @@ -300,6 +313,7 @@
   7.120  
   7.121    // Initialization
   7.122    static void initialize();
   7.123 +  CDS_ONLY(static void initialize_shared_path();)
   7.124    static void create_package_info_table();
   7.125    static void create_package_info_table(HashtableBucket<mtClass> *t, int length,
   7.126                                          int number_of_entries);
   7.127 @@ -314,10 +328,21 @@
   7.128      return e;
   7.129    }
   7.130  
   7.131 +#if INCLUDE_CDS
   7.132    // Sharing dump and restore
   7.133    static void copy_package_info_buckets(char** top, char* end);
   7.134    static void copy_package_info_table(char** top, char* end);
   7.135  
   7.136 +  static void  check_shared_classpath(const char *path);
   7.137 +  static void  finalize_shared_paths_misc_info();
   7.138 +  static int   get_shared_paths_misc_info_size();
   7.139 +  static void* get_shared_paths_misc_info();
   7.140 +  static bool  check_shared_paths_misc_info(void* info, int size);
   7.141 +  static void  exit_with_path_failure(const char* error, const char* message);
   7.142 +#endif
   7.143 +
   7.144 +  static void  trace_class_path(const char* msg, const char* name = NULL);
   7.145 +
   7.146    // VM monitoring and management support
   7.147    static jlong classloader_time_ms();
   7.148    static jlong class_method_total_size();
   7.149 @@ -341,7 +366,7 @@
   7.150  
   7.151    // Force compilation of all methods in all classes in bootstrap class path (stress test)
   7.152  #ifndef PRODUCT
   7.153 - private:
   7.154 + protected:
   7.155    static int _compile_the_world_class_counter;
   7.156    static int _compile_the_world_method_counter;
   7.157   public:
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/share/vm/classfile/classLoaderExt.hpp	Wed Sep 03 09:25:44 2014 +0200
     8.3 @@ -0,0 +1,69 @@
     8.4 +/*
     8.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.
    8.11 + *
    8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.15 + * version 2 for more details (a copy is included in the LICENSE file that
    8.16 + * accompanied this code).
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License version
    8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.21 + *
    8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.23 + * or visit www.oracle.com if you need additional information or have any
    8.24 + * questions.
    8.25 + *
    8.26 + */
    8.27 +
    8.28 +#ifndef SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
    8.29 +#define SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
    8.30 +
    8.31 +#include "classfile/classLoader.hpp"
    8.32 +
    8.33 +class ClassLoaderExt: public ClassLoader { // AllStatic
    8.34 +public:
    8.35 +
    8.36 +  class Context {
    8.37 +    const char* _file_name;
    8.38 +  public:
    8.39 +    Context(const char* class_name, const char* file_name, TRAPS) {
    8.40 +      _file_name = file_name;
    8.41 +    }
    8.42 +
    8.43 +    bool check(ClassFileStream* stream, const int classpath_index) {
    8.44 +      return true;
    8.45 +    }
    8.46 +
    8.47 +    bool should_verify(int classpath_index) {
    8.48 +      return false;
    8.49 +    }
    8.50 +
    8.51 +    instanceKlassHandle record_result(const int classpath_index,
    8.52 +                                      ClassPathEntry* e, instanceKlassHandle result, TRAPS) {
    8.53 +      if (ClassLoader::add_package(_file_name, classpath_index, THREAD)) {
    8.54 +        if (DumpSharedSpaces) {
    8.55 +          result->set_shared_classpath_index(classpath_index);
    8.56 +        }
    8.57 +        return result;
    8.58 +      } else {
    8.59 +        return instanceKlassHandle(); // NULL
    8.60 +      }
    8.61 +    }
    8.62 +  };
    8.63 +
    8.64 +
    8.65 +  static void add_class_path_entry(const char* path, bool check_for_duplicates,
    8.66 +                                   ClassPathEntry* new_entry) {
    8.67 +    ClassLoader::add_to_list(new_entry);
    8.68 +  }
    8.69 +  static void setup_search_paths() {}
    8.70 +};
    8.71 +
    8.72 +#endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
     9.1 --- a/src/share/vm/classfile/dictionary.cpp	Wed Sep 03 09:24:07 2014 +0200
     9.2 +++ b/src/share/vm/classfile/dictionary.cpp	Wed Sep 03 09:25:44 2014 +0200
     9.3 @@ -209,6 +209,29 @@
     9.4    _pd_cache_table->roots_oops_do(strong, weak);
     9.5  }
     9.6  
     9.7 +void Dictionary::remove_classes_in_error_state() {
     9.8 +  assert(DumpSharedSpaces, "supported only when dumping");
     9.9 +  DictionaryEntry* probe = NULL;
    9.10 +  for (int index = 0; index < table_size(); index++) {
    9.11 +    for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
    9.12 +      probe = *p;
    9.13 +      InstanceKlass* ik = InstanceKlass::cast(probe->klass());
    9.14 +      if (ik->is_in_error_state()) { // purge this entry
    9.15 +        *p = probe->next();
    9.16 +        if (probe == _current_class_entry) {
    9.17 +          _current_class_entry = NULL;
    9.18 +        }
    9.19 +        free_entry(probe);
    9.20 +        ResourceMark rm;
    9.21 +        tty->print_cr("Removed error class: %s", ik->external_name());
    9.22 +        continue;
    9.23 +      }
    9.24 +
    9.25 +      p = probe->next_addr();
    9.26 +    }
    9.27 +  }
    9.28 +}
    9.29 +
    9.30  void Dictionary::always_strong_oops_do(OopClosure* blk) {
    9.31    // Follow all system classes and temporary placeholders in dictionary; only
    9.32    // protection domain oops contain references into the heap. In a first
    9.33 @@ -682,16 +705,17 @@
    9.34  
    9.35  
    9.36  // ----------------------------------------------------------------------------
    9.37 -#ifndef PRODUCT
    9.38  
    9.39 -void Dictionary::print() {
    9.40 +void Dictionary::print(bool details) {
    9.41    ResourceMark rm;
    9.42    HandleMark   hm;
    9.43  
    9.44 -  tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",
    9.45 -                 table_size(), number_of_entries());
    9.46 -  tty->print_cr("^ indicates that initiating loader is different from "
    9.47 -                "defining loader");
    9.48 +  if (details) {
    9.49 +    tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",
    9.50 +                   table_size(), number_of_entries());
    9.51 +    tty->print_cr("^ indicates that initiating loader is different from "
    9.52 +                  "defining loader");
    9.53 +  }
    9.54  
    9.55    for (int index = 0; index < table_size(); index++) {
    9.56      for (DictionaryEntry* probe = bucket(index);
    9.57 @@ -702,21 +726,28 @@
    9.58        ClassLoaderData* loader_data =  probe->loader_data();
    9.59        bool is_defining_class =
    9.60           (loader_data == InstanceKlass::cast(e)->class_loader_data());
    9.61 -      tty->print("%s%s", is_defining_class ? " " : "^",
    9.62 +      tty->print("%s%s", ((!details) || is_defining_class) ? " " : "^",
    9.63                     e->external_name());
    9.64  
    9.65 +      if (details) {
    9.66          tty->print(", loader ");
    9.67 -      loader_data->print_value();
    9.68 +        if (loader_data != NULL) {
    9.69 +          loader_data->print_value();
    9.70 +        } else {
    9.71 +          tty->print("NULL");
    9.72 +        }
    9.73 +      }
    9.74        tty->cr();
    9.75      }
    9.76    }
    9.77 -  tty->cr();
    9.78 -  _pd_cache_table->print();
    9.79 +
    9.80 +  if (details) {
    9.81 +    tty->cr();
    9.82 +    _pd_cache_table->print();
    9.83 +  }
    9.84    tty->cr();
    9.85  }
    9.86  
    9.87 -#endif
    9.88 -
    9.89  void Dictionary::verify() {
    9.90    guarantee(number_of_entries() >= 0, "Verify of system dictionary failed");
    9.91  
    10.1 --- a/src/share/vm/classfile/dictionary.hpp	Wed Sep 03 09:24:07 2014 +0200
    10.2 +++ b/src/share/vm/classfile/dictionary.hpp	Wed Sep 03 09:25:44 2014 +0200
    10.3 @@ -100,6 +100,7 @@
    10.4    void methods_do(void f(Method*));
    10.5  
    10.6    void unlink(BoolObjectClosure* is_alive);
    10.7 +  void remove_classes_in_error_state();
    10.8  
    10.9    // Classes loaded by the bootstrap loader are always strongly reachable.
   10.10    // If we're not doing class unloading, all classes are strongly reachable.
   10.11 @@ -126,9 +127,7 @@
   10.12  
   10.13    ProtectionDomainCacheEntry* cache_get(oop protection_domain);
   10.14  
   10.15 -#ifndef PRODUCT
   10.16 -  void print();
   10.17 -#endif
   10.18 +  void print(bool details = true);
   10.19    void verify();
   10.20  };
   10.21  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/share/vm/classfile/sharedClassUtil.hpp	Wed Sep 03 09:25:44 2014 +0200
    11.3 @@ -0,0 +1,69 @@
    11.4 +/*
    11.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + *
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + *
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + *
   11.26 + */
   11.27 +
   11.28 +#ifndef SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
   11.29 +#define SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
   11.30 +
   11.31 +#include "classfile/sharedPathsMiscInfo.hpp"
   11.32 +#include "memory/filemap.hpp"
   11.33 +
   11.34 +class SharedClassUtil : AllStatic {
   11.35 +public:
   11.36 +
   11.37 +  static SharedPathsMiscInfo* allocate_shared_paths_misc_info() {
   11.38 +    return new SharedPathsMiscInfo();
   11.39 +  }
   11.40 +
   11.41 +  static SharedPathsMiscInfo* allocate_shared_paths_misc_info(char* buf, int size) {
   11.42 +    return new SharedPathsMiscInfo(buf, size);
   11.43 +  }
   11.44 +
   11.45 +  static FileMapInfo::FileMapHeader* allocate_file_map_header() {
   11.46 +    return new FileMapInfo::FileMapHeader();
   11.47 +  }
   11.48 +
   11.49 +  static size_t file_map_header_size() {
   11.50 +    return sizeof(FileMapInfo::FileMapHeader);
   11.51 +  }
   11.52 +
   11.53 +  static size_t shared_class_path_entry_size() {
   11.54 +    return sizeof(SharedClassPathEntry);
   11.55 +  }
   11.56 +
   11.57 +  static void update_shared_classpath(ClassPathEntry *cpe,
   11.58 +                                      SharedClassPathEntry* ent,
   11.59 +                                      time_t timestamp,
   11.60 +                                      long filesize, TRAPS) {
   11.61 +    ent->_timestamp = timestamp;
   11.62 +    ent->_filesize  = filesize;
   11.63 +  }
   11.64 +
   11.65 +  static void initialize(TRAPS) {}
   11.66 +
   11.67 +  inline static bool is_shared_boot_class(Klass* klass) {
   11.68 +    return (klass->_shared_class_path_index >= 0);
   11.69 +  }
   11.70 +};
   11.71 +
   11.72 +#endif // SHARE_VM_CLASSFILE_SHAREDCLASSUTIL_HPP
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Wed Sep 03 09:25:44 2014 +0200
    12.3 @@ -0,0 +1,154 @@
    12.4 +/*
    12.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.23 + * or visit www.oracle.com if you need additional information or have any
   12.24 + * questions.
   12.25 + *
   12.26 + */
   12.27 +
   12.28 +#include "precompiled.hpp"
   12.29 +#include "classfile/classLoader.hpp"
   12.30 +#include "classfile/classLoaderData.inline.hpp"
   12.31 +#include "classfile/sharedPathsMiscInfo.hpp"
   12.32 +#include "memory/allocation.inline.hpp"
   12.33 +#include "memory/metaspaceShared.hpp"
   12.34 +#include "runtime/arguments.hpp"
   12.35 +
   12.36 +void SharedPathsMiscInfo::add_path(const char* path, int type) {
   12.37 +  if (TraceClassPaths) {
   12.38 +    tty->print("[type=%s] ", type_name(type));
   12.39 +    trace_class_path("[Add misc shared path ", path);
   12.40 +  }
   12.41 +  write(path, strlen(path) + 1);
   12.42 +  write_jint(jint(type));
   12.43 +}
   12.44 +
   12.45 +void SharedPathsMiscInfo::ensure_size(size_t needed_bytes) {
   12.46 +  assert(_allocated, "cannot modify buffer during validation.");
   12.47 +  int used = get_used_bytes();
   12.48 +  int target = used + int(needed_bytes);
   12.49 +  if (target > _buf_size) {
   12.50 +    _buf_size = _buf_size * 2 + (int)needed_bytes;
   12.51 +    _buf_start = REALLOC_C_HEAP_ARRAY(char, _buf_start, _buf_size, mtClass);
   12.52 +    _cur_ptr = _buf_start + used;
   12.53 +    _end_ptr = _buf_start + _buf_size;
   12.54 +  }
   12.55 +}
   12.56 +
   12.57 +void SharedPathsMiscInfo::write(const void* ptr, size_t size) {
   12.58 +  ensure_size(size);
   12.59 +  memcpy(_cur_ptr, ptr, size);
   12.60 +  _cur_ptr += size;
   12.61 +}
   12.62 +
   12.63 +bool SharedPathsMiscInfo::read(void* ptr, size_t size) {
   12.64 +  if (_cur_ptr + size <= _end_ptr) {
   12.65 +    memcpy(ptr, _cur_ptr, size);
   12.66 +    _cur_ptr += size;
   12.67 +    return true;
   12.68 +  }
   12.69 +  return false;
   12.70 +}
   12.71 +
   12.72 +bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
   12.73 +  ClassLoader::trace_class_path(msg, name);
   12.74 +  MetaspaceShared::set_archive_loading_failed();
   12.75 +  return false;
   12.76 +}
   12.77 +
   12.78 +bool SharedPathsMiscInfo::check() {
   12.79 +  // The whole buffer must be 0 terminated so that we can use strlen and strcmp
   12.80 +  // without fear.
   12.81 +  _end_ptr -= sizeof(jint);
   12.82 +  if (_cur_ptr >= _end_ptr) {
   12.83 +    return fail("Truncated archive file header");
   12.84 +  }
   12.85 +  if (*_end_ptr != 0) {
   12.86 +    return fail("Corrupted archive file header");
   12.87 +  }
   12.88 +
   12.89 +  while (_cur_ptr < _end_ptr) {
   12.90 +    jint type;
   12.91 +    const char* path = _cur_ptr;
   12.92 +    _cur_ptr += strlen(path) + 1;
   12.93 +    if (!read_jint(&type)) {
   12.94 +      return fail("Corrupted archive file header");
   12.95 +    }
   12.96 +    if (TraceClassPaths) {
   12.97 +      tty->print("[type=%s ", type_name(type));
   12.98 +      print_path(tty, type, path);
   12.99 +      tty->print_cr("]");
  12.100 +    }
  12.101 +    if (!check(type, path)) {
  12.102 +      if (!PrintSharedArchiveAndExit) {
  12.103 +        return false;
  12.104 +      }
  12.105 +    } else {
  12.106 +      trace_class_path("[ok");
  12.107 +    }
  12.108 +  }
  12.109 +
  12.110 +  return true;
  12.111 +}
  12.112 +
  12.113 +bool SharedPathsMiscInfo::check(jint type, const char* path) {
  12.114 +  switch (type) {
  12.115 +  case BOOT:
  12.116 +    if (strcmp(path, Arguments::get_sysclasspath()) != 0) {
  12.117 +      return fail("[BOOT classpath mismatch, actual: -Dsun.boot.class.path=", Arguments::get_sysclasspath());
  12.118 +    }
  12.119 +    break;
  12.120 +  case NON_EXIST: // fall-through
  12.121 +  case REQUIRED:
  12.122 +    {
  12.123 +      struct stat st;
  12.124 +      if (os::stat(path, &st) != 0) {
  12.125 +        // The file does not actually exist
  12.126 +        if (type == REQUIRED) {
  12.127 +          // but we require it to exist -> fail
  12.128 +          return fail("Required file doesn't exist");
  12.129 +        }
  12.130 +      } else {
  12.131 +        // The file actually exists
  12.132 +        if (type == NON_EXIST) {
  12.133 +          // But we want it to not exist -> fail
  12.134 +          return fail("File must not exist");
  12.135 +        }
  12.136 +        time_t    timestamp;
  12.137 +        long      filesize;
  12.138 +
  12.139 +        if (!read_time(&timestamp) || !read_long(&filesize)) {
  12.140 +          return fail("Corrupted archive file header");
  12.141 +        }
  12.142 +        if (timestamp != st.st_mtime) {
  12.143 +          return fail("Timestamp mismatch");
  12.144 +        }
  12.145 +        if (filesize != st.st_size) {
  12.146 +          return fail("File size mismatch");
  12.147 +        }
  12.148 +      }
  12.149 +    }
  12.150 +    break;
  12.151 +
  12.152 +  default:
  12.153 +    return fail("Corrupted archive file header");
  12.154 +  }
  12.155 +
  12.156 +  return true;
  12.157 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Wed Sep 03 09:25:44 2014 +0200
    13.3 @@ -0,0 +1,187 @@
    13.4 +/*
    13.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.
   13.11 + *
   13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.15 + * version 2 for more details (a copy is included in the LICENSE file that
   13.16 + * accompanied this code).
   13.17 + *
   13.18 + * You should have received a copy of the GNU General Public License version
   13.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.21 + *
   13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.23 + * or visit www.oracle.com if you need additional information or have any
   13.24 + * questions.
   13.25 + *
   13.26 + */
   13.27 +
   13.28 +#ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
   13.29 +#define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
   13.30 +
   13.31 +#include "runtime/os.hpp"
   13.32 +
   13.33 +// During dumping time, when processing class paths, we build up the dump-time
   13.34 +// classpath. The JAR files that exist are stored in the list ClassLoader::_first_entry.
   13.35 +// However, we need to store other "misc" information for run-time checking, such as
   13.36 +//
   13.37 +// + The values of Arguments::get_sysclasspath() used during dumping.
   13.38 +//
   13.39 +// + The meta-index file(s) used during dumping (incl modification time and size)
   13.40 +//
   13.41 +// + The class path elements specified during dumping but did not exist --
   13.42 +//   these elements must also be specified at run time, and they also must not
   13.43 +//   exist at run time.
   13.44 +//
   13.45 +// These misc items are stored in a linear buffer in SharedPathsMiscInfo.
   13.46 +// The storage format is stream oriented to minimize its size.
   13.47 +//
   13.48 +// When writing the information to the archive file, SharedPathsMiscInfo is stored in
   13.49 +// the archive file header. At run-time, this information is used only during initialization
   13.50 +// (accessed using read() instead of mmap()), and is deallocated afterwards to save space.
   13.51 +//
   13.52 +// The SharedPathsMiscInfo class is used for both creating the the information (during
   13.53 +// dumping time) and validation (at run time). Different constructors are used in the
   13.54 +// two situations. See below.
   13.55 +
   13.56 +class SharedPathsMiscInfo : public CHeapObj<mtClass> {
   13.57 +protected:
   13.58 +  char* _buf_start;
   13.59 +  char* _cur_ptr;
   13.60 +  char* _end_ptr;
   13.61 +  int   _buf_size;
   13.62 +  bool  _allocated;   // was _buf_start allocated by me?
   13.63 +  void ensure_size(size_t needed_bytes);
   13.64 +  void add_path(const char* path, int type);
   13.65 +
   13.66 +  void write(const void* ptr, size_t size);
   13.67 +  bool read(void* ptr, size_t size);
   13.68 +
   13.69 +  static void trace_class_path(const char* msg, const char* name = NULL) {
   13.70 +    ClassLoader::trace_class_path(msg, name);
   13.71 +  }
   13.72 +protected:
   13.73 +  static bool fail(const char* msg, const char* name = NULL);
   13.74 +  virtual bool check(jint type, const char* path);
   13.75 +
   13.76 +public:
   13.77 +  enum {
   13.78 +    INITIAL_BUF_SIZE = 128
   13.79 +  };
   13.80 +  // This constructor is used when creating the misc information (during dump)
   13.81 +  SharedPathsMiscInfo() {
   13.82 +    _buf_size = INITIAL_BUF_SIZE;
   13.83 +    _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
   13.84 +    _allocated = true;
   13.85 +  }
   13.86 +  // This constructor is used when validating the misc info (during run time)
   13.87 +  SharedPathsMiscInfo(char *buff, int size) {
   13.88 +    _cur_ptr = _buf_start = buff;
   13.89 +    _end_ptr = _buf_start + size;
   13.90 +    _buf_size = size;
   13.91 +    _allocated = false;
   13.92 +  }
   13.93 +  ~SharedPathsMiscInfo() {
   13.94 +    if (_allocated) {
   13.95 +      FREE_C_HEAP_ARRAY(char, _buf_start, mtClass);
   13.96 +    }
   13.97 +  }
   13.98 +  int get_used_bytes() {
   13.99 +    return _cur_ptr - _buf_start;
  13.100 +  }
  13.101 +  void* buffer() {
  13.102 +    return _buf_start;
  13.103 +  }
  13.104 +
  13.105 +  // writing --
  13.106 +
  13.107 +  // The path must not exist at run-time
  13.108 +  void add_nonexist_path(const char* path) {
  13.109 +    add_path(path, NON_EXIST);
  13.110 +  }
  13.111 +
  13.112 +  // The path must exist and have required size and modification time
  13.113 +  void add_required_file(const char* path) {
  13.114 +    add_path(path, REQUIRED);
  13.115 +
  13.116 +    struct stat st;
  13.117 +    if (os::stat(path, &st) != 0) {
  13.118 +      assert(0, "sanity");
  13.119 +      ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
  13.120 +    }
  13.121 +    write_time(st.st_mtime);
  13.122 +    write_long(st.st_size);
  13.123 +  }
  13.124 +
  13.125 +  // The path must exist, and must contain exactly <num_entries> files/dirs
  13.126 +  void add_boot_classpath(const char* path) {
  13.127 +    add_path(path, BOOT);
  13.128 +  }
  13.129 +  int write_jint(jint num) {
  13.130 +    write(&num, sizeof(num));
  13.131 +    return 0;
  13.132 +  }
  13.133 +  void write_time(time_t t) {
  13.134 +    write(&t, sizeof(t));
  13.135 +  }
  13.136 +  void write_long(long l) {
  13.137 +    write(&l, sizeof(l));
  13.138 +  }
  13.139 +
  13.140 +  bool dump_to_file(int fd) {
  13.141 +    int n = get_used_bytes();
  13.142 +    return (os::write(fd, _buf_start, n) == (size_t)n);
  13.143 +  }
  13.144 +
  13.145 +  // reading --
  13.146 +
  13.147 +  enum {
  13.148 +    BOOT      = 1,
  13.149 +    NON_EXIST = 2,
  13.150 +    REQUIRED  = 3
  13.151 +  };
  13.152 +
  13.153 +  virtual const char* type_name(int type) {
  13.154 +    switch (type) {
  13.155 +    case BOOT:      return "BOOT";
  13.156 +    case NON_EXIST: return "NON_EXIST";
  13.157 +    case REQUIRED:  return "REQUIRED";
  13.158 +    default:        ShouldNotReachHere(); return "?";
  13.159 +    }
  13.160 +  }
  13.161 +
  13.162 +  virtual void print_path(outputStream* out, int type, const char* path) {
  13.163 +    switch (type) {
  13.164 +    case BOOT:
  13.165 +      out->print("Expecting -Dsun.boot.class.path=%s", path);
  13.166 +      break;
  13.167 +    case NON_EXIST:
  13.168 +      out->print("Expecting that %s does not exist", path);
  13.169 +      break;
  13.170 +    case REQUIRED:
  13.171 +      out->print("Expecting that file %s must exist and is not altered", path);
  13.172 +      break;
  13.173 +    default:
  13.174 +      ShouldNotReachHere();
  13.175 +    }
  13.176 +  }
  13.177 +
  13.178 +  bool check();
  13.179 +  bool read_jint(jint *ptr) {
  13.180 +    return read(ptr, sizeof(jint));
  13.181 +  }
  13.182 +  bool read_long(long *ptr) {
  13.183 +    return read(ptr, sizeof(long));
  13.184 +  }
  13.185 +  bool read_time(time_t *ptr) {
  13.186 +    return read(ptr, sizeof(time_t));
  13.187 +  }
  13.188 +};
  13.189 +
  13.190 +#endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP
    14.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Wed Sep 03 09:24:07 2014 +0200
    14.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Wed Sep 03 09:25:44 2014 +0200
    14.3 @@ -30,10 +30,15 @@
    14.4  #include "classfile/placeholders.hpp"
    14.5  #include "classfile/resolutionErrors.hpp"
    14.6  #include "classfile/systemDictionary.hpp"
    14.7 +#if INCLUDE_CDS
    14.8 +#include "classfile/sharedClassUtil.hpp"
    14.9 +#include "classfile/systemDictionaryShared.hpp"
   14.10 +#endif
   14.11  #include "classfile/vmSymbols.hpp"
   14.12  #include "compiler/compileBroker.hpp"
   14.13  #include "interpreter/bytecodeStream.hpp"
   14.14  #include "interpreter/interpreter.hpp"
   14.15 +#include "memory/filemap.hpp"
   14.16  #include "memory/gcLocker.hpp"
   14.17  #include "memory/oopFactory.hpp"
   14.18  #include "oops/instanceKlass.hpp"
   14.19 @@ -109,6 +114,8 @@
   14.20                           CHECK);
   14.21  
   14.22    _java_system_loader = (oop)result.get_jobject();
   14.23 +
   14.24 +  CDS_ONLY(SystemDictionaryShared::initialize(CHECK);)
   14.25  }
   14.26  
   14.27  
   14.28 @@ -974,6 +981,7 @@
   14.29      // as the host_klass
   14.30      assert(EnableInvokeDynamic, "");
   14.31      guarantee(host_klass->class_loader() == class_loader(), "should be the same");
   14.32 +    guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping");
   14.33      loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
   14.34      loader_data->record_dependency(host_klass(), CHECK_NULL);
   14.35    } else {
   14.36 @@ -1135,7 +1143,7 @@
   14.37    return k();
   14.38  }
   14.39  
   14.40 -
   14.41 +#if INCLUDE_CDS
   14.42  void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
   14.43                                               int number_of_entries) {
   14.44    assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
   14.45 @@ -1168,15 +1176,21 @@
   14.46  instanceKlassHandle SystemDictionary::load_shared_class(
   14.47                   Symbol* class_name, Handle class_loader, TRAPS) {
   14.48    instanceKlassHandle ik (THREAD, find_shared_class(class_name));
   14.49 -  return load_shared_class(ik, class_loader, THREAD);
   14.50 +  // Make sure we only return the boot class for the NULL classloader.
   14.51 +  if (ik.not_null() &&
   14.52 +      SharedClassUtil::is_shared_boot_class(ik()) && class_loader.is_null()) {
   14.53 +    Handle protection_domain;
   14.54 +    return load_shared_class(ik, class_loader, protection_domain, THREAD);
   14.55 +  }
   14.56 +  return instanceKlassHandle();
   14.57  }
   14.58  
   14.59 -instanceKlassHandle SystemDictionary::load_shared_class(
   14.60 -                 instanceKlassHandle ik, Handle class_loader, TRAPS) {
   14.61 -  assert(class_loader.is_null(), "non-null classloader for shared class?");
   14.62 +instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
   14.63 +                                                        Handle class_loader,
   14.64 +                                                        Handle protection_domain, TRAPS) {
   14.65    if (ik.not_null()) {
   14.66      instanceKlassHandle nh = instanceKlassHandle(); // null Handle
   14.67 -    Symbol*  class_name = ik->name();
   14.68 +    Symbol* class_name = ik->name();
   14.69  
   14.70      // Found the class, now load the superclass and interfaces.  If they
   14.71      // are shared, add them to the main system dictionary and reset
   14.72 @@ -1185,7 +1199,7 @@
   14.73      if (ik->super() != NULL) {
   14.74        Symbol*  cn = ik->super()->name();
   14.75        resolve_super_or_fail(class_name, cn,
   14.76 -                            class_loader, Handle(), true, CHECK_(nh));
   14.77 +                            class_loader, protection_domain, true, CHECK_(nh));
   14.78      }
   14.79  
   14.80      Array<Klass*>* interfaces = ik->local_interfaces();
   14.81 @@ -1198,7 +1212,7 @@
   14.82        // reinitialized yet (they will be once the interface classes
   14.83        // are loaded)
   14.84        Symbol*  name  = k->name();
   14.85 -      resolve_super_or_fail(class_name, name, class_loader, Handle(), false, CHECK_(nh));
   14.86 +      resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
   14.87      }
   14.88  
   14.89      // Adjust methods to recover missing data.  They need addresses for
   14.90 @@ -1207,30 +1221,45 @@
   14.91  
   14.92      // Updating methods must be done under a lock so multiple
   14.93      // threads don't update these in parallel
   14.94 -    // Shared classes are all currently loaded by the bootstrap
   14.95 -    // classloader, so this will never cause a deadlock on
   14.96 -    // a custom class loader lock.
   14.97 +    //
   14.98 +    // Shared classes are all currently loaded by either the bootstrap or
   14.99 +    // internal parallel class loaders, so this will never cause a deadlock
  14.100 +    // on a custom class loader lock.
  14.101  
  14.102 +    ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
  14.103      {
  14.104        Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
  14.105        check_loader_lock_contention(lockObject, THREAD);
  14.106        ObjectLocker ol(lockObject, THREAD, true);
  14.107 -      ik->restore_unshareable_info(CHECK_(nh));
  14.108 +      ik->restore_unshareable_info(loader_data, protection_domain, CHECK_(nh));
  14.109      }
  14.110  
  14.111      if (TraceClassLoading) {
  14.112        ResourceMark rm;
  14.113        tty->print("[Loaded %s", ik->external_name());
  14.114        tty->print(" from shared objects file");
  14.115 +      if (class_loader.not_null()) {
  14.116 +        tty->print(" by %s", loader_data->loader_name());
  14.117 +      }
  14.118        tty->print_cr("]");
  14.119      }
  14.120 +
  14.121 +    if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
  14.122 +      // Only dump the classes that can be stored into CDS archive
  14.123 +      if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
  14.124 +        ResourceMark rm(THREAD);
  14.125 +        classlist_file->print_cr("%s", ik->name()->as_C_string());
  14.126 +        classlist_file->flush();
  14.127 +      }
  14.128 +    }
  14.129 +
  14.130      // notify a class loaded from shared object
  14.131      ClassLoadingService::notify_class_loaded(InstanceKlass::cast(ik()),
  14.132                                               true /* shared class */);
  14.133    }
  14.134    return ik;
  14.135  }
  14.136 -
  14.137 +#endif // INCLUDE_CDS
  14.138  
  14.139  instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
  14.140    instanceKlassHandle nh = instanceKlassHandle(); // null Handle
  14.141 @@ -1240,8 +1269,10 @@
  14.142      // shared spaces.
  14.143      instanceKlassHandle k;
  14.144      {
  14.145 +#if INCLUDE_CDS
  14.146        PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
  14.147        k = load_shared_class(class_name, class_loader, THREAD);
  14.148 +#endif
  14.149      }
  14.150  
  14.151      if (k.is_null()) {
  14.152 @@ -1600,7 +1631,6 @@
  14.153    Universe::flush_dependents_on(k);
  14.154  }
  14.155  
  14.156 -
  14.157  // ----------------------------------------------------------------------------
  14.158  // GC support
  14.159  
  14.160 @@ -1682,6 +1712,7 @@
  14.161  void SystemDictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
  14.162    strong->do_oop(&_java_system_loader);
  14.163    strong->do_oop(&_system_loader_lock_obj);
  14.164 +  CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
  14.165  
  14.166    // Adjust dictionary
  14.167    dictionary()->roots_oops_do(strong, weak);
  14.168 @@ -1693,6 +1724,7 @@
  14.169  void SystemDictionary::oops_do(OopClosure* f) {
  14.170    f->do_oop(&_java_system_loader);
  14.171    f->do_oop(&_system_loader_lock_obj);
  14.172 +  CDS_ONLY(SystemDictionaryShared::oops_do(f);)
  14.173  
  14.174    // Adjust dictionary
  14.175    dictionary()->oops_do(f);
  14.176 @@ -1754,6 +1786,10 @@
  14.177    invoke_method_table()->methods_do(f);
  14.178  }
  14.179  
  14.180 +void SystemDictionary::remove_classes_in_error_state() {
  14.181 +  dictionary()->remove_classes_in_error_state();
  14.182 +}
  14.183 +
  14.184  // ----------------------------------------------------------------------------
  14.185  // Lazily load klasses
  14.186  
  14.187 @@ -2566,10 +2602,12 @@
  14.188  
  14.189  
  14.190  // ----------------------------------------------------------------------------
  14.191 -#ifndef PRODUCT
  14.192 +void SystemDictionary::print_shared(bool details) {
  14.193 +  shared_dictionary()->print(details);
  14.194 +}
  14.195  
  14.196 -void SystemDictionary::print() {
  14.197 -  dictionary()->print();
  14.198 +void SystemDictionary::print(bool details) {
  14.199 +  dictionary()->print(details);
  14.200  
  14.201    // Placeholders
  14.202    GCMutexLocker mu(SystemDictionary_lock);
  14.203 @@ -2579,7 +2617,6 @@
  14.204    constraints()->print();
  14.205  }
  14.206  
  14.207 -#endif
  14.208  
  14.209  void SystemDictionary::verify() {
  14.210    guarantee(dictionary() != NULL, "Verify of system dictionary failed");
    15.1 --- a/src/share/vm/classfile/systemDictionary.hpp	Wed Sep 03 09:24:07 2014 +0200
    15.2 +++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Sep 03 09:25:44 2014 +0200
    15.3 @@ -111,6 +111,7 @@
    15.4    do_klass(SecurityManager_klass,                       java_lang_SecurityManager,                 Pre                 ) \
    15.5    do_klass(ProtectionDomain_klass,                      java_security_ProtectionDomain,            Pre                 ) \
    15.6    do_klass(AccessControlContext_klass,                  java_security_AccessControlContext,        Pre                 ) \
    15.7 +  do_klass(SecureClassLoader_klass,                     java_security_SecureClassLoader,           Pre                 ) \
    15.8    do_klass(ClassNotFoundException_klass,                java_lang_ClassNotFoundException,          Pre                 ) \
    15.9    do_klass(NoClassDefFoundError_klass,                  java_lang_NoClassDefFoundError,            Pre                 ) \
   15.10    do_klass(LinkageError_klass,                          java_lang_LinkageError,                    Pre                 ) \
   15.11 @@ -167,6 +168,15 @@
   15.12    do_klass(StringBuilder_klass,                         java_lang_StringBuilder,                   Pre                 ) \
   15.13    do_klass(misc_Unsafe_klass,                           sun_misc_Unsafe,                           Pre                 ) \
   15.14                                                                                                                           \
   15.15 +  /* support for CDS */                                                                                                  \
   15.16 +  do_klass(ByteArrayInputStream_klass,                  java_io_ByteArrayInputStream,              Pre                 ) \
   15.17 +  do_klass(File_klass,                                  java_io_File,                              Pre                 ) \
   15.18 +  do_klass(URLClassLoader_klass,                        java_net_URLClassLoader,                   Pre                 ) \
   15.19 +  do_klass(URL_klass,                                   java_net_URL,                              Pre                 ) \
   15.20 +  do_klass(Jar_Manifest_klass,                          java_util_jar_Manifest,                    Pre                 ) \
   15.21 +  do_klass(sun_misc_Launcher_klass,                     sun_misc_Launcher,                         Pre                 ) \
   15.22 +  do_klass(CodeSource_klass,                            java_security_CodeSource,                  Pre                 ) \
   15.23 +                                                                                                                         \
   15.24    /* It's NULL in non-1.4 JDKs. */                                                                                       \
   15.25    do_klass(StackTraceElement_klass,                     java_lang_StackTraceElement,               Opt                 ) \
   15.26    /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                                   \
   15.27 @@ -226,7 +236,7 @@
   15.28    static Klass* resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS);
   15.29    // Convenient call for null loader and protection domain.
   15.30    static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS);
   15.31 -private:
   15.32 +protected:
   15.33    // handle error translation for resolve_or_null results
   15.34    static Klass* handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS);
   15.35  
   15.36 @@ -331,6 +341,9 @@
   15.37    // loaders.  Returns "true" iff something was unloaded.
   15.38    static bool do_unloading(BoolObjectClosure* is_alive);
   15.39  
   15.40 +  // Used by DumpSharedSpaces only to remove classes that failed verification
   15.41 +  static void remove_classes_in_error_state();
   15.42 +
   15.43    static int calculate_systemdictionary_size(int loadedclasses);
   15.44  
   15.45    // Applies "f->do_oop" to all root oops in the system dictionary.
   15.46 @@ -340,7 +353,7 @@
   15.47    // System loader lock
   15.48    static oop system_loader_lock()           { return _system_loader_lock_obj; }
   15.49  
   15.50 -private:
   15.51 +protected:
   15.52    // Extended Redefine classes support (tbi)
   15.53    static void preloaded_classes_do(KlassClosure* f);
   15.54    static void lazily_loaded_classes_do(KlassClosure* f);
   15.55 @@ -353,7 +366,8 @@
   15.56    static void set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
   15.57                                      int number_of_entries);
   15.58    // Printing
   15.59 -  static void print()                   PRODUCT_RETURN;
   15.60 +  static void print(bool details = true);
   15.61 +  static void print_shared(bool details = true);
   15.62    static void print_class_statistics()  PRODUCT_RETURN;
   15.63    static void print_method_statistics() PRODUCT_RETURN;
   15.64  
   15.65 @@ -439,7 +453,7 @@
   15.66  
   15.67    static void load_abstract_ownable_synchronizer_klass(TRAPS);
   15.68  
   15.69 -private:
   15.70 +protected:
   15.71    // Tells whether ClassLoader.loadClassInternal is present
   15.72    static bool has_loadClassInternal()       { return _has_loadClassInternal; }
   15.73  
   15.74 @@ -467,7 +481,7 @@
   15.75  
   15.76    // Register a new class loader
   15.77    static ClassLoaderData* register_loader(Handle class_loader, TRAPS);
   15.78 -private:
   15.79 +protected:
   15.80    // Mirrors for primitive classes (created eagerly)
   15.81    static oop check_mirror(oop m) {
   15.82      assert(m != NULL, "mirror not initialized");
   15.83 @@ -536,7 +550,7 @@
   15.84    static void delete_resolution_error(ConstantPool* pool);
   15.85    static Symbol* find_resolution_error(constantPoolHandle pool, int which);
   15.86  
   15.87 - private:
   15.88 + protected:
   15.89  
   15.90    enum Constants {
   15.91      _loader_constraint_size = 107,                     // number of entries in constraint table
   15.92 @@ -587,7 +601,7 @@
   15.93    friend class CounterDecay;
   15.94    static Klass* try_get_next_class();
   15.95  
   15.96 -private:
   15.97 +protected:
   15.98    static void validate_protection_domain(instanceKlassHandle klass,
   15.99                                           Handle class_loader,
  15.100                                           Handle protection_domain, TRAPS);
  15.101 @@ -614,10 +628,10 @@
  15.102    static instanceKlassHandle find_or_define_instance_class(Symbol* class_name,
  15.103                                                  Handle class_loader,
  15.104                                                  instanceKlassHandle k, TRAPS);
  15.105 -  static instanceKlassHandle load_shared_class(Symbol* class_name,
  15.106 -                                               Handle class_loader, TRAPS);
  15.107    static instanceKlassHandle load_shared_class(instanceKlassHandle ik,
  15.108 -                                               Handle class_loader, TRAPS);
  15.109 +                                               Handle class_loader,
  15.110 +                                               Handle protection_domain,
  15.111 +                                               TRAPS);
  15.112    static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
  15.113    static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
  15.114    static void check_loader_lock_contention(Handle loader_lock, TRAPS);
  15.115 @@ -625,9 +639,12 @@
  15.116    static bool is_parallelDefine(Handle class_loader);
  15.117  
  15.118  public:
  15.119 +  static instanceKlassHandle load_shared_class(Symbol* class_name,
  15.120 +                                               Handle class_loader,
  15.121 +                                               TRAPS);
  15.122    static bool is_ext_class_loader(Handle class_loader);
  15.123  
  15.124 -private:
  15.125 +protected:
  15.126    static Klass* find_shared_class(Symbol* class_name);
  15.127  
  15.128    // Setup link to hierarchy
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/share/vm/classfile/systemDictionaryShared.hpp	Wed Sep 03 09:25:44 2014 +0200
    16.3 @@ -0,0 +1,47 @@
    16.4 +/*
    16.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + *
   16.26 + */
   16.27 +
   16.28 +
   16.29 +#ifndef SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
   16.30 +#define SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
   16.31 +
   16.32 +#include "classfile/systemDictionary.hpp"
   16.33 +
   16.34 +class SystemDictionaryShared: public SystemDictionary {
   16.35 +public:
   16.36 +  static void initialize(TRAPS) {}
   16.37 +  static instanceKlassHandle find_or_load_shared_class(Symbol* class_name,
   16.38 +                                                       Handle class_loader,
   16.39 +                                                       TRAPS) {
   16.40 +    return instanceKlassHandle();
   16.41 +  }
   16.42 +  static void roots_oops_do(OopClosure* blk) {}
   16.43 +  static void oops_do(OopClosure* f) {}
   16.44 +  static bool is_sharing_possible(ClassLoaderData* loader_data) {
   16.45 +    oop class_loader = loader_data->class_loader();
   16.46 +    return (class_loader == NULL);
   16.47 +  }
   16.48 +};
   16.49 +
   16.50 +#endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
    17.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Wed Sep 03 09:24:07 2014 +0200
    17.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Sep 03 09:25:44 2014 +0200
    17.3 @@ -91,11 +91,17 @@
    17.4    template(java_lang_CharSequence,                    "java/lang/CharSequence")                   \
    17.5    template(java_lang_SecurityManager,                 "java/lang/SecurityManager")                \
    17.6    template(java_security_AccessControlContext,        "java/security/AccessControlContext")       \
    17.7 +  template(java_security_CodeSource,                  "java/security/CodeSource")                 \
    17.8    template(java_security_ProtectionDomain,            "java/security/ProtectionDomain")           \
    17.9 +  template(java_security_SecureClassLoader,           "java/security/SecureClassLoader")          \
   17.10 +  template(java_net_URLClassLoader,                   "java/net/URLClassLoader")                  \
   17.11 +  template(java_net_URL,                              "java/net/URL")                             \
   17.12 +  template(java_util_jar_Manifest,                    "java/util/jar/Manifest")                   \
   17.13    template(impliesCreateAccessControlContext_name,    "impliesCreateAccessControlContext")        \
   17.14    template(java_io_OutputStream,                      "java/io/OutputStream")                     \
   17.15    template(java_io_Reader,                            "java/io/Reader")                           \
   17.16    template(java_io_BufferedReader,                    "java/io/BufferedReader")                   \
   17.17 +  template(java_io_File,                              "java/io/File")                             \
   17.18    template(java_io_FileInputStream,                   "java/io/FileInputStream")                  \
   17.19    template(java_io_ByteArrayInputStream,              "java/io/ByteArrayInputStream")             \
   17.20    template(java_io_Serializable,                      "java/io/Serializable")                     \
   17.21 @@ -106,6 +112,7 @@
   17.22    template(java_util_Hashtable,                       "java/util/Hashtable")                      \
   17.23    template(java_lang_Compiler,                        "java/lang/Compiler")                       \
   17.24    template(sun_misc_Signal,                           "sun/misc/Signal")                          \
   17.25 +  template(sun_misc_Launcher,                         "sun/misc/Launcher")                        \
   17.26    template(java_lang_AssertionStatusDirectives,       "java/lang/AssertionStatusDirectives")      \
   17.27    template(getBootClassPathEntryForClass_name,        "getBootClassPathEntryForClass")            \
   17.28    template(sun_misc_PostVMInitHook,                   "sun/misc/PostVMInitHook")                  \
   17.29 @@ -397,6 +404,14 @@
   17.30    template(signers_name,                              "signers_name")                             \
   17.31    template(loader_data_name,                          "loader_data")                              \
   17.32    template(dependencies_name,                         "dependencies")                             \
   17.33 +  template(input_stream_void_signature,               "(Ljava/io/InputStream;)V")                 \
   17.34 +  template(getFileURL_name,                           "getFileURL")                               \
   17.35 +  template(getFileURL_signature,                      "(Ljava/io/File;)Ljava/net/URL;")           \
   17.36 +  template(definePackageInternal_name,                "definePackageInternal")                    \
   17.37 +  template(definePackageInternal_signature,           "(Ljava/lang/String;Ljava/util/jar/Manifest;Ljava/net/URL;)V") \
   17.38 +  template(getProtectionDomain_name,                  "getProtectionDomain")                      \
   17.39 +  template(getProtectionDomain_signature,             "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \
   17.40 +  template(url_code_signer_array_void_signature,      "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \
   17.41                                                                                                    \
   17.42    /* non-intrinsic name/signature pairs: */                                                       \
   17.43    template(register_method_name,                      "register")                                 \
    18.1 --- a/src/share/vm/memory/allocation.hpp	Wed Sep 03 09:24:07 2014 +0200
    18.2 +++ b/src/share/vm/memory/allocation.hpp	Wed Sep 03 09:25:44 2014 +0200
    18.3 @@ -265,7 +265,8 @@
    18.4    f(ConstantPool) \
    18.5    f(ConstantPoolCache) \
    18.6    f(Annotation) \
    18.7 -  f(MethodCounters)
    18.8 +  f(MethodCounters) \
    18.9 +  f(Deallocated)
   18.10  
   18.11  #define METASPACE_OBJ_TYPE_DECLARE(name) name ## Type,
   18.12  #define METASPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
    19.1 --- a/src/share/vm/memory/filemap.cpp	Wed Sep 03 09:24:07 2014 +0200
    19.2 +++ b/src/share/vm/memory/filemap.cpp	Wed Sep 03 09:25:44 2014 +0200
    19.3 @@ -24,9 +24,14 @@
    19.4  
    19.5  #include "precompiled.hpp"
    19.6  #include "classfile/classLoader.hpp"
    19.7 +#include "classfile/sharedClassUtil.hpp"
    19.8  #include "classfile/symbolTable.hpp"
    19.9 +#include "classfile/systemDictionaryShared.hpp"
   19.10  #include "classfile/altHashing.hpp"
   19.11  #include "memory/filemap.hpp"
   19.12 +#include "memory/metadataFactory.hpp"
   19.13 +#include "memory/oopFactory.hpp"
   19.14 +#include "oops/objArrayOop.hpp"
   19.15  #include "runtime/arguments.hpp"
   19.16  #include "runtime/java.hpp"
   19.17  #include "runtime/os.hpp"
   19.18 @@ -41,7 +46,6 @@
   19.19  #endif
   19.20  
   19.21  PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
   19.22 -
   19.23  extern address JVM_FunctionAtStart();
   19.24  extern address JVM_FunctionAtEnd();
   19.25  
   19.26 @@ -77,12 +81,27 @@
   19.27  void FileMapInfo::fail_continue(const char *msg, ...) {
   19.28    va_list ap;
   19.29    va_start(ap, msg);
   19.30 -  if (RequireSharedSpaces) {
   19.31 -    fail(msg, ap);
   19.32 +  MetaspaceShared::set_archive_loading_failed();
   19.33 +  if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) {
   19.34 +    // If we are doing PrintSharedArchiveAndExit and some of the classpath entries
   19.35 +    // do not validate, we can still continue "limping" to validate the remaining
   19.36 +    // entries. No need to quit.
   19.37 +    tty->print("[");
   19.38 +    tty->vprint(msg, ap);
   19.39 +    tty->print_cr("]");
   19.40 +  } else {
   19.41 +    if (RequireSharedSpaces) {
   19.42 +      fail(msg, ap);
   19.43 +    } else {
   19.44 +      if (PrintSharedSpaces) {
   19.45 +        tty->print_cr("UseSharedSpaces: %s", msg);
   19.46 +      }
   19.47 +    }
   19.48    }
   19.49    va_end(ap);
   19.50    UseSharedSpaces = false;
   19.51 -  close();
   19.52 +  assert(current_info() != NULL, "singleton must be registered");
   19.53 +  current_info()->close();
   19.54  }
   19.55  
   19.56  // Fill in the fileMapInfo structure with data about this VM instance.
   19.57 @@ -117,67 +136,201 @@
   19.58    }
   19.59  }
   19.60  
   19.61 +FileMapInfo::FileMapInfo() {
   19.62 +  assert(_current_info == NULL, "must be singleton"); // not thread safe
   19.63 +  _current_info = this;
   19.64 +  memset(this, 0, sizeof(FileMapInfo));
   19.65 +  _file_offset = 0;
   19.66 +  _file_open = false;
   19.67 +  _header = SharedClassUtil::allocate_file_map_header();
   19.68 +  _header->_version = _invalid_version;
   19.69 +}
   19.70 +
   19.71 +FileMapInfo::~FileMapInfo() {
   19.72 +  assert(_current_info == this, "must be singleton"); // not thread safe
   19.73 +  _current_info = NULL;
   19.74 +}
   19.75 +
   19.76  void FileMapInfo::populate_header(size_t alignment) {
   19.77 -  _header._magic = 0xf00baba2;
   19.78 -  _header._version = _current_version;
   19.79 -  _header._alignment = alignment;
   19.80 -  _header._obj_alignment = ObjectAlignmentInBytes;
   19.81 +  _header->populate(this, alignment);
   19.82 +}
   19.83 +
   19.84 +size_t FileMapInfo::FileMapHeader::data_size() {
   19.85 +  return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
   19.86 +}
   19.87 +
   19.88 +void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
   19.89 +  _magic = 0xf00baba2;
   19.90 +  _version = _current_version;
   19.91 +  _alignment = alignment;
   19.92 +  _obj_alignment = ObjectAlignmentInBytes;
   19.93 +  _classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
   19.94 +  _classpath_entry_table = mapinfo->_classpath_entry_table;
   19.95 +  _classpath_entry_size = mapinfo->_classpath_entry_size;
   19.96  
   19.97    // The following fields are for sanity checks for whether this archive
   19.98    // will function correctly with this JVM and the bootclasspath it's
   19.99    // invoked with.
  19.100  
  19.101    // JVM version string ... changes on each build.
  19.102 -  get_header_version(_header._jvm_ident);
  19.103 +  get_header_version(_jvm_ident);
  19.104 +}
  19.105  
  19.106 -  // Build checks on classpath and jar files
  19.107 -  _header._num_jars = 0;
  19.108 -  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
  19.109 -  for ( ; cpe != NULL; cpe = cpe->next()) {
  19.110 +void FileMapInfo::allocate_classpath_entry_table() {
  19.111 +  int bytes = 0;
  19.112 +  int count = 0;
  19.113 +  char* strptr = NULL;
  19.114 +  char* strptr_max = NULL;
  19.115 +  Thread* THREAD = Thread::current();
  19.116  
  19.117 -    if (cpe->is_jar_file()) {
  19.118 -      if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
  19.119 -        fail_stop("Too many jar files to share.", NULL);
  19.120 +  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
  19.121 +  size_t entry_size = SharedClassUtil::shared_class_path_entry_size();
  19.122 +
  19.123 +  for (int pass=0; pass<2; pass++) {
  19.124 +    ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
  19.125 +
  19.126 +    for (int cur_entry = 0 ; cpe != NULL; cpe = cpe->next(), cur_entry++) {
  19.127 +      const char *name = cpe->name();
  19.128 +      int name_bytes = (int)(strlen(name) + 1);
  19.129 +
  19.130 +      if (pass == 0) {
  19.131 +        count ++;
  19.132 +        bytes += (int)entry_size;
  19.133 +        bytes += name_bytes;
  19.134 +        if (TraceClassPaths || (TraceClassLoading && Verbose)) {
  19.135 +          tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name);
  19.136 +        }
  19.137 +      } else {
  19.138 +        SharedClassPathEntry* ent = shared_classpath(cur_entry);
  19.139 +        if (cpe->is_jar_file()) {
  19.140 +          struct stat st;
  19.141 +          if (os::stat(name, &st) != 0) {
  19.142 +            // The file/dir must exist, or it would not have been added
  19.143 +            // into ClassLoader::classpath_entry().
  19.144 +            //
  19.145 +            // If we can't access a jar file in the boot path, then we can't
  19.146 +            // make assumptions about where classes get loaded from.
  19.147 +            FileMapInfo::fail_stop("Unable to open jar file %s.", name);
  19.148 +          }
  19.149 +
  19.150 +          EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
  19.151 +          SharedClassUtil::update_shared_classpath(cpe, ent, st.st_mtime, st.st_size, THREAD);
  19.152 +        } else {
  19.153 +          ent->_filesize  = -1;
  19.154 +          if (!os::dir_is_empty(name)) {
  19.155 +            ClassLoader::exit_with_path_failure("Cannot have non-empty directory in archived classpaths", name);
  19.156 +          }
  19.157 +        }
  19.158 +        ent->_name = strptr;
  19.159 +        if (strptr + name_bytes <= strptr_max) {
  19.160 +          strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0.
  19.161 +          strptr += name_bytes;
  19.162 +        } else {
  19.163 +          assert(0, "miscalculated buffer size");
  19.164 +        }
  19.165        }
  19.166 +    }
  19.167  
  19.168 -      // Jar file - record timestamp and file size.
  19.169 -      struct stat st;
  19.170 -      const char *path = cpe->name();
  19.171 -      if (os::stat(path, &st) != 0) {
  19.172 -        // If we can't access a jar file in the boot path, then we can't
  19.173 -        // make assumptions about where classes get loaded from.
  19.174 -        fail_stop("Unable to open jar file %s.", path);
  19.175 -      }
  19.176 -      _header._jar[_header._num_jars]._timestamp = st.st_mtime;
  19.177 -      _header._jar[_header._num_jars]._filesize = st.st_size;
  19.178 -      _header._num_jars++;
  19.179 -    } else {
  19.180 +    if (pass == 0) {
  19.181 +      EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
  19.182 +      Array<u8>* arr = MetadataFactory::new_array<u8>(loader_data, (bytes + 7)/8, THREAD);
  19.183 +      strptr = (char*)(arr->data());
  19.184 +      strptr_max = strptr + bytes;
  19.185 +      SharedClassPathEntry* table = (SharedClassPathEntry*)strptr;
  19.186 +      strptr += entry_size * count;
  19.187  
  19.188 -      // If directories appear in boot classpath, they must be empty to
  19.189 -      // avoid having to verify each individual class file.
  19.190 -      const char* name = ((ClassPathDirEntry*)cpe)->name();
  19.191 -      if (!os::dir_is_empty(name)) {
  19.192 -        fail_stop("Boot classpath directory %s is not empty.", name);
  19.193 -      }
  19.194 +      _classpath_entry_table_size = count;
  19.195 +      _classpath_entry_table = table;
  19.196 +      _classpath_entry_size = entry_size;
  19.197      }
  19.198    }
  19.199  }
  19.200  
  19.201 +bool FileMapInfo::validate_classpath_entry_table() {
  19.202 +  _validating_classpath_entry_table = true;
  19.203 +
  19.204 +  int count = _header->_classpath_entry_table_size;
  19.205 +
  19.206 +  _classpath_entry_table = _header->_classpath_entry_table;
  19.207 +  _classpath_entry_size = _header->_classpath_entry_size;
  19.208 +
  19.209 +  for (int i=0; i<count; i++) {
  19.210 +    SharedClassPathEntry* ent = shared_classpath(i);
  19.211 +    struct stat st;
  19.212 +    const char* name = ent->_name;
  19.213 +    bool ok = true;
  19.214 +    if (TraceClassPaths || (TraceClassLoading && Verbose)) {
  19.215 +      tty->print_cr("[Checking shared classpath entry: %s]", name);
  19.216 +    }
  19.217 +    if (os::stat(name, &st) != 0) {
  19.218 +      fail_continue("Required classpath entry does not exist: %s", name);
  19.219 +      ok = false;
  19.220 +    } else if (ent->is_dir()) {
  19.221 +      if (!os::dir_is_empty(name)) {
  19.222 +        fail_continue("directory is not empty: %s", name);
  19.223 +        ok = false;
  19.224 +      }
  19.225 +    } else {
  19.226 +      if (ent->_timestamp != st.st_mtime ||
  19.227 +          ent->_filesize != st.st_size) {
  19.228 +        ok = false;
  19.229 +        if (PrintSharedArchiveAndExit) {
  19.230 +          fail_continue(ent->_timestamp != st.st_mtime ?
  19.231 +                        "Timestamp mismatch" :
  19.232 +                        "File size mismatch");
  19.233 +        } else {
  19.234 +          fail_continue("A jar file is not the one used while building"
  19.235 +                        " the shared archive file: %s", name);
  19.236 +        }
  19.237 +      }
  19.238 +    }
  19.239 +    if (ok) {
  19.240 +      if (TraceClassPaths || (TraceClassLoading && Verbose)) {
  19.241 +        tty->print_cr("[ok]");
  19.242 +      }
  19.243 +    } else if (!PrintSharedArchiveAndExit) {
  19.244 +      _validating_classpath_entry_table = false;
  19.245 +      return false;
  19.246 +    }
  19.247 +  }
  19.248 +
  19.249 +  _classpath_entry_table_size = _header->_classpath_entry_table_size;
  19.250 +  _validating_classpath_entry_table = false;
  19.251 +  return true;
  19.252 +}
  19.253 +
  19.254  
  19.255  // Read the FileMapInfo information from the file.
  19.256  
  19.257  bool FileMapInfo::init_from_file(int fd) {
  19.258 -
  19.259 -  size_t n = read(fd, &_header, sizeof(struct FileMapHeader));
  19.260 -  if (n != sizeof(struct FileMapHeader)) {
  19.261 +  size_t sz = _header->data_size();
  19.262 +  char* addr = _header->data();
  19.263 +  size_t n = os::read(fd, addr, (unsigned int)sz);
  19.264 +  if (n != sz) {
  19.265      fail_continue("Unable to read the file header.");
  19.266      return false;
  19.267    }
  19.268 -  if (_header._version != current_version()) {
  19.269 +  if (_header->_version != current_version()) {
  19.270      fail_continue("The shared archive file has the wrong version.");
  19.271      return false;
  19.272    }
  19.273    _file_offset = (long)n;
  19.274 +
  19.275 +  size_t info_size = _header->_paths_misc_info_size;
  19.276 +  _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass);
  19.277 +  if (_paths_misc_info == NULL) {
  19.278 +    fail_continue("Unable to read the file header.");
  19.279 +    return false;
  19.280 +  }
  19.281 +  n = os::read(fd, _paths_misc_info, (unsigned int)info_size);
  19.282 +  if (n != info_size) {
  19.283 +    fail_continue("Unable to read the shared path info header.");
  19.284 +    FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
  19.285 +    _paths_misc_info = NULL;
  19.286 +    return false;
  19.287 +  }
  19.288 +
  19.289 +  _file_offset += (long)n;
  19.290    return true;
  19.291  }
  19.292  
  19.293 @@ -232,7 +385,16 @@
  19.294  // Write the header to the file, seek to the next allocation boundary.
  19.295  
  19.296  void FileMapInfo::write_header() {
  19.297 -  write_bytes_aligned(&_header, sizeof(FileMapHeader));
  19.298 +  int info_size = ClassLoader::get_shared_paths_misc_info_size();
  19.299 +
  19.300 +  _header->_paths_misc_info_size = info_size;
  19.301 +
  19.302 +  align_file_position();
  19.303 +  size_t sz = _header->data_size();
  19.304 +  char* addr = _header->data();
  19.305 +  write_bytes(addr, (int)sz); // skip the C++ vtable
  19.306 +  write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size);
  19.307 +  align_file_position();
  19.308  }
  19.309  
  19.310  
  19.311 @@ -242,7 +404,7 @@
  19.312    align_file_position();
  19.313    size_t used = space->used_bytes_slow(Metaspace::NonClassType);
  19.314    size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType);
  19.315 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
  19.316 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
  19.317    write_region(i, (char*)space->bottom(), used, capacity, read_only, false);
  19.318  }
  19.319  
  19.320 @@ -252,7 +414,7 @@
  19.321  void FileMapInfo::write_region(int region, char* base, size_t size,
  19.322                                 size_t capacity, bool read_only,
  19.323                                 bool allow_exec) {
  19.324 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region];
  19.325 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[region];
  19.326  
  19.327    if (_file_open) {
  19.328      guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
  19.329 @@ -334,7 +496,7 @@
  19.330  // JVM/TI RedefineClasses() support:
  19.331  // Remap the shared readonly space to shared readwrite, private.
  19.332  bool FileMapInfo::remap_shared_readonly_as_readwrite() {
  19.333 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
  19.334 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0];
  19.335    if (!si->_read_only) {
  19.336      // the space is already readwrite so we are done
  19.337      return true;
  19.338 @@ -362,7 +524,7 @@
  19.339  
  19.340  // Map the whole region at once, assumed to be allocated contiguously.
  19.341  ReservedSpace FileMapInfo::reserve_shared_memory() {
  19.342 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
  19.343 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0];
  19.344    char* requested_addr = si->_base;
  19.345  
  19.346    size_t size = FileMapInfo::shared_spaces_size();
  19.347 @@ -384,7 +546,7 @@
  19.348  static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"};
  19.349  
  19.350  char* FileMapInfo::map_region(int i) {
  19.351 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
  19.352 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
  19.353    size_t used = si->_used;
  19.354    size_t alignment = os::vm_allocation_granularity();
  19.355    size_t size = align_size_up(used, alignment);
  19.356 @@ -410,7 +572,7 @@
  19.357  // Unmap a memory region in the address space.
  19.358  
  19.359  void FileMapInfo::unmap_region(int i) {
  19.360 -  struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
  19.361 +  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
  19.362    size_t used = si->_used;
  19.363    size_t size = align_size_up(used, os::vm_allocation_granularity());
  19.364    if (!os::unmap_memory(si->_base, size)) {
  19.365 @@ -427,12 +589,21 @@
  19.366  
  19.367  
  19.368  FileMapInfo* FileMapInfo::_current_info = NULL;
  19.369 -
  19.370 +SharedClassPathEntry* FileMapInfo::_classpath_entry_table = NULL;
  19.371 +int FileMapInfo::_classpath_entry_table_size = 0;
  19.372 +size_t FileMapInfo::_classpath_entry_size = 0x1234baad;
  19.373 +bool FileMapInfo::_validating_classpath_entry_table = false;
  19.374  
  19.375  // Open the shared archive file, read and validate the header
  19.376  // information (version, boot classpath, etc.).  If initialization
  19.377  // fails, shared spaces are disabled and the file is closed. [See
  19.378  // fail_continue.]
  19.379 +//
  19.380 +// Validation of the archive is done in two steps:
  19.381 +//
  19.382 +// [1] validate_header() - done here. This checks the header, including _paths_misc_info.
  19.383 +// [2] validate_classpath_entry_table - this is done later, because the table is in the RW
  19.384 +//     region of the archive, which is not mapped yet.
  19.385  bool FileMapInfo::initialize() {
  19.386    assert(UseSharedSpaces, "UseSharedSpaces expected.");
  19.387  
  19.388 @@ -446,92 +617,66 @@
  19.389    }
  19.390  
  19.391    init_from_file(_fd);
  19.392 -  if (!validate()) {
  19.393 +  if (!validate_header()) {
  19.394      return false;
  19.395    }
  19.396  
  19.397 -  SharedReadOnlySize =  _header._space[0]._capacity;
  19.398 -  SharedReadWriteSize = _header._space[1]._capacity;
  19.399 -  SharedMiscDataSize =  _header._space[2]._capacity;
  19.400 -  SharedMiscCodeSize =  _header._space[3]._capacity;
  19.401 +  SharedReadOnlySize =  _header->_space[0]._capacity;
  19.402 +  SharedReadWriteSize = _header->_space[1]._capacity;
  19.403 +  SharedMiscDataSize =  _header->_space[2]._capacity;
  19.404 +  SharedMiscCodeSize =  _header->_space[3]._capacity;
  19.405    return true;
  19.406  }
  19.407  
  19.408 -
  19.409 -bool FileMapInfo::validate() {
  19.410 -  if (_header._version != current_version()) {
  19.411 -    fail_continue("The shared archive file is the wrong version.");
  19.412 +bool FileMapInfo::FileMapHeader::validate() {
  19.413 +  if (_version != current_version()) {
  19.414 +    FileMapInfo::fail_continue("The shared archive file is the wrong version.");
  19.415      return false;
  19.416    }
  19.417 -  if (_header._magic != (int)0xf00baba2) {
  19.418 -    fail_continue("The shared archive file has a bad magic number.");
  19.419 +  if (_magic != (int)0xf00baba2) {
  19.420 +    FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
  19.421      return false;
  19.422    }
  19.423    char header_version[JVM_IDENT_MAX];
  19.424    get_header_version(header_version);
  19.425 -  if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
  19.426 -    fail_continue("The shared archive file was created by a different"
  19.427 -                  " version or build of HotSpot.");
  19.428 +  if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
  19.429 +    if (TraceClassPaths) {
  19.430 +      tty->print_cr("Expected: %s", header_version);
  19.431 +      tty->print_cr("Actual:   %s", _jvm_ident);
  19.432 +    }
  19.433 +    FileMapInfo::fail_continue("The shared archive file was created by a different"
  19.434 +                  " version or build of HotSpot");
  19.435      return false;
  19.436    }
  19.437 -  if (_header._obj_alignment != ObjectAlignmentInBytes) {
  19.438 -    fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
  19.439 +  if (_obj_alignment != ObjectAlignmentInBytes) {
  19.440 +    FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d"
  19.441                    " does not equal the current ObjectAlignmentInBytes of %d.",
  19.442 -                  _header._obj_alignment, ObjectAlignmentInBytes);
  19.443 -    return false;
  19.444 -  }
  19.445 -
  19.446 -  // Cannot verify interpreter yet, as it can only be created after the GC
  19.447 -  // heap has been initialized.
  19.448 -
  19.449 -  if (_header._num_jars >= JVM_SHARED_JARS_MAX) {
  19.450 -    fail_continue("Too many jar files to share.");
  19.451 -    return false;
  19.452 -  }
  19.453 -
  19.454 -  // Build checks on classpath and jar files
  19.455 -  int num_jars_now = 0;
  19.456 -  ClassPathEntry *cpe = ClassLoader::classpath_entry(0);
  19.457 -  for ( ; cpe != NULL; cpe = cpe->next()) {
  19.458 -
  19.459 -    if (cpe->is_jar_file()) {
  19.460 -      if (num_jars_now < _header._num_jars) {
  19.461 -
  19.462 -        // Jar file - verify timestamp and file size.
  19.463 -        struct stat st;
  19.464 -        const char *path = cpe->name();
  19.465 -        if (os::stat(path, &st) != 0) {
  19.466 -          fail_continue("Unable to open jar file %s.", path);
  19.467 -          return false;
  19.468 -        }
  19.469 -        if (_header._jar[num_jars_now]._timestamp != st.st_mtime ||
  19.470 -            _header._jar[num_jars_now]._filesize != st.st_size) {
  19.471 -          fail_continue("A jar file is not the one used while building"
  19.472 -                        " the shared archive file.");
  19.473 -          return false;
  19.474 -        }
  19.475 -      }
  19.476 -      ++num_jars_now;
  19.477 -    } else {
  19.478 -
  19.479 -      // If directories appear in boot classpath, they must be empty to
  19.480 -      // avoid having to verify each individual class file.
  19.481 -      const char* name = ((ClassPathDirEntry*)cpe)->name();
  19.482 -      if (!os::dir_is_empty(name)) {
  19.483 -        fail_continue("Boot classpath directory %s is not empty.", name);
  19.484 -        return false;
  19.485 -      }
  19.486 -    }
  19.487 -  }
  19.488 -  if (num_jars_now < _header._num_jars) {
  19.489 -    fail_continue("The number of jar files in the boot classpath is"
  19.490 -                  " less than the number the shared archive was created with.");
  19.491 +                  _obj_alignment, ObjectAlignmentInBytes);
  19.492      return false;
  19.493    }
  19.494  
  19.495    return true;
  19.496  }
  19.497  
  19.498 +bool FileMapInfo::validate_header() {
  19.499 +  bool status = _header->validate();
  19.500 +
  19.501 +  if (status) {
  19.502 +    if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) {
  19.503 +      if (!PrintSharedArchiveAndExit) {
  19.504 +        fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)");
  19.505 +        status = false;
  19.506 +      }
  19.507 +    }
  19.508 +  }
  19.509 +
  19.510 +  if (_paths_misc_info != NULL) {
  19.511 +    FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass);
  19.512 +    _paths_misc_info = NULL;
  19.513 +  }
  19.514 +  return status;
  19.515 +}
  19.516 +
  19.517  // The following method is provided to see whether a given pointer
  19.518  // falls in the mapped shared space.
  19.519  // Param:
  19.520 @@ -540,8 +685,8 @@
  19.521  // True if the p is within the mapped shared space, otherwise, false.
  19.522  bool FileMapInfo::is_in_shared_space(const void* p) {
  19.523    for (int i = 0; i < MetaspaceShared::n_regions; i++) {
  19.524 -    if (p >= _header._space[i]._base &&
  19.525 -        p < _header._space[i]._base + _header._space[i]._used) {
  19.526 +    if (p >= _header->_space[i]._base &&
  19.527 +        p < _header->_space[i]._base + _header->_space[i]._used) {
  19.528        return true;
  19.529      }
  19.530    }
  19.531 @@ -552,7 +697,7 @@
  19.532  void FileMapInfo::print_shared_spaces() {
  19.533    gclog_or_tty->print_cr("Shared Spaces:");
  19.534    for (int i = 0; i < MetaspaceShared::n_regions; i++) {
  19.535 -    struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i];
  19.536 +    struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
  19.537      gclog_or_tty->print("  %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
  19.538                          shared_region_name[i],
  19.539                          si->_base, si->_base + si->_used);
  19.540 @@ -565,9 +710,9 @@
  19.541    if (map_info) {
  19.542      map_info->fail_continue(msg);
  19.543      for (int i = 0; i < MetaspaceShared::n_regions; i++) {
  19.544 -      if (map_info->_header._space[i]._base != NULL) {
  19.545 +      if (map_info->_header->_space[i]._base != NULL) {
  19.546          map_info->unmap_region(i);
  19.547 -        map_info->_header._space[i]._base = NULL;
  19.548 +        map_info->_header->_space[i]._base = NULL;
  19.549        }
  19.550      }
  19.551    } else if (DumpSharedSpaces) {
    20.1 --- a/src/share/vm/memory/filemap.hpp	Wed Sep 03 09:24:07 2014 +0200
    20.2 +++ b/src/share/vm/memory/filemap.hpp	Wed Sep 03 09:25:44 2014 +0200
    20.3 @@ -37,30 +37,55 @@
    20.4  //  misc data (block offset table, string table, symbols, dictionary, etc.)
    20.5  //  tag(666)
    20.6  
    20.7 -static const int JVM_SHARED_JARS_MAX = 128;
    20.8 -static const int JVM_SPACENAME_MAX = 128;
    20.9  static const int JVM_IDENT_MAX = 256;
   20.10 -static const int JVM_ARCH_MAX = 12;
   20.11 -
   20.12  
   20.13  class Metaspace;
   20.14  
   20.15 +class SharedClassPathEntry VALUE_OBJ_CLASS_SPEC {
   20.16 +public:
   20.17 +  const char *_name;
   20.18 +  time_t _timestamp;          // jar timestamp,  0 if is directory
   20.19 +  long   _filesize;           // jar file size, -1 if is directory
   20.20 +  bool is_dir() {
   20.21 +    return _filesize == -1;
   20.22 +  }
   20.23 +};
   20.24 +
   20.25  class FileMapInfo : public CHeapObj<mtInternal> {
   20.26  private:
   20.27 +  friend class ManifestStream;
   20.28    enum {
   20.29      _invalid_version = -1,
   20.30 -    _current_version = 1
   20.31 +    _current_version = 2
   20.32    };
   20.33  
   20.34    bool  _file_open;
   20.35    int   _fd;
   20.36    long  _file_offset;
   20.37  
   20.38 +private:
   20.39 +  static SharedClassPathEntry* _classpath_entry_table;
   20.40 +  static int                   _classpath_entry_table_size;
   20.41 +  static size_t                _classpath_entry_size;
   20.42 +  static bool                  _validating_classpath_entry_table;
   20.43 +
   20.44    // FileMapHeader describes the shared space data in the file to be
   20.45    // mapped.  This structure gets written to a file.  It is not a class, so
   20.46    // that the compilers don't add any compiler-private data to it.
   20.47  
   20.48 -  struct FileMapHeader {
   20.49 +public:
   20.50 +  struct FileMapHeaderBase : public CHeapObj<mtClass> {
   20.51 +    virtual bool validate() = 0;
   20.52 +    virtual void populate(FileMapInfo* info, size_t alignment) = 0;
   20.53 +  };
   20.54 +  struct FileMapHeader : FileMapHeaderBase {
   20.55 +    // Use data() and data_size() to memcopy to/from the FileMapHeader. We need to
   20.56 +    // avoid read/writing the C++ vtable pointer.
   20.57 +    static size_t data_size();
   20.58 +    char* data() {
   20.59 +      return ((char*)this) + sizeof(FileMapHeaderBase);
   20.60 +    }
   20.61 +
   20.62      int    _magic;                    // identify file type.
   20.63      int    _version;                  // (from enum, above.)
   20.64      size_t _alignment;                // how shared archive should be aligned
   20.65 @@ -78,44 +103,64 @@
   20.66      // The following fields are all sanity checks for whether this archive
   20.67      // will function correctly with this JVM and the bootclasspath it's
   20.68      // invoked with.
   20.69 -    char  _arch[JVM_ARCH_MAX];            // architecture
   20.70      char  _jvm_ident[JVM_IDENT_MAX];      // identifier for jvm
   20.71 -    int   _num_jars;              // Number of jars in bootclasspath
   20.72  
   20.73 -    // Per jar file data:  timestamp, size.
   20.74 +    // The _paths_misc_info is a variable-size structure that records "miscellaneous"
   20.75 +    // information during dumping. It is generated and validated by the
   20.76 +    // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp and sharedClassUtil.hpp for
   20.77 +    // detailed description.
   20.78 +    //
   20.79 +    // The _paths_misc_info data is stored as a byte array in the archive file header,
   20.80 +    // immediately after the _header field. This information is used only when
   20.81 +    // checking the validity of the archive and is deallocated after the archive is loaded.
   20.82 +    //
   20.83 +    // Note that the _paths_misc_info does NOT include information for JAR files
   20.84 +    // that existed during dump time. Their information is stored in _classpath_entry_table.
   20.85 +    int _paths_misc_info_size;
   20.86  
   20.87 -    struct {
   20.88 -      time_t _timestamp;          // jar timestamp.
   20.89 -      long   _filesize;           // jar file size.
   20.90 -    } _jar[JVM_SHARED_JARS_MAX];
   20.91 -  } _header;
   20.92 +    // The following is a table of all the class path entries that were used
   20.93 +    // during dumping. At run time, we require these files to exist and have the same
   20.94 +    // size/modification time, or else the archive will refuse to load.
   20.95 +    //
   20.96 +    // All of these entries must be JAR files. The dumping process would fail if a non-empty
   20.97 +    // directory was specified in the classpaths. If an empty directory was specified
   20.98 +    // it is checked by the _paths_misc_info as described above.
   20.99 +    //
  20.100 +    // FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
  20.101 +    // they should be removed from this table, to save space and to avoid spurious
  20.102 +    // loading failures during runtime.
  20.103 +    int _classpath_entry_table_size;
  20.104 +    size_t _classpath_entry_size;
  20.105 +    SharedClassPathEntry* _classpath_entry_table;
  20.106 +
  20.107 +    virtual bool validate();
  20.108 +    virtual void populate(FileMapInfo* info, size_t alignment);
  20.109 +  };
  20.110 +
  20.111 +  FileMapHeader * _header;
  20.112 +
  20.113    const char* _full_path;
  20.114 +  char* _paths_misc_info;
  20.115  
  20.116    static FileMapInfo* _current_info;
  20.117  
  20.118    bool  init_from_file(int fd);
  20.119    void  align_file_position();
  20.120 +  bool  validate_header_impl();
  20.121  
  20.122  public:
  20.123 -  FileMapInfo() {
  20.124 -    _file_offset = 0;
  20.125 -    _file_open = false;
  20.126 -    _header._version = _invalid_version;
  20.127 -  }
  20.128 +  FileMapInfo();
  20.129 +  ~FileMapInfo();
  20.130  
  20.131    static int current_version()        { return _current_version; }
  20.132    void   populate_header(size_t alignment);
  20.133 -  bool   validate();
  20.134 +  bool   validate_header();
  20.135    void   invalidate();
  20.136 -  int    version()                    { return _header._version; }
  20.137 -  size_t alignment()                  { return _header._alignment; }
  20.138 -  size_t space_capacity(int i)        { return _header._space[i]._capacity; }
  20.139 -  char*  region_base(int i)           { return _header._space[i]._base; }
  20.140 -  struct FileMapHeader* header()      { return &_header; }
  20.141 -
  20.142 -  static void set_current_info(FileMapInfo* info) {
  20.143 -    CDS_ONLY(_current_info = info;)
  20.144 -  }
  20.145 +  int    version()                    { return _header->_version; }
  20.146 +  size_t alignment()                  { return _header->_alignment; }
  20.147 +  size_t space_capacity(int i)        { return _header->_space[i]._capacity; }
  20.148 +  char*  region_base(int i)           { return _header->_space[i]._base; }
  20.149 +  struct FileMapHeader* header()      { return _header; }
  20.150  
  20.151    static FileMapInfo* current_info() {
  20.152      CDS_ONLY(return _current_info;)
  20.153 @@ -146,7 +191,7 @@
  20.154  
  20.155    // Errors.
  20.156    static void fail_stop(const char *msg, ...);
  20.157 -  void fail_continue(const char *msg, ...);
  20.158 +  static void fail_continue(const char *msg, ...);
  20.159  
  20.160    // Return true if given address is in the mapped shared space.
  20.161    bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
  20.162 @@ -160,6 +205,22 @@
  20.163  
  20.164    // Stop CDS sharing and unmap CDS regions.
  20.165    static void stop_sharing_and_unmap(const char* msg);
  20.166 +
  20.167 +  static void allocate_classpath_entry_table();
  20.168 +  bool validate_classpath_entry_table();
  20.169 +
  20.170 +  static SharedClassPathEntry* shared_classpath(int index) {
  20.171 +    char* p = (char*)_classpath_entry_table;
  20.172 +    p += _classpath_entry_size * index;
  20.173 +    return (SharedClassPathEntry*)p;
  20.174 +  }
  20.175 +  static const char* shared_classpath_name(int index) {
  20.176 +    return shared_classpath(index)->_name;
  20.177 +  }
  20.178 +
  20.179 +  static int get_number_of_share_classpaths() {
  20.180 +    return _classpath_entry_table_size;
  20.181 +  }
  20.182  };
  20.183  
  20.184  #endif // SHARE_VM_MEMORY_FILEMAP_HPP
    21.1 --- a/src/share/vm/memory/metadataFactory.hpp	Wed Sep 03 09:24:07 2014 +0200
    21.2 +++ b/src/share/vm/memory/metadataFactory.hpp	Wed Sep 03 09:25:44 2014 +0200
    21.3 @@ -79,6 +79,12 @@
    21.4    // Deallocation method for metadata
    21.5    template <class T>
    21.6    static void free_metadata(ClassLoaderData* loader_data, T md) {
    21.7 +    if (DumpSharedSpaces) {
    21.8 +      // FIXME: the freeing code is buggy, especially when PrintSharedSpaces is enabled.
    21.9 +      // Disable for now -- this means if you specify bad classes in your classlist you
   21.10 +      // may have wasted space inside the archive.
   21.11 +      return;
   21.12 +    }
   21.13      if (md != NULL) {
   21.14        assert(loader_data != NULL, "shouldn't pass null");
   21.15        int size = md->size();
    22.1 --- a/src/share/vm/memory/metaspace.cpp	Wed Sep 03 09:24:07 2014 +0200
    22.2 +++ b/src/share/vm/memory/metaspace.cpp	Wed Sep 03 09:25:44 2014 +0200
    22.3 @@ -413,6 +413,7 @@
    22.4  VirtualSpaceNode::VirtualSpaceNode(size_t bytes) : _top(NULL), _next(NULL), _rs(), _container_count(0) {
    22.5    assert_is_size_aligned(bytes, Metaspace::reserve_alignment());
    22.6  
    22.7 +#if INCLUDE_CDS
    22.8    // This allocates memory with mmap.  For DumpSharedspaces, try to reserve
    22.9    // configurable address, generally at the top of the Java heap so other
   22.10    // memory addresses don't conflict.
   22.11 @@ -428,7 +429,9 @@
   22.12        _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
   22.13      }
   22.14      MetaspaceShared::set_shared_rs(&_rs);
   22.15 -  } else {
   22.16 +  } else
   22.17 +#endif
   22.18 +  {
   22.19      bool large_pages = should_commit_large_pages_when_reserving(bytes);
   22.20  
   22.21      _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
   22.22 @@ -2937,11 +2940,14 @@
   22.23    // between the lower base and higher address.
   22.24    address lower_base;
   22.25    address higher_address;
   22.26 +#if INCLUDE_CDS
   22.27    if (UseSharedSpaces) {
   22.28      higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
   22.29                            (address)(metaspace_base + compressed_class_space_size()));
   22.30      lower_base = MIN2(metaspace_base, cds_base);
   22.31 -  } else {
   22.32 +  } else
   22.33 +#endif
   22.34 +  {
   22.35      higher_address = metaspace_base + compressed_class_space_size();
   22.36      lower_base = metaspace_base;
   22.37  
   22.38 @@ -2962,6 +2968,7 @@
   22.39    }
   22.40  }
   22.41  
   22.42 +#if INCLUDE_CDS
   22.43  // Return TRUE if the specified metaspace_base and cds_base are close enough
   22.44  // to work with compressed klass pointers.
   22.45  bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
   22.46 @@ -2972,6 +2979,7 @@
   22.47                                  (address)(metaspace_base + compressed_class_space_size()));
   22.48    return ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax);
   22.49  }
   22.50 +#endif
   22.51  
   22.52  // Try to allocate the metaspace at the requested addr.
   22.53  void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
   22.54 @@ -2991,6 +2999,7 @@
   22.55                                               large_pages,
   22.56                                               requested_addr, 0);
   22.57    if (!metaspace_rs.is_reserved()) {
   22.58 +#if INCLUDE_CDS
   22.59      if (UseSharedSpaces) {
   22.60        size_t increment = align_size_up(1*G, _reserve_alignment);
   22.61  
   22.62 @@ -3005,7 +3014,7 @@
   22.63                                       _reserve_alignment, large_pages, addr, 0);
   22.64        }
   22.65      }
   22.66 -
   22.67 +#endif
   22.68      // If no successful allocation then try to allocate the space anywhere.  If
   22.69      // that fails then OOM doom.  At this point we cannot try allocating the
   22.70      // metaspace as if UseCompressedClassPointers is off because too much
   22.71 @@ -3024,12 +3033,13 @@
   22.72    // If we got here then the metaspace got allocated.
   22.73    MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass);
   22.74  
   22.75 +#if INCLUDE_CDS
   22.76    // Verify that we can use shared spaces.  Otherwise, turn off CDS.
   22.77    if (UseSharedSpaces && !can_use_cds_with_metaspace_addr(metaspace_rs.base(), cds_base)) {
   22.78      FileMapInfo::stop_sharing_and_unmap(
   22.79          "Could not allocate metaspace at a compatible address");
   22.80    }
   22.81 -
   22.82 +#endif
   22.83    set_narrow_klass_base_and_shift((address)metaspace_rs.base(),
   22.84                                    UseSharedSpaces ? (address)cds_base : 0);
   22.85  
   22.86 @@ -3113,6 +3123,7 @@
   22.87    MetaspaceShared::set_max_alignment(max_alignment);
   22.88  
   22.89    if (DumpSharedSpaces) {
   22.90 +#if INCLUDE_CDS
   22.91      SharedReadOnlySize  = align_size_up(SharedReadOnlySize,  max_alignment);
   22.92      SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment);
   22.93      SharedMiscDataSize  = align_size_up(SharedMiscDataSize,  max_alignment);
   22.94 @@ -3150,23 +3161,22 @@
   22.95      }
   22.96  
   22.97      Universe::set_narrow_klass_shift(0);
   22.98 -#endif
   22.99 -
  22.100 +#endif // _LP64
  22.101 +#endif // INCLUDE_CDS
  22.102    } else {
  22.103 +#if INCLUDE_CDS
  22.104      // If using shared space, open the file that contains the shared space
  22.105      // and map in the memory before initializing the rest of metaspace (so
  22.106      // the addresses don't conflict)
  22.107      address cds_address = NULL;
  22.108      if (UseSharedSpaces) {
  22.109        FileMapInfo* mapinfo = new FileMapInfo();
  22.110 -      memset(mapinfo, 0, sizeof(FileMapInfo));
  22.111  
  22.112        // Open the shared archive file, read and validate the header. If
  22.113        // initialization fails, shared spaces [UseSharedSpaces] are
  22.114        // disabled and the file is closed.
  22.115        // Map in spaces now also
  22.116        if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
  22.117 -        FileMapInfo::set_current_info(mapinfo);
  22.118          cds_total = FileMapInfo::shared_spaces_size();
  22.119          cds_address = (address)mapinfo->region_base(0);
  22.120        } else {
  22.121 @@ -3174,21 +3184,23 @@
  22.122                 "archive file not closed or shared spaces not disabled.");
  22.123        }
  22.124      }
  22.125 -
  22.126 +#endif // INCLUDE_CDS
  22.127  #ifdef _LP64
  22.128      // If UseCompressedClassPointers is set then allocate the metaspace area
  22.129      // above the heap and above the CDS area (if it exists).
  22.130      if (using_class_space()) {
  22.131        if (UseSharedSpaces) {
  22.132 +#if INCLUDE_CDS
  22.133          char* cds_end = (char*)(cds_address + cds_total);
  22.134          cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
  22.135          allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
  22.136 +#endif
  22.137        } else {
  22.138          char* base = (char*)align_ptr_up(Universe::heap()->reserved_region().end(), _reserve_alignment);
  22.139          allocate_metaspace_compressed_klass_ptrs(base, 0);
  22.140        }
  22.141      }
  22.142 -#endif
  22.143 +#endif // _LP64
  22.144  
  22.145      // Initialize these before initializing the VirtualSpaceList
  22.146      _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
  22.147 @@ -3366,6 +3378,10 @@
  22.148  
  22.149  void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
  22.150    if (SafepointSynchronize::is_at_safepoint()) {
  22.151 +    if (DumpSharedSpaces && PrintSharedSpaces) {
  22.152 +      record_deallocation(ptr, vsm()->get_raw_word_size(word_size));
  22.153 +    }
  22.154 +
  22.155      assert(Thread::current()->is_VM_thread(), "should be the VM thread");
  22.156      // Don't take Heap_lock
  22.157      MutexLockerEx ml(vsm()->lock(), Mutex::_no_safepoint_check_flag);
  22.158 @@ -3420,8 +3436,9 @@
  22.159      if (result == NULL) {
  22.160        report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
  22.161      }
  22.162 -
  22.163 -    space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
  22.164 +    if (PrintSharedSpaces) {
  22.165 +      space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
  22.166 +    }
  22.167  
  22.168      // Zero initialize.
  22.169      Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
  22.170 @@ -3520,15 +3537,55 @@
  22.171  void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
  22.172    assert(DumpSharedSpaces, "sanity");
  22.173  
  22.174 -  AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize);
  22.175 +  int byte_size = (int)word_size * HeapWordSize;
  22.176 +  AllocRecord *rec = new AllocRecord((address)ptr, type, byte_size);
  22.177 +
  22.178    if (_alloc_record_head == NULL) {
  22.179      _alloc_record_head = _alloc_record_tail = rec;
  22.180 -  } else {
  22.181 +  } else if (_alloc_record_tail->_ptr + _alloc_record_tail->_byte_size == (address)ptr) {
  22.182      _alloc_record_tail->_next = rec;
  22.183      _alloc_record_tail = rec;
  22.184 +  } else {
  22.185 +    // slow linear search, but this doesn't happen that often, and only when dumping
  22.186 +    for (AllocRecord *old = _alloc_record_head; old; old = old->_next) {
  22.187 +      if (old->_ptr == ptr) {
  22.188 +        assert(old->_type == MetaspaceObj::DeallocatedType, "sanity");
  22.189 +        int remain_bytes = old->_byte_size - byte_size;
  22.190 +        assert(remain_bytes >= 0, "sanity");
  22.191 +        old->_type = type;
  22.192 +
  22.193 +        if (remain_bytes == 0) {
  22.194 +          delete(rec);
  22.195 +        } else {
  22.196 +          address remain_ptr = address(ptr) + byte_size;
  22.197 +          rec->_ptr = remain_ptr;
  22.198 +          rec->_byte_size = remain_bytes;
  22.199 +          rec->_type = MetaspaceObj::DeallocatedType;
  22.200 +          rec->_next = old->_next;
  22.201 +          old->_byte_size = byte_size;
  22.202 +          old->_next = rec;
  22.203 +        }
  22.204 +        return;
  22.205 +      }
  22.206 +    }
  22.207 +    assert(0, "reallocating a freed pointer that was not recorded");
  22.208    }
  22.209  }
  22.210  
  22.211 +void Metaspace::record_deallocation(void* ptr, size_t word_size) {
  22.212 +  assert(DumpSharedSpaces, "sanity");
  22.213 +
  22.214 +  for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
  22.215 +    if (rec->_ptr == ptr) {
  22.216 +      assert(rec->_byte_size == (int)word_size * HeapWordSize, "sanity");
  22.217 +      rec->_type = MetaspaceObj::DeallocatedType;
  22.218 +      return;
  22.219 +    }
  22.220 +  }
  22.221 +
  22.222 +  assert(0, "deallocating a pointer that was not recorded");
  22.223 +}
  22.224 +
  22.225  void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
  22.226    assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
  22.227  
    23.1 --- a/src/share/vm/memory/metaspace.hpp	Wed Sep 03 09:24:07 2014 +0200
    23.2 +++ b/src/share/vm/memory/metaspace.hpp	Wed Sep 03 09:25:44 2014 +0200
    23.3 @@ -171,9 +171,10 @@
    23.4    static const MetaspaceTracer* tracer() { return _tracer; }
    23.5  
    23.6   private:
    23.7 -  // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
    23.8 +  // These 2 methods are used by DumpSharedSpaces only, where only _vsm is used. So we will
    23.9    // maintain a single list for now.
   23.10    void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
   23.11 +  void record_deallocation(void* ptr, size_t word_size);
   23.12  
   23.13  #ifdef _LP64
   23.14    static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
    24.1 --- a/src/share/vm/memory/metaspaceShared.cpp	Wed Sep 03 09:24:07 2014 +0200
    24.2 +++ b/src/share/vm/memory/metaspaceShared.cpp	Wed Sep 03 09:25:44 2014 +0200
    24.3 @@ -26,6 +26,7 @@
    24.4  #include "classfile/dictionary.hpp"
    24.5  #include "classfile/loaderConstraints.hpp"
    24.6  #include "classfile/placeholders.hpp"
    24.7 +#include "classfile/sharedClassUtil.hpp"
    24.8  #include "classfile/symbolTable.hpp"
    24.9  #include "classfile/systemDictionary.hpp"
   24.10  #include "code/codeCache.hpp"
   24.11 @@ -46,6 +47,10 @@
   24.12  
   24.13  ReservedSpace* MetaspaceShared::_shared_rs = NULL;
   24.14  
   24.15 +bool MetaspaceShared::_link_classes_made_progress;
   24.16 +bool MetaspaceShared::_check_classes_made_progress;
   24.17 +bool MetaspaceShared::_has_error_classes;
   24.18 +bool MetaspaceShared::_archive_loading_failed = false;
   24.19  // Read/write a data stream for restoring/preserving metadata pointers and
   24.20  // miscellaneous data from/to the shared archive file.
   24.21  
   24.22 @@ -445,6 +450,23 @@
   24.23    SystemDictionary::classes_do(collect_classes);
   24.24  
   24.25    tty->print_cr("Number of classes %d", _global_klass_objects->length());
   24.26 +  {
   24.27 +    int num_type_array = 0, num_obj_array = 0, num_inst = 0;
   24.28 +    for (int i = 0; i < _global_klass_objects->length(); i++) {
   24.29 +      Klass* k = _global_klass_objects->at(i);
   24.30 +      if (k->oop_is_instance()) {
   24.31 +        num_inst ++;
   24.32 +      } else if (k->oop_is_objArray()) {
   24.33 +        num_obj_array ++;
   24.34 +      } else {
   24.35 +        assert(k->oop_is_typeArray(), "sanity");
   24.36 +        num_type_array ++;
   24.37 +      }
   24.38 +    }
   24.39 +    tty->print_cr("    instance classes   = %5d", num_inst);
   24.40 +    tty->print_cr("    obj array classes  = %5d", num_obj_array);
   24.41 +    tty->print_cr("    type array classes = %5d", num_type_array);
   24.42 +  }
   24.43  
   24.44    // Update all the fingerprints in the shared methods.
   24.45    tty->print("Calculating fingerprints ... ");
   24.46 @@ -610,38 +632,58 @@
   24.47  #undef fmt_space
   24.48  }
   24.49  
   24.50 -static void link_shared_classes(Klass* obj, TRAPS) {
   24.51 +
   24.52 +void MetaspaceShared::link_one_shared_class(Klass* obj, TRAPS) {
   24.53    Klass* k = obj;
   24.54    if (k->oop_is_instance()) {
   24.55      InstanceKlass* ik = (InstanceKlass*) k;
   24.56      // Link the class to cause the bytecodes to be rewritten and the
   24.57 -    // cpcache to be created.
   24.58 -    if (ik->init_state() < InstanceKlass::linked) {
   24.59 -      ik->link_class(THREAD);
   24.60 -      guarantee(!HAS_PENDING_EXCEPTION, "exception in class rewriting");
   24.61 +    // cpcache to be created. Class verification is done according
   24.62 +    // to -Xverify setting.
   24.63 +    _link_classes_made_progress |= try_link_class(ik, THREAD);
   24.64 +    guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
   24.65 +  }
   24.66 +}
   24.67 +
   24.68 +void MetaspaceShared::check_one_shared_class(Klass* k) {
   24.69 +  if (k->oop_is_instance() && InstanceKlass::cast(k)->check_sharing_error_state()) {
   24.70 +    _check_classes_made_progress = true;
   24.71 +  }
   24.72 +}
   24.73 +
   24.74 +void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
   24.75 +  // We need to iterate because verification may cause additional classes
   24.76 +  // to be loaded.
   24.77 +  do {
   24.78 +    _link_classes_made_progress = false;
   24.79 +    SystemDictionary::classes_do(link_one_shared_class, THREAD);
   24.80 +    guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
   24.81 +  } while (_link_classes_made_progress);
   24.82 +
   24.83 +  if (_has_error_classes) {
   24.84 +    // Mark all classes whose super class or interfaces failed verification.
   24.85 +    do {
   24.86 +      // Not completely sure if we need to do this iteratively. Anyway,
   24.87 +      // we should come here only if there are unverifiable classes, which
   24.88 +      // shouldn't happen in normal cases. So better safe than sorry.
   24.89 +      _check_classes_made_progress = false;
   24.90 +      SystemDictionary::classes_do(check_one_shared_class);
   24.91 +    } while (_check_classes_made_progress);
   24.92 +
   24.93 +    if (IgnoreUnverifiableClassesDuringDump) {
   24.94 +      // This is useful when running JCK or SQE tests. You should not
   24.95 +      // enable this when running real apps.
   24.96 +      SystemDictionary::remove_classes_in_error_state();
   24.97 +    } else {
   24.98 +      tty->print_cr("Please remove the unverifiable classes from your class list and try again");
   24.99 +      exit(1);
  24.100      }
  24.101    }
  24.102  }
  24.103  
  24.104 -
  24.105 -// Support for a simple checksum of the contents of the class list
  24.106 -// file to prevent trivial tampering. The algorithm matches that in
  24.107 -// the MakeClassList program used by the J2SE build process.
  24.108 -#define JSUM_SEED ((jlong)CONST64(0xcafebabebabecafe))
  24.109 -static jlong
  24.110 -jsum(jlong start, const char *buf, const int len)
  24.111 -{
  24.112 -    jlong h = start;
  24.113 -    char *p = (char *)buf, *e = p + len;
  24.114 -    while (p < e) {
  24.115 -        char c = *p++;
  24.116 -        if (c <= ' ') {
  24.117 -            /* Skip spaces and control characters */
  24.118 -            continue;
  24.119 -        }
  24.120 -        h = 31 * h + c;
  24.121 -    }
  24.122 -    return h;
  24.123 +void MetaspaceShared::prepare_for_dumping() {
  24.124 +  ClassLoader::initialize_shared_path();
  24.125 +  FileMapInfo::allocate_classpath_entry_table();
  24.126  }
  24.127  
  24.128  // Preload classes from a list, populate the shared spaces and dump to a
  24.129 @@ -650,72 +692,112 @@
  24.130    TraceTime timer("Dump Shared Spaces", TraceStartupTime);
  24.131    ResourceMark rm;
  24.132  
  24.133 +  tty->print_cr("Allocated shared space: %d bytes at " PTR_FORMAT,
  24.134 +                MetaspaceShared::shared_rs()->size(),
  24.135 +                MetaspaceShared::shared_rs()->base());
  24.136 +
  24.137    // Preload classes to be shared.
  24.138    // Should use some os:: method rather than fopen() here. aB.
  24.139 -  // Construct the path to the class list (in jre/lib)
  24.140 -  // Walk up two directories from the location of the VM and
  24.141 -  // optionally tack on "lib" (depending on platform)
  24.142 -  char class_list_path[JVM_MAXPATHLEN];
  24.143 -  os::jvm_path(class_list_path, sizeof(class_list_path));
  24.144 -  for (int i = 0; i < 3; i++) {
  24.145 -    char *end = strrchr(class_list_path, *os::file_separator());
  24.146 -    if (end != NULL) *end = '\0';
  24.147 +  const char* class_list_path;
  24.148 +  if (SharedClassListFile == NULL) {
  24.149 +    // Construct the path to the class list (in jre/lib)
  24.150 +    // Walk up two directories from the location of the VM and
  24.151 +    // optionally tack on "lib" (depending on platform)
  24.152 +    char class_list_path_str[JVM_MAXPATHLEN];
  24.153 +    os::jvm_path(class_list_path_str, sizeof(class_list_path_str));
  24.154 +    for (int i = 0; i < 3; i++) {
  24.155 +      char *end = strrchr(class_list_path_str, *os::file_separator());
  24.156 +      if (end != NULL) *end = '\0';
  24.157 +    }
  24.158 +    int class_list_path_len = (int)strlen(class_list_path_str);
  24.159 +    if (class_list_path_len >= 3) {
  24.160 +      if (strcmp(class_list_path_str + class_list_path_len - 3, "lib") != 0) {
  24.161 +        strcat(class_list_path_str, os::file_separator());
  24.162 +        strcat(class_list_path_str, "lib");
  24.163 +      }
  24.164 +    }
  24.165 +    strcat(class_list_path_str, os::file_separator());
  24.166 +    strcat(class_list_path_str, "classlist");
  24.167 +    class_list_path = class_list_path_str;
  24.168 +  } else {
  24.169 +    class_list_path = SharedClassListFile;
  24.170    }
  24.171 -  int class_list_path_len = (int)strlen(class_list_path);
  24.172 -  if (class_list_path_len >= 3) {
  24.173 -    if (strcmp(class_list_path + class_list_path_len - 3, "lib") != 0) {
  24.174 -      strcat(class_list_path, os::file_separator());
  24.175 -      strcat(class_list_path, "lib");
  24.176 -    }
  24.177 +
  24.178 +  int class_count = 0;
  24.179 +  GrowableArray<Klass*>* class_promote_order = new GrowableArray<Klass*>();
  24.180 +
  24.181 +  // sun.io.Converters
  24.182 +  static const char obj_array_sig[] = "[[Ljava/lang/Object;";
  24.183 +  SymbolTable::new_permanent_symbol(obj_array_sig, THREAD);
  24.184 +
  24.185 +  // java.util.HashMap
  24.186 +  static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
  24.187 +  SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
  24.188 +
  24.189 +  tty->print_cr("Loading classes to share ...");
  24.190 +  _has_error_classes = false;
  24.191 +  class_count += preload_and_dump(class_list_path, class_promote_order,
  24.192 +                                  THREAD);
  24.193 +  if (ExtraSharedClassListFile) {
  24.194 +    class_count += preload_and_dump(ExtraSharedClassListFile, class_promote_order,
  24.195 +                                    THREAD);
  24.196    }
  24.197 -  strcat(class_list_path, os::file_separator());
  24.198 -  strcat(class_list_path, "classlist");
  24.199 +  tty->print_cr("Loading classes to share: done.");
  24.200  
  24.201 +  if (PrintSharedSpaces) {
  24.202 +    tty->print_cr("Shared spaces: preloaded %d classes", class_count);
  24.203 +  }
  24.204 +
  24.205 +  // Rewrite and link classes
  24.206 +  tty->print_cr("Rewriting and linking classes ...");
  24.207 +
  24.208 +  // Link any classes which got missed. This would happen if we have loaded classes that
  24.209 +  // were not explicitly specified in the classlist. E.g., if an interface implemented by class K
  24.210 +  // fails verification, all other interfaces that were not specified in the classlist but
  24.211 +  // are implemented by K are not verified.
  24.212 +  link_and_cleanup_shared_classes(CATCH);
  24.213 +  tty->print_cr("Rewriting and linking classes: done");
  24.214 +
  24.215 +  // Create and dump the shared spaces.   Everything so far is loaded
  24.216 +  // with the null class loader.
  24.217 +  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
  24.218 +  VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
  24.219 +  VMThread::execute(&op);
  24.220 +
  24.221 +  // Since various initialization steps have been undone by this process,
  24.222 +  // it is not reasonable to continue running a java process.
  24.223 +  exit(0);
  24.224 +}
  24.225 +
  24.226 +int MetaspaceShared::preload_and_dump(const char * class_list_path,
  24.227 +                                      GrowableArray<Klass*>* class_promote_order,
  24.228 +                                      TRAPS) {
  24.229    FILE* file = fopen(class_list_path, "r");
  24.230 +  char class_name[256];
  24.231 +  int class_count = 0;
  24.232 +
  24.233    if (file != NULL) {
  24.234 -    jlong computed_jsum  = JSUM_SEED;
  24.235 -    jlong file_jsum      = 0;
  24.236 -
  24.237 -    char class_name[256];
  24.238 -    int class_count = 0;
  24.239 -    GrowableArray<Klass*>* class_promote_order = new GrowableArray<Klass*>();
  24.240 -
  24.241 -    // sun.io.Converters
  24.242 -    static const char obj_array_sig[] = "[[Ljava/lang/Object;";
  24.243 -    SymbolTable::new_permanent_symbol(obj_array_sig, THREAD);
  24.244 -
  24.245 -    // java.util.HashMap
  24.246 -    static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
  24.247 -    SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
  24.248 -
  24.249 -    tty->print("Loading classes to share ... ");
  24.250      while ((fgets(class_name, sizeof class_name, file)) != NULL) {
  24.251 -      if (*class_name == '#') {
  24.252 -        jint fsh, fsl;
  24.253 -        if (sscanf(class_name, "# %8x%8x\n", &fsh, &fsl) == 2) {
  24.254 -          file_jsum = ((jlong)(fsh) << 32) | (fsl & 0xffffffff);
  24.255 -        }
  24.256 -
  24.257 +      if (*class_name == '#') { // comment
  24.258          continue;
  24.259        }
  24.260        // Remove trailing newline
  24.261        size_t name_len = strlen(class_name);
  24.262 -      class_name[name_len-1] = '\0';
  24.263 -
  24.264 -      computed_jsum = jsum(computed_jsum, class_name, (const int)name_len - 1);
  24.265 +      if (class_name[name_len-1] == '\n') {
  24.266 +        class_name[name_len-1] = '\0';
  24.267 +      }
  24.268  
  24.269        // Got a class name - load it.
  24.270        TempNewSymbol class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD);
  24.271        guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
  24.272        Klass* klass = SystemDictionary::resolve_or_null(class_name_symbol,
  24.273                                                           THREAD);
  24.274 -      guarantee(!HAS_PENDING_EXCEPTION, "Exception resolving a class.");
  24.275 +      CLEAR_PENDING_EXCEPTION;
  24.276        if (klass != NULL) {
  24.277          if (PrintSharedSpaces && Verbose && WizardMode) {
  24.278            tty->print_cr("Shared spaces preloaded: %s", class_name);
  24.279          }
  24.280  
  24.281 -
  24.282          InstanceKlass* ik = InstanceKlass::cast(klass);
  24.283  
  24.284          // Should be class load order as per -XX:+TraceClassLoadingPreorder
  24.285 @@ -725,52 +807,14 @@
  24.286          // cpcache to be created. The linking is done as soon as classes
  24.287          // are loaded in order that the related data structures (klass and
  24.288          // cpCache) are located together.
  24.289 -
  24.290 -        if (ik->init_state() < InstanceKlass::linked) {
  24.291 -          ik->link_class(THREAD);
  24.292 -          guarantee(!(HAS_PENDING_EXCEPTION), "exception in class rewriting");
  24.293 -        }
  24.294 -
  24.295 -        // TODO: Resolve klasses in constant pool
  24.296 -        ik->constants()->resolve_class_constants(THREAD);
  24.297 +        try_link_class(ik, THREAD);
  24.298 +        guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
  24.299  
  24.300          class_count++;
  24.301        } else {
  24.302 -        if (PrintSharedSpaces && Verbose && WizardMode) {
  24.303 -          tty->cr();
  24.304 -          tty->print_cr(" Preload failed: %s", class_name);
  24.305 -        }
  24.306 +        //tty->print_cr("Preload failed: %s", class_name);
  24.307        }
  24.308 -      file_jsum = 0; // Checksum must be on last line of file
  24.309      }
  24.310 -    if (computed_jsum != file_jsum) {
  24.311 -      tty->cr();
  24.312 -      tty->print_cr("Preload failed: checksum of class list was incorrect.");
  24.313 -      exit(1);
  24.314 -    }
  24.315 -
  24.316 -    tty->print_cr("done. ");
  24.317 -
  24.318 -    if (PrintSharedSpaces) {
  24.319 -      tty->print_cr("Shared spaces: preloaded %d classes", class_count);
  24.320 -    }
  24.321 -
  24.322 -    // Rewrite and unlink classes.
  24.323 -    tty->print("Rewriting and linking classes ... ");
  24.324 -
  24.325 -    // Link any classes which got missed.  (It's not quite clear why
  24.326 -    // they got missed.)  This iteration would be unsafe if we weren't
  24.327 -    // single-threaded at this point; however we can't do it on the VM
  24.328 -    // thread because it requires object allocation.
  24.329 -    SystemDictionary::classes_do(link_shared_classes, CATCH);
  24.330 -    tty->print_cr("done. ");
  24.331 -
  24.332 -    // Create and dump the shared spaces.   Everything so far is loaded
  24.333 -    // with the null class loader.
  24.334 -    ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
  24.335 -    VM_PopulateDumpSharedSpace op(loader_data, class_promote_order);
  24.336 -    VMThread::execute(&op);
  24.337 -
  24.338    } else {
  24.339      char errmsg[JVM_MAXPATHLEN];
  24.340      os::lasterror(errmsg, JVM_MAXPATHLEN);
  24.341 @@ -778,11 +822,39 @@
  24.342      exit(1);
  24.343    }
  24.344  
  24.345 -  // Since various initialization steps have been undone by this process,
  24.346 -  // it is not reasonable to continue running a java process.
  24.347 -  exit(0);
  24.348 +  return class_count;
  24.349  }
  24.350  
  24.351 +// Returns true if the class's status has changed
  24.352 +bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) {
  24.353 +  assert(DumpSharedSpaces, "should only be called during dumping");
  24.354 +  if (ik->init_state() < InstanceKlass::linked) {
  24.355 +    bool saved = BytecodeVerificationLocal;
  24.356 +    if (!SharedClassUtil::is_shared_boot_class(ik)) {
  24.357 +      // The verification decision is based on BytecodeVerificationRemote
  24.358 +      // for non-system classes. Since we are using the NULL classloader
  24.359 +      // to load non-system classes during dumping, we need to temporarily
  24.360 +      // change BytecodeVerificationLocal to be the same as
  24.361 +      // BytecodeVerificationRemote. Note this can cause the parent system
  24.362 +      // classes also being verified. The extra overhead is acceptable during
  24.363 +      // dumping.
  24.364 +      BytecodeVerificationLocal = BytecodeVerificationRemote;
  24.365 +    }
  24.366 +    ik->link_class(THREAD);
  24.367 +    if (HAS_PENDING_EXCEPTION) {
  24.368 +      ResourceMark rm;
  24.369 +      tty->print_cr("Preload Error: Verification failed for %s",
  24.370 +                    ik->external_name());
  24.371 +      CLEAR_PENDING_EXCEPTION;
  24.372 +      ik->set_in_error_state();
  24.373 +      _has_error_classes = true;
  24.374 +    }
  24.375 +    BytecodeVerificationLocal = saved;
  24.376 +    return true;
  24.377 +  } else {
  24.378 +    return false;
  24.379 +  }
  24.380 +}
  24.381  
  24.382  // Closure for serializing initialization data in from a data area
  24.383  // (ptr_array) read from the shared file.
  24.384 @@ -866,7 +938,8 @@
  24.385        (_rw_base = mapinfo->map_region(rw)) != NULL &&
  24.386        (_md_base = mapinfo->map_region(md)) != NULL &&
  24.387        (_mc_base = mapinfo->map_region(mc)) != NULL &&
  24.388 -      (image_alignment == (size_t)max_alignment())) {
  24.389 +      (image_alignment == (size_t)max_alignment()) &&
  24.390 +      mapinfo->validate_classpath_entry_table()) {
  24.391      // Success (no need to do anything)
  24.392      return true;
  24.393    } else {
  24.394 @@ -883,7 +956,7 @@
  24.395      // If -Xshare:on is specified, print out the error message and exit VM,
  24.396      // otherwise, set UseSharedSpaces to false and continue.
  24.397      if (RequireSharedSpaces) {
  24.398 -      vm_exit_during_initialization("Unable to use shared archive.", NULL);
  24.399 +      vm_exit_during_initialization("Unable to use shared archive.", "Failed map_region for using -Xshare:on.");
  24.400      } else {
  24.401        FLAG_SET_DEFAULT(UseSharedSpaces, false);
  24.402      }
  24.403 @@ -983,6 +1056,20 @@
  24.404  
  24.405    // Close the mapinfo file
  24.406    mapinfo->close();
  24.407 +
  24.408 +  if (PrintSharedArchiveAndExit) {
  24.409 +    if (PrintSharedDictionary) {
  24.410 +      tty->print_cr("\nShared classes:\n");
  24.411 +      SystemDictionary::print_shared(false);
  24.412 +    }
  24.413 +    if (_archive_loading_failed) {
  24.414 +      tty->print_cr("archive is invalid");
  24.415 +      vm_exit(1);
  24.416 +    } else {
  24.417 +      tty->print_cr("archive is valid");
  24.418 +      vm_exit(0);
  24.419 +    }
  24.420 +  }
  24.421  }
  24.422  
  24.423  // JVM/TI RedefineClasses() support:
    25.1 --- a/src/share/vm/memory/metaspaceShared.hpp	Wed Sep 03 09:24:07 2014 +0200
    25.2 +++ b/src/share/vm/memory/metaspaceShared.hpp	Wed Sep 03 09:25:44 2014 +0200
    25.3 @@ -38,7 +38,10 @@
    25.4    // CDS support
    25.5    static ReservedSpace* _shared_rs;
    25.6    static int _max_alignment;
    25.7 -
    25.8 +  static bool _link_classes_made_progress;
    25.9 +  static bool _check_classes_made_progress;
   25.10 +  static bool _has_error_classes;
   25.11 +  static bool _archive_loading_failed;
   25.12   public:
   25.13    enum {
   25.14      vtbl_list_size = 17, // number of entries in the shared space vtable list.
   25.15 @@ -67,7 +70,11 @@
   25.16      NOT_CDS(return 0);
   25.17    }
   25.18  
   25.19 +  static void prepare_for_dumping() NOT_CDS_RETURN;
   25.20    static void preload_and_dump(TRAPS) NOT_CDS_RETURN;
   25.21 +  static int preload_and_dump(const char * class_list_path,
   25.22 +                              GrowableArray<Klass*>* class_promote_order,
   25.23 +                              TRAPS) NOT_CDS_RETURN;
   25.24  
   25.25    static ReservedSpace* shared_rs() {
   25.26      CDS_ONLY(return _shared_rs);
   25.27 @@ -78,6 +85,9 @@
   25.28      CDS_ONLY(_shared_rs = rs;)
   25.29    }
   25.30  
   25.31 +  static void set_archive_loading_failed() {
   25.32 +    _archive_loading_failed = true;
   25.33 +  }
   25.34    static bool map_shared_spaces(FileMapInfo* mapinfo) NOT_CDS_RETURN_(false);
   25.35    static void initialize_shared_spaces() NOT_CDS_RETURN;
   25.36  
   25.37 @@ -97,5 +107,10 @@
   25.38    static bool remap_shared_readonly_as_readwrite() NOT_CDS_RETURN_(true);
   25.39  
   25.40    static void print_shared_spaces();
   25.41 +
   25.42 +  static bool try_link_class(InstanceKlass* ik, TRAPS);
   25.43 +  static void link_one_shared_class(Klass* obj, TRAPS);
   25.44 +  static void check_one_shared_class(Klass* obj);
   25.45 +  static void link_and_cleanup_shared_classes(TRAPS);
   25.46  };
   25.47  #endif // SHARE_VM_MEMORY_METASPACE_SHARED_HPP
    26.1 --- a/src/share/vm/memory/universe.cpp	Wed Sep 03 09:24:07 2014 +0200
    26.2 +++ b/src/share/vm/memory/universe.cpp	Wed Sep 03 09:25:44 2014 +0200
    26.3 @@ -26,6 +26,9 @@
    26.4  #include "classfile/classLoader.hpp"
    26.5  #include "classfile/classLoaderData.hpp"
    26.6  #include "classfile/javaClasses.hpp"
    26.7 +#if INCLUDE_CDS
    26.8 +#include "classfile/sharedClassUtil.hpp"
    26.9 +#endif
   26.10  #include "classfile/symbolTable.hpp"
   26.11  #include "classfile/systemDictionary.hpp"
   26.12  #include "classfile/vmSymbols.hpp"
   26.13 @@ -34,6 +37,7 @@
   26.14  #include "gc_interface/collectedHeap.inline.hpp"
   26.15  #include "interpreter/interpreter.hpp"
   26.16  #include "memory/cardTableModRefBS.hpp"
   26.17 +#include "memory/filemap.hpp"
   26.18  #include "memory/gcLocker.inline.hpp"
   26.19  #include "memory/genCollectedHeap.hpp"
   26.20  #include "memory/genRemSet.hpp"
   26.21 @@ -238,8 +242,9 @@
   26.22  void initialize_basic_type_klass(Klass* k, TRAPS) {
   26.23    Klass* ok = SystemDictionary::Object_klass();
   26.24    if (UseSharedSpaces) {
   26.25 +    ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   26.26      assert(k->super() == ok, "u3");
   26.27 -    k->restore_unshareable_info(CHECK);
   26.28 +    k->restore_unshareable_info(loader_data, Handle(), CHECK);
   26.29    } else {
   26.30      k->initialize_supers(ok, CHECK);
   26.31    }
   26.32 @@ -665,6 +670,10 @@
   26.33      SymbolTable::create_table();
   26.34      StringTable::create_table();
   26.35      ClassLoader::create_package_info_table();
   26.36 +
   26.37 +    if (DumpSharedSpaces) {
   26.38 +      MetaspaceShared::prepare_for_dumping();
   26.39 +    }
   26.40    }
   26.41  
   26.42    return JNI_OK;
   26.43 @@ -1166,6 +1175,11 @@
   26.44    MemoryService::add_metaspace_memory_pools();
   26.45  
   26.46    MemoryService::set_universe_heap(Universe::_collectedHeap);
   26.47 +#if INCLUDE_CDS
   26.48 +  if (UseSharedSpaces) {
   26.49 +    SharedClassUtil::initialize(CHECK_false);
   26.50 +  }
   26.51 +#endif
   26.52    return true;
   26.53  }
   26.54  
    27.1 --- a/src/share/vm/oops/arrayKlass.cpp	Wed Sep 03 09:24:07 2014 +0200
    27.2 +++ b/src/share/vm/oops/arrayKlass.cpp	Wed Sep 03 09:25:44 2014 +0200
    27.3 @@ -186,8 +186,9 @@
    27.4    set_component_mirror(NULL);
    27.5  }
    27.6  
    27.7 -void ArrayKlass::restore_unshareable_info(TRAPS) {
    27.8 -  Klass::restore_unshareable_info(CHECK);
    27.9 +void ArrayKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
   27.10 +  assert(loader_data == ClassLoaderData::the_null_class_loader_data(), "array classes belong to null loader");
   27.11 +  Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
   27.12    // Klass recreates the component mirror also
   27.13  }
   27.14  
    28.1 --- a/src/share/vm/oops/arrayKlass.hpp	Wed Sep 03 09:24:07 2014 +0200
    28.2 +++ b/src/share/vm/oops/arrayKlass.hpp	Wed Sep 03 09:25:44 2014 +0200
    28.3 @@ -137,7 +137,7 @@
    28.4  
    28.5    // CDS support - remove and restore oops from metadata. Oops are not shared.
    28.6    virtual void remove_unshareable_info();
    28.7 -  virtual void restore_unshareable_info(TRAPS);
    28.8 +  virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
    28.9  
   28.10    // Printing
   28.11    void print_on(outputStream* st) const;
    29.1 --- a/src/share/vm/oops/instanceKlass.cpp	Wed Sep 03 09:24:07 2014 +0200
    29.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Wed Sep 03 09:25:44 2014 +0200
    29.3 @@ -2321,12 +2321,14 @@
    29.4    array_klasses_do(remove_unshareable_in_class);
    29.5  }
    29.6  
    29.7 -void restore_unshareable_in_class(Klass* k, TRAPS) {
    29.8 -  k->restore_unshareable_info(CHECK);
    29.9 +static void restore_unshareable_in_class(Klass* k, TRAPS) {
   29.10 +  // Array classes have null protection domain.
   29.11 +  // --> see ArrayKlass::complete_create_array_klass()
   29.12 +  k->restore_unshareable_info(ClassLoaderData::the_null_class_loader_data(), Handle(), CHECK);
   29.13  }
   29.14  
   29.15 -void InstanceKlass::restore_unshareable_info(TRAPS) {
   29.16 -  Klass::restore_unshareable_info(CHECK);
   29.17 +void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
   29.18 +  Klass::restore_unshareable_info(loader_data, protection_domain, CHECK);
   29.19    instanceKlassHandle ik(THREAD, this);
   29.20  
   29.21    Array<Method*>* methods = ik->methods();
   29.22 @@ -2352,6 +2354,38 @@
   29.23    ik->array_klasses_do(restore_unshareable_in_class, CHECK);
   29.24  }
   29.25  
   29.26 +// returns true IFF is_in_error_state() has been changed as a result of this call.
   29.27 +bool InstanceKlass::check_sharing_error_state() {
   29.28 +  assert(DumpSharedSpaces, "should only be called during dumping");
   29.29 +  bool old_state = is_in_error_state();
   29.30 +
   29.31 +  if (!is_in_error_state()) {
   29.32 +    bool bad = false;
   29.33 +    for (InstanceKlass* sup = java_super(); sup; sup = sup->java_super()) {
   29.34 +      if (sup->is_in_error_state()) {
   29.35 +        bad = true;
   29.36 +        break;
   29.37 +      }
   29.38 +    }
   29.39 +    if (!bad) {
   29.40 +      Array<Klass*>* interfaces = transitive_interfaces();
   29.41 +      for (int i = 0; i < interfaces->length(); i++) {
   29.42 +        Klass* iface = interfaces->at(i);
   29.43 +        if (InstanceKlass::cast(iface)->is_in_error_state()) {
   29.44 +          bad = true;
   29.45 +          break;
   29.46 +        }
   29.47 +      }
   29.48 +    }
   29.49 +
   29.50 +    if (bad) {
   29.51 +      set_in_error_state();
   29.52 +    }
   29.53 +  }
   29.54 +
   29.55 +  return (old_state != is_in_error_state());
   29.56 +}
   29.57 +
   29.58  static void clear_all_breakpoints(Method* m) {
   29.59    m->clear_all_breakpoints();
   29.60  }
    30.1 --- a/src/share/vm/oops/instanceKlass.hpp	Wed Sep 03 09:24:07 2014 +0200
    30.2 +++ b/src/share/vm/oops/instanceKlass.hpp	Wed Sep 03 09:25:44 2014 +0200
    30.3 @@ -1004,6 +1004,13 @@
    30.4  
    30.5    u2 idnum_allocated_count() const      { return _idnum_allocated_count; }
    30.6  
    30.7 +public:
    30.8 +  void set_in_error_state() {
    30.9 +    assert(DumpSharedSpaces, "only call this when dumping archive");
   30.10 +    _init_state = initialization_error;
   30.11 +  }
   30.12 +  bool check_sharing_error_state();
   30.13 +
   30.14  private:
   30.15    // initialization state
   30.16  #ifdef ASSERT
   30.17 @@ -1062,7 +1069,7 @@
   30.18  public:
   30.19    // CDS support - remove and restore oops from metadata. Oops are not shared.
   30.20    virtual void remove_unshareable_info();
   30.21 -  virtual void restore_unshareable_info(TRAPS);
   30.22 +  virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
   30.23  
   30.24    // jvm support
   30.25    jint compute_modifier_flags(TRAPS) const;
    31.1 --- a/src/share/vm/oops/klass.cpp	Wed Sep 03 09:24:07 2014 +0200
    31.2 +++ b/src/share/vm/oops/klass.cpp	Wed Sep 03 09:25:44 2014 +0200
    31.3 @@ -184,6 +184,7 @@
    31.4    // The klass doesn't have any references at this point.
    31.5    clear_modified_oops();
    31.6    clear_accumulated_modified_oops();
    31.7 +  _shared_class_path_index = -1;
    31.8  }
    31.9  
   31.10  jint Klass::array_layout_helper(BasicType etype) {
   31.11 @@ -508,27 +509,25 @@
   31.12    set_class_loader_data(NULL);
   31.13  }
   31.14  
   31.15 -void Klass::restore_unshareable_info(TRAPS) {
   31.16 +void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
   31.17    TRACE_INIT_ID(this);
   31.18    // If an exception happened during CDS restore, some of these fields may already be
   31.19    // set.  We leave the class on the CLD list, even if incomplete so that we don't
   31.20    // modify the CLD list outside a safepoint.
   31.21    if (class_loader_data() == NULL) {
   31.22 -    ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   31.23 -    // Restore class_loader_data to the null class loader data
   31.24 +    // Restore class_loader_data
   31.25      set_class_loader_data(loader_data);
   31.26  
   31.27 -    // Add to null class loader list first before creating the mirror
   31.28 +    // Add to class loader list first before creating the mirror
   31.29      // (same order as class file parsing)
   31.30      loader_data->add_class(this);
   31.31    }
   31.32  
   31.33 -  // Recreate the class mirror.  The protection_domain is always null for
   31.34 -  // boot loader, for now.
   31.35 +  // Recreate the class mirror.
   31.36    // Only recreate it if not present.  A previous attempt to restore may have
   31.37    // gotten an OOM later but keep the mirror if it was created.
   31.38    if (java_mirror() == NULL) {
   31.39 -    java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
   31.40 +    java_lang_Class::create_mirror(this, protection_domain, CHECK);
   31.41    }
   31.42  }
   31.43  
    32.1 --- a/src/share/vm/oops/klass.hpp	Wed Sep 03 09:24:07 2014 +0200
    32.2 +++ b/src/share/vm/oops/klass.hpp	Wed Sep 03 09:25:44 2014 +0200
    32.3 @@ -175,6 +175,16 @@
    32.4    jbyte _modified_oops;             // Card Table Equivalent (YC/CMS support)
    32.5    jbyte _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
    32.6  
    32.7 +private:
    32.8 +  // This is an index into FileMapHeader::_classpath_entry_table[], to
    32.9 +  // associate this class with the JAR file where it's loaded from during
   32.10 +  // dump time. If a class is not loaded from the shared archive, this field is
   32.11 +  // -1.
   32.12 +  jshort _shared_class_path_index;
   32.13 +
   32.14 +  friend class SharedClassUtil;
   32.15 +protected:
   32.16 +
   32.17    // Constructor
   32.18    Klass();
   32.19  
   32.20 @@ -281,6 +291,15 @@
   32.21    void clear_accumulated_modified_oops() { _accumulated_modified_oops = 0; }
   32.22    bool has_accumulated_modified_oops()   { return _accumulated_modified_oops == 1; }
   32.23  
   32.24 +  int shared_classpath_index() const   {
   32.25 +    return _shared_class_path_index;
   32.26 +  };
   32.27 +
   32.28 +  void set_shared_classpath_index(int index) {
   32.29 +    _shared_class_path_index = index;
   32.30 +  };
   32.31 +
   32.32 +
   32.33   protected:                                // internal accessors
   32.34    Klass* subklass_oop() const            { return _subklass; }
   32.35    Klass* next_sibling_oop() const        { return _next_sibling; }
   32.36 @@ -452,7 +471,7 @@
   32.37   public:
   32.38    // CDS support - remove and restore oops from metadata. Oops are not shared.
   32.39    virtual void remove_unshareable_info();
   32.40 -  virtual void restore_unshareable_info(TRAPS);
   32.41 +  virtual void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
   32.42  
   32.43   protected:
   32.44    // computes the subtype relationship
    33.1 --- a/src/share/vm/prims/jvm.cpp	Wed Sep 03 09:24:07 2014 +0200
    33.2 +++ b/src/share/vm/prims/jvm.cpp	Wed Sep 03 09:25:44 2014 +0200
    33.3 @@ -28,6 +28,10 @@
    33.4  #include "classfile/javaClasses.hpp"
    33.5  #include "classfile/symbolTable.hpp"
    33.6  #include "classfile/systemDictionary.hpp"
    33.7 +#if INCLUDE_CDS
    33.8 +#include "classfile/sharedClassUtil.hpp"
    33.9 +#include "classfile/systemDictionaryShared.hpp"
   33.10 +#endif
   33.11  #include "classfile/vmSymbols.hpp"
   33.12  #include "gc_interface/collectedHeap.inline.hpp"
   33.13  #include "interpreter/bytecode.hpp"
   33.14 @@ -996,7 +1000,15 @@
   33.15                                                                h_loader,
   33.16                                                                Handle(),
   33.17                                                                CHECK_NULL);
   33.18 -
   33.19 +#if INCLUDE_CDS
   33.20 +  if (k == NULL) {
   33.21 +    // If the class is not already loaded, try to see if it's in the shared
   33.22 +    // archive for the current classloader (h_loader).
   33.23 +    instanceKlassHandle ik = SystemDictionaryShared::find_or_load_shared_class(
   33.24 +        klass_name, h_loader, CHECK_NULL);
   33.25 +    k = ik();
   33.26 +  }
   33.27 +#endif
   33.28    return (k == NULL) ? NULL :
   33.29              (jclass) JNIHandles::make_local(env, k->java_mirror());
   33.30  JVM_END
    34.1 --- a/src/share/vm/runtime/arguments.cpp	Wed Sep 03 09:24:07 2014 +0200
    34.2 +++ b/src/share/vm/runtime/arguments.cpp	Wed Sep 03 09:25:44 2014 +0200
    34.3 @@ -23,6 +23,7 @@
    34.4   */
    34.5  
    34.6  #include "precompiled.hpp"
    34.7 +#include "classfile/classLoader.hpp"
    34.8  #include "classfile/javaAssertions.hpp"
    34.9  #include "classfile/symbolTable.hpp"
   34.10  #include "compiler/compilerOracle.hpp"
   34.11 @@ -40,6 +41,7 @@
   34.12  #include "services/memTracker.hpp"
   34.13  #include "utilities/defaultStream.hpp"
   34.14  #include "utilities/macros.hpp"
   34.15 +#include "utilities/stringUtils.hpp"
   34.16  #include "utilities/taskqueue.hpp"
   34.17  #ifdef TARGET_OS_FAMILY_linux
   34.18  # include "os_linux.inline.hpp"
   34.19 @@ -1109,11 +1111,11 @@
   34.20  // Conflict: required to use shared spaces (-Xshare:on), but
   34.21  // incompatible command line options were chosen.
   34.22  
   34.23 -static void no_shared_spaces() {
   34.24 +static void no_shared_spaces(const char* message) {
   34.25    if (RequireSharedSpaces) {
   34.26      jio_fprintf(defaultStream::error_stream(),
   34.27        "Class data sharing is inconsistent with other specified options.\n");
   34.28 -    vm_exit_during_initialization("Unable to use shared archive.", NULL);
   34.29 +    vm_exit_during_initialization("Unable to use shared archive.", message);
   34.30    } else {
   34.31      FLAG_SET_DEFAULT(UseSharedSpaces, false);
   34.32    }
   34.33 @@ -1554,7 +1556,7 @@
   34.34    // at link time, or rewrite bytecodes in non-shared methods.
   34.35    if (!DumpSharedSpaces && !RequireSharedSpaces &&
   34.36        (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
   34.37 -    no_shared_spaces();
   34.38 +    no_shared_spaces("COMPILER2 default: -Xshare:auto | off, have to manually setup to on.");
   34.39    }
   34.40  #endif
   34.41  
   34.42 @@ -3243,6 +3245,15 @@
   34.43      }
   34.44    }
   34.45  
   34.46 +  // PrintSharedArchiveAndExit will turn on
   34.47 +  //   -Xshare:on
   34.48 +  //   -XX:+TraceClassPaths
   34.49 +  if (PrintSharedArchiveAndExit) {
   34.50 +    FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
   34.51 +    FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
   34.52 +    FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
   34.53 +  }
   34.54 +
   34.55    // Change the default value for flags  which have different default values
   34.56    // when working with older JDKs.
   34.57  #ifdef LINUX
   34.58 @@ -3251,9 +3262,55 @@
   34.59      FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
   34.60    }
   34.61  #endif // LINUX
   34.62 +  fix_appclasspath();
   34.63    return JNI_OK;
   34.64  }
   34.65  
   34.66 +// Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
   34.67 +//
   34.68 +// This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
   34.69 +// in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
   34.70 +// Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
   34.71 +// path is treated as the current directory.
   34.72 +//
   34.73 +// This causes problems with CDS, which requires that all directories specified in the classpath
   34.74 +// must be empty. In most cases, applications do NOT want to load classes from the current
   34.75 +// directory anyway. Adding -XX:+IgnoreEmptyClassPaths will make these applications' start-up
   34.76 +// scripts compatible with CDS.
   34.77 +void Arguments::fix_appclasspath() {
   34.78 +  if (IgnoreEmptyClassPaths) {
   34.79 +    const char separator = *os::path_separator();
   34.80 +    const char* src = _java_class_path->value();
   34.81 +
   34.82 +    // skip over all the leading empty paths
   34.83 +    while (*src == separator) {
   34.84 +      src ++;
   34.85 +    }
   34.86 +
   34.87 +    char* copy = AllocateHeap(strlen(src) + 1, mtInternal);
   34.88 +    strncpy(copy, src, strlen(src) + 1);
   34.89 +
   34.90 +    // trim all trailing empty paths
   34.91 +    for (char* tail = copy + strlen(copy) - 1; tail >= copy && *tail == separator; tail--) {
   34.92 +      *tail = '\0';
   34.93 +    }
   34.94 +
   34.95 +    char from[3] = {separator, separator, '\0'};
   34.96 +    char to  [2] = {separator, '\0'};
   34.97 +    while (StringUtils::replace_no_expand(copy, from, to) > 0) {
   34.98 +      // Keep replacing "::" -> ":" until we have no more "::" (non-windows)
   34.99 +      // Keep replacing ";;" -> ";" until we have no more ";;" (windows)
  34.100 +    }
  34.101 +
  34.102 +    _java_class_path->set_value(copy);
  34.103 +    FreeHeap(copy); // a copy was made by set_value, so don't need this anymore
  34.104 +  }
  34.105 +
  34.106 +  if (!PrintSharedArchiveAndExit) {
  34.107 +    ClassLoader::trace_class_path("[classpath: ", _java_class_path->value());
  34.108 +  }
  34.109 +}
  34.110 +
  34.111  jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required) {
  34.112    // This must be done after all -D arguments have been processed.
  34.113    scp_p->expand_endorsed();
  34.114 @@ -3424,9 +3481,8 @@
  34.115          "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
  34.116      }
  34.117    } else {
  34.118 -    // UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.
  34.119      if (!UseCompressedOops || !UseCompressedClassPointers) {
  34.120 -      no_shared_spaces();
  34.121 +      no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
  34.122      }
  34.123  #endif
  34.124    }
  34.125 @@ -3684,7 +3740,7 @@
  34.126      FLAG_SET_DEFAULT(UseSharedSpaces, false);
  34.127      FLAG_SET_DEFAULT(PrintSharedSpaces, false);
  34.128    }
  34.129 -  no_shared_spaces();
  34.130 +  no_shared_spaces("CDS Disabled");
  34.131  #endif // INCLUDE_CDS
  34.132  
  34.133    return JNI_OK;
    35.1 --- a/src/share/vm/runtime/arguments.hpp	Wed Sep 03 09:24:07 2014 +0200
    35.2 +++ b/src/share/vm/runtime/arguments.hpp	Wed Sep 03 09:25:44 2014 +0200
    35.3 @@ -577,12 +577,15 @@
    35.4      _meta_index_dir  = meta_index_dir;
    35.5    }
    35.6  
    35.7 -  static char *get_java_home() { return _java_home->value(); }
    35.8 -  static char *get_dll_dir() { return _sun_boot_library_path->value(); }
    35.9 -  static char *get_endorsed_dir() { return _java_endorsed_dirs->value(); }
   35.10 -  static char *get_sysclasspath() { return _sun_boot_class_path->value(); }
   35.11 +  static char* get_java_home() { return _java_home->value(); }
   35.12 +  static char* get_dll_dir() { return _sun_boot_library_path->value(); }
   35.13 +  static char* get_endorsed_dir() { return _java_endorsed_dirs->value(); }
   35.14 +  static char* get_sysclasspath() { return _sun_boot_class_path->value(); }
   35.15    static char* get_meta_index_path() { return _meta_index_path; }
   35.16    static char* get_meta_index_dir()  { return _meta_index_dir;  }
   35.17 +  static char* get_ext_dirs() { return _java_ext_dirs->value(); }
   35.18 +  static char* get_appclasspath() { return _java_class_path->value(); }
   35.19 +  static void  fix_appclasspath();
   35.20  
   35.21    // Operation modi
   35.22    static Mode mode()                        { return _mode; }
    36.1 --- a/src/share/vm/runtime/globals.hpp	Wed Sep 03 09:24:07 2014 +0200
    36.2 +++ b/src/share/vm/runtime/globals.hpp	Wed Sep 03 09:25:44 2014 +0200
    36.3 @@ -2334,6 +2334,12 @@
    36.4    notproduct(bool, TraceScavenge, false,                                    \
    36.5            "Trace scavenge")                                                 \
    36.6                                                                              \
    36.7 +  product(bool, IgnoreEmptyClassPaths, false,                               \
    36.8 +          "Ignore empty path elements in -classpath")                       \
    36.9 +                                                                            \
   36.10 +  product(bool, TraceClassPaths, false,                                     \
   36.11 +          "Trace processing of class paths")                                \
   36.12 +                                                                            \
   36.13    product_rw(bool, TraceClassLoading, false,                                \
   36.14            "Trace all classes loaded")                                       \
   36.15                                                                              \
   36.16 @@ -3780,6 +3786,13 @@
   36.17    product(bool, PrintSharedSpaces, false,                                   \
   36.18            "Print usage of shared spaces")                                   \
   36.19                                                                              \
   36.20 +  product(bool, PrintSharedArchiveAndExit, false,                           \
   36.21 +          "Print shared archive file contents")                             \
   36.22 +                                                                            \
   36.23 +  product(bool, PrintSharedDictionary, false,                               \
   36.24 +          "If PrintSharedArchiveAndExit is true, also print the shared "    \
   36.25 +          "dictionary")                                                     \
   36.26 +                                                                            \
   36.27    product(uintx, SharedReadWriteSize,  NOT_LP64(12*M) LP64_ONLY(16*M),      \
   36.28            "Size of read-write space for metadata (in bytes)")               \
   36.29                                                                              \
   36.30 @@ -3800,6 +3813,10 @@
   36.31            "support JSR 292 (method handles, invokedynamic, "                \
   36.32            "anonymous classes")                                              \
   36.33                                                                              \
   36.34 +  diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false,              \
   36.35 +          "Do not quit -Xshare:dump even if we encounter unverifiable "     \
   36.36 +          "classes. Just exclude them from the shared dictionary.")         \
   36.37 +                                                                            \
   36.38    diagnostic(bool, PrintMethodHandleStubs, false,                           \
   36.39            "Print generated stub code for method handles")                   \
   36.40                                                                              \
   36.41 @@ -3895,9 +3912,19 @@
   36.42    product(bool , AllowNonVirtualCalls, false,                               \
   36.43            "Obey the ACC_SUPER flag and allow invokenonvirtual calls")       \
   36.44                                                                              \
   36.45 +  product(ccstr, DumpLoadedClassList, NULL,                                 \
   36.46 +          "Dump the names all loaded classes, that could be stored into "   \
   36.47 +          "the CDS archive, in the specified file")                         \
   36.48 +                                                                            \
   36.49 +  product(ccstr, SharedClassListFile, NULL,                                 \
   36.50 +          "Override the default CDS class list")                            \
   36.51 +                                                                            \
   36.52    diagnostic(ccstr, SharedArchiveFile, NULL,                                \
   36.53            "Override the default location of the CDS archive file")          \
   36.54                                                                              \
   36.55 +  product(ccstr, ExtraSharedClassListFile, NULL,                            \
   36.56 +          "Extra classlist for building the CDS archive file")              \
   36.57 +                                                                            \
   36.58    experimental(uintx, ArrayAllocatorMallocLimit,                            \
   36.59            SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx),                        \
   36.60            "Allocation less than this value will be allocated "              \
    37.1 --- a/src/share/vm/runtime/javaCalls.cpp	Wed Sep 03 09:24:07 2014 +0200
    37.2 +++ b/src/share/vm/runtime/javaCalls.cpp	Wed Sep 03 09:25:44 2014 +0200
    37.3 @@ -308,6 +308,10 @@
    37.4  }
    37.5  
    37.6  void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {
    37.7 +  // During dumping, Java execution environment is not fully initialized. Also, Java execution
    37.8 +  // may cause undesirable side-effects in the class metadata.
    37.9 +  assert(!DumpSharedSpaces, "must not execute Java bytecodes when dumping");
   37.10 +
   37.11    methodHandle method = *m;
   37.12    JavaThread* thread = (JavaThread*)THREAD;
   37.13    assert(thread->is_Java_thread(), "must be called by a java thread");
    38.1 --- a/src/share/vm/runtime/vmStructs.cpp	Wed Sep 03 09:24:07 2014 +0200
    38.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Wed Sep 03 09:25:44 2014 +0200
    38.3 @@ -320,7 +320,7 @@
    38.4    nonstatic_field(InstanceKlass,               _jni_ids,                                      JNIid*)                                \
    38.5    nonstatic_field(InstanceKlass,               _osr_nmethods_head,                            nmethod*)                              \
    38.6    nonstatic_field(InstanceKlass,               _breakpoints,                                  BreakpointInfo*)                       \
    38.7 -  nonstatic_field(InstanceKlass,               _generic_signature_index,                           u2)                               \
    38.8 +  nonstatic_field(InstanceKlass,               _generic_signature_index,                      u2)                                    \
    38.9    nonstatic_field(InstanceKlass,               _methods_jmethod_ids,                          jmethodID*)                            \
   38.10    volatile_nonstatic_field(InstanceKlass,      _idnum_allocated_count,                        u2)                                    \
   38.11    nonstatic_field(InstanceKlass,               _annotations,                                  Annotations*)                          \
   38.12 @@ -665,6 +665,7 @@
   38.13        static_field(SystemDictionary,            WK_KLASS(StackOverflowError_klass),            Klass*)                               \
   38.14        static_field(SystemDictionary,            WK_KLASS(ProtectionDomain_klass),              Klass*)                               \
   38.15        static_field(SystemDictionary,            WK_KLASS(AccessControlContext_klass),          Klass*)                               \
   38.16 +      static_field(SystemDictionary,            WK_KLASS(SecureClassLoader_klass),             Klass*)                               \
   38.17        static_field(SystemDictionary,            WK_KLASS(Reference_klass),                     Klass*)                               \
   38.18        static_field(SystemDictionary,            WK_KLASS(SoftReference_klass),                 Klass*)                               \
   38.19        static_field(SystemDictionary,            WK_KLASS(WeakReference_klass),                 Klass*)                               \
    39.1 --- a/src/share/vm/utilities/exceptions.cpp	Wed Sep 03 09:24:07 2014 +0200
    39.2 +++ b/src/share/vm/utilities/exceptions.cpp	Wed Sep 03 09:25:44 2014 +0200
    39.3 @@ -85,9 +85,13 @@
    39.4  #endif // ASSERT
    39.5  
    39.6    if (thread->is_VM_thread()
    39.7 -      || thread->is_Compiler_thread() ) {
    39.8 +      || thread->is_Compiler_thread()
    39.9 +      || DumpSharedSpaces ) {
   39.10      // We do not care what kind of exception we get for the vm-thread or a thread which
   39.11      // is compiling.  We just install a dummy exception object
   39.12 +    //
   39.13 +    // We also cannot throw a proper exception when dumping, because we cannot run
   39.14 +    // Java bytecodes now. A dummy exception will suffice.
   39.15      thread->set_pending_exception(Universe::vm_exception(), file, line);
   39.16      return true;
   39.17    }
   39.18 @@ -108,9 +112,13 @@
   39.19    }
   39.20  
   39.21    if (thread->is_VM_thread()
   39.22 -      || thread->is_Compiler_thread() ) {
   39.23 +      || thread->is_Compiler_thread()
   39.24 +      || DumpSharedSpaces ) {
   39.25      // We do not care what kind of exception we get for the vm-thread or a thread which
   39.26      // is compiling.  We just install a dummy exception object
   39.27 +    //
   39.28 +    // We also cannot throw a proper exception when dumping, because we cannot run
   39.29 +    // Java bytecodes now. A dummy exception will suffice.
   39.30      thread->set_pending_exception(Universe::vm_exception(), file, line);
   39.31      return true;
   39.32    }
    40.1 --- a/src/share/vm/utilities/ostream.cpp	Wed Sep 03 09:24:07 2014 +0200
    40.2 +++ b/src/share/vm/utilities/ostream.cpp	Wed Sep 03 09:25:44 2014 +0200
    40.3 @@ -365,6 +365,7 @@
    40.4  xmlStream*   xtty;
    40.5  outputStream* tty;
    40.6  outputStream* gclog_or_tty;
    40.7 +CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
    40.8  extern Mutex* tty_lock;
    40.9  
   40.10  #define EXTRACHARLEN   32
   40.11 @@ -476,7 +477,8 @@
   40.12    return buf;
   40.13  }
   40.14  
   40.15 -// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name
   40.16 +// log_name comes from -XX:LogFile=log_name, -Xloggc:log_name or
   40.17 +// -XX:DumpLoadedClassList=<file_name>
   40.18  // in log_name, %p => pid1234 and
   40.19  //              %t => YYYY-MM-DD_HH-MM-SS
   40.20  static const char* make_log_name(const char* log_name, const char* force_directory) {
   40.21 @@ -1116,6 +1118,16 @@
   40.22      gclog_or_tty = gclog;
   40.23    }
   40.24  
   40.25 +#if INCLUDE_CDS
   40.26 +  // For -XX:DumpLoadedClassList=<file> option
   40.27 +  if (DumpLoadedClassList != NULL) {
   40.28 +    const char* list_name = make_log_name(DumpLoadedClassList, NULL);
   40.29 +    classlist_file = new(ResourceObj::C_HEAP, mtInternal)
   40.30 +                         fileStream(list_name);
   40.31 +    FREE_C_HEAP_ARRAY(char, list_name, mtInternal);
   40.32 +  }
   40.33 +#endif
   40.34 +
   40.35    // If we haven't lazily initialized the logfile yet, do it now,
   40.36    // to avoid the possibility of lazy initialization during a VM
   40.37    // crash, which can affect the stability of the fatal error handler.
   40.38 @@ -1128,6 +1140,11 @@
   40.39    static bool ostream_exit_called = false;
   40.40    if (ostream_exit_called)  return;
   40.41    ostream_exit_called = true;
   40.42 +#if INCLUDE_CDS
   40.43 +  if (classlist_file != NULL) {
   40.44 +    delete classlist_file;
   40.45 +  }
   40.46 +#endif
   40.47    if (gclog_or_tty != tty) {
   40.48        delete gclog_or_tty;
   40.49    }
    41.1 --- a/src/share/vm/utilities/ostream.hpp	Wed Sep 03 09:24:07 2014 +0200
    41.2 +++ b/src/share/vm/utilities/ostream.hpp	Wed Sep 03 09:25:44 2014 +0200
    41.3 @@ -214,6 +214,8 @@
    41.4    void flush();
    41.5  };
    41.6  
    41.7 +CDS_ONLY(extern fileStream*   classlist_file;)
    41.8 +
    41.9  // unlike fileStream, fdStream does unbuffered I/O by calling
   41.10  // open() and write() directly. It is async-safe, but output
   41.11  // from multiple thread may be mixed together. Used by fatal
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/src/share/vm/utilities/stringUtils.cpp	Wed Sep 03 09:25:44 2014 +0200
    42.3 @@ -0,0 +1,43 @@
    42.4 +/*
    42.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    42.7 + *
    42.8 + * This code is free software; you can redistribute it and/or modify it
    42.9 + * under the terms of the GNU General Public License version 2 only, as
   42.10 + * published by the Free Software Foundation.
   42.11 + *
   42.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   42.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   42.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   42.15 + * version 2 for more details (a copy is included in the LICENSE file that
   42.16 + * accompanied this code).
   42.17 + *
   42.18 + * You should have received a copy of the GNU General Public License version
   42.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   42.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   42.21 + *
   42.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   42.23 + * or visit www.oracle.com if you need additional information or have any
   42.24 + * questions.
   42.25 + *
   42.26 + */
   42.27 +
   42.28 +#include "precompiled.hpp"
   42.29 +#include "utilities/stringUtils.hpp"
   42.30 +
   42.31 +int StringUtils::replace_no_expand(char* string, const char* from, const char* to) {
   42.32 +  int replace_count = 0;
   42.33 +  size_t from_len = strlen(from);
   42.34 +  size_t to_len = strlen(to);
   42.35 +  assert(from_len >= to_len, "must not expand input");
   42.36 +
   42.37 +  for (char* dst = string; *dst && (dst = strstr(dst, from)) != NULL;) {
   42.38 +    char* left_over = dst + from_len;
   42.39 +    memmove(dst, to, to_len);                       // does not copy trailing 0 of <to>
   42.40 +    dst += to_len;                                  // skip over the replacement.
   42.41 +    memmove(dst, left_over, strlen(left_over) + 1); // copies the trailing 0 of <left_over>
   42.42 +    ++ replace_count;
   42.43 +  }
   42.44 +
   42.45 +  return replace_count;
   42.46 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/src/share/vm/utilities/stringUtils.hpp	Wed Sep 03 09:25:44 2014 +0200
    43.3 @@ -0,0 +1,42 @@
    43.4 +/*
    43.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    43.7 + *
    43.8 + * This code is free software; you can redistribute it and/or modify it
    43.9 + * under the terms of the GNU General Public License version 2 only, as
   43.10 + * published by the Free Software Foundation.
   43.11 + *
   43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   43.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   43.15 + * version 2 for more details (a copy is included in the LICENSE file that
   43.16 + * accompanied this code).
   43.17 + *
   43.18 + * You should have received a copy of the GNU General Public License version
   43.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   43.21 + *
   43.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   43.23 + * or visit www.oracle.com if you need additional information or have any
   43.24 + * questions.
   43.25 + *
   43.26 + */
   43.27 +
   43.28 +#ifndef SHARE_VM_UTILITIES_STRINGUTILS_HPP
   43.29 +#define SHARE_VM_UTILITIES_STRINGUTILS_HPP
   43.30 +
   43.31 +#include "memory/allocation.hpp"
   43.32 +
   43.33 +class StringUtils : AllStatic {
   43.34 +public:
   43.35 +  // Replace the substring <from> with another string <to>. <to> must be
   43.36 +  // no longer than <from>. The input string is modified in-place.
   43.37 +  //
   43.38 +  // Replacement is done in a single pass left-to-right. So replace_no_expand("aaa", "aa", "a")
   43.39 +  // will result in "aa", not "a".
   43.40 +  //
   43.41 +  // Returns the count of substrings that have been replaced.
   43.42 +  static int replace_no_expand(char* string, const char* from, const char* to);
   43.43 +};
   43.44 +
   43.45 +#endif // SHARE_VM_UTILITIES_STRINGUTILS_HPP
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/test/testlibrary/com/oracle/java/testlibrary/BuildHelper.java	Wed Sep 03 09:25:44 2014 +0200
    44.3 @@ -0,0 +1,106 @@
    44.4 +/*
    44.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    44.7 + *
    44.8 + * This code is free software; you can redistribute it and/or modify it
    44.9 + * under the terms of the GNU General Public License version 2 only, as
   44.10 + * published by the Free Software Foundation.
   44.11 + *
   44.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   44.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   44.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   44.15 + * version 2 for more details (a copy is included in the LICENSE file that
   44.16 + * accompanied this code).
   44.17 + *
   44.18 + * You should have received a copy of the GNU General Public License version
   44.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   44.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   44.21 + *
   44.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   44.23 + * or visit www.oracle.com if you need additional information or have any
   44.24 + * questions.
   44.25 + */
   44.26 +
   44.27 +package com.oracle.java.testlibrary;
   44.28 +
   44.29 +import java.io.File;
   44.30 +import java.io.FileReader;
   44.31 +import java.util.Properties;
   44.32 +
   44.33 +public class BuildHelper {
   44.34 +
   44.35 +    /**
   44.36 +     * Commercial builds should have the BUILD_TYPE set to commercial
   44.37 +     * within the release file, found at the root of the JDK.
   44.38 +     */
   44.39 +    public static boolean isCommercialBuild() throws Exception {
   44.40 +        String buildType = getReleaseProperty("BUILD_TYPE","notFound");
   44.41 +        return buildType.equals("commercial");
   44.42 +    }
   44.43 +
   44.44 +
   44.45 +    /**
   44.46 +     * Return the value for property key, or defaultValue if no property not found.
   44.47 +     * If present, double quotes are trimmed.
   44.48 +     */
   44.49 +    public static String getReleaseProperty(String key, String defaultValue) throws Exception {
   44.50 +        Properties properties = getReleaseProperties();
   44.51 +        String value = properties.getProperty(key, defaultValue);
   44.52 +        return trimDoubleQuotes(value);
   44.53 +    }
   44.54 +
   44.55 +    /**
   44.56 +     * Return the value for property key, or null if no property not found.
   44.57 +     * If present, double quotes are trimmed.
   44.58 +     */
   44.59 +    public static String getReleaseProperty(String key) throws Exception {
   44.60 +        return getReleaseProperty(key, null);
   44.61 +    }
   44.62 +
   44.63 +    /**
   44.64 +     * Get properties from the release file
   44.65 +     */
   44.66 +    public static Properties getReleaseProperties() throws Exception {
   44.67 +        Properties properties = new Properties();
   44.68 +        properties.load(new FileReader(getReleaseFile()));
   44.69 +        return properties;
   44.70 +    }
   44.71 +
   44.72 +    /**
   44.73 +     * Every JDK has a release file in its root.
   44.74 +     * @return A handler to the release file.
   44.75 +     */
   44.76 +    public static File getReleaseFile() throws Exception {
   44.77 +        String jdkPath = getJDKRoot();
   44.78 +        File releaseFile = new File(jdkPath,"release");
   44.79 +        if ( ! releaseFile.canRead() ) {
   44.80 +            throw new Exception("Release file is not readable, or it is absent: " +
   44.81 +                    releaseFile.getCanonicalPath());
   44.82 +        }
   44.83 +        return releaseFile;
   44.84 +    }
   44.85 +
   44.86 +    /**
   44.87 +     * Returns path to the JDK under test.
   44.88 +     * This path is obtained through the test.jdk property, usually set by JTREG.
   44.89 +     */
   44.90 +    public static String getJDKRoot() {
   44.91 +        String jdkPath = System.getProperty("test.jdk");
   44.92 +        if (jdkPath == null) {
   44.93 +            throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
   44.94 +                    + "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
   44.95 +        }
   44.96 +        return jdkPath;
   44.97 +    }
   44.98 +
   44.99 +    /**
  44.100 +     * Trim double quotes from the beginning and the end of the given string.
  44.101 +     * @param original string to trim.
  44.102 +     * @return a new trimmed string.
  44.103 +     */
  44.104 +    public static String trimDoubleQuotes(String original) {
  44.105 +        if (original == null) { return null; }
  44.106 +        String trimmed = original.replaceAll("^\"+|\"+$", "");
  44.107 +        return trimmed;
  44.108 +    }
  44.109 +}

mercurial