Wed, 03 Sep 2014 09:25:44 +0200
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(×tamp) || !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 +}