src/share/vm/memory/filemap.cpp

Print this page
rev 6841 : mq
rev 6842 : mq

*** 22,34 **** --- 22,39 ---- * */ #include "precompiled.hpp" #include "classfile/classLoader.hpp" + #include "classfile/sharedClassUtil.hpp" #include "classfile/symbolTable.hpp" + #include "classfile/systemDictionaryShared.hpp" #include "classfile/altHashing.hpp" #include "memory/filemap.hpp" + #include "memory/metadataFactory.hpp" + #include "memory/oopFactory.hpp" + #include "oops/objArrayOop.hpp" #include "runtime/arguments.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" #include "services/memTracker.hpp"
*** 40,50 **** #ifndef O_BINARY // if defined (Win32) use binary files. #define O_BINARY 0 // otherwise do nothing. #endif PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC - extern address JVM_FunctionAtStart(); extern address JVM_FunctionAtEnd(); // Complain and stop. All error conditions occurring during the writing of // an archive file should stop the process. Unrecoverable errors during --- 45,54 ----
*** 76,95 **** // If we continue, then disable shared spaces and close the file. void FileMapInfo::fail_continue(const char *msg, ...) { va_list ap; va_start(ap, msg); if (RequireSharedSpaces) { fail(msg, ap); } else { if (PrintSharedSpaces) { tty->print_cr("UseSharedSpaces: %s", msg); } } va_end(ap); UseSharedSpaces = false; ! close(); } // Fill in the fileMapInfo structure with data about this VM instance. // This method copies the vm version info into header_version. If the version is too --- 80,110 ---- // If we continue, then disable shared spaces and close the file. void FileMapInfo::fail_continue(const char *msg, ...) { va_list ap; va_start(ap, msg); + MetaspaceShared::set_archive_loading_failed(); + if (PrintSharedArchiveAndExit && _validating_classpath_entry_table) { + // If we are doing PrintSharedArchiveAndExit and some of the classpath entries + // do not validate, we can still continue "limping" to validate the remaining + // entries. No need to quit. + tty->print("["); + tty->vprint(msg, ap); + tty->print_cr("]"); + } else { if (RequireSharedSpaces) { fail(msg, ap); } else { if (PrintSharedSpaces) { tty->print_cr("UseSharedSpaces: %s", msg); } } + } va_end(ap); UseSharedSpaces = false; ! assert(current_info() != NULL, "singleton must be registered"); ! current_info()->close(); } // Fill in the fileMapInfo structure with data about this VM instance. // This method copies the vm version info into header_version. If the version is too
*** 120,190 **** sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. } } void FileMapInfo::populate_header(size_t alignment) { ! _header._magic = 0xf00baba2; ! _header._version = _current_version; ! _header._alignment = alignment; ! _header._obj_alignment = ObjectAlignmentInBytes; // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's // invoked with. // JVM version string ... changes on each build. ! get_header_version(_header._jvm_ident); ! // Build checks on classpath and jar files ! _header._num_jars = 0; ClassPathEntry *cpe = ClassLoader::classpath_entry(0); - for ( ; cpe != NULL; cpe = cpe->next()) { ! if (cpe->is_jar_file()) { ! if (_header._num_jars >= JVM_SHARED_JARS_MAX) { ! fail_stop("Too many jar files to share.", NULL); } ! ! // Jar file - record timestamp and file size. struct stat st; ! const char *path = cpe->name(); ! if (os::stat(path, &st) != 0) { // If we can't access a jar file in the boot path, then we can't // make assumptions about where classes get loaded from. ! fail_stop("Unable to open jar file %s.", path); } ! _header._jar[_header._num_jars]._timestamp = st.st_mtime; ! _header._jar[_header._num_jars]._filesize = st.st_size; ! _header._num_jars++; } else { ! // If directories appear in boot classpath, they must be empty to ! // avoid having to verify each individual class file. ! const char* name = ((ClassPathDirEntry*)cpe)->name(); if (!os::dir_is_empty(name)) { ! fail_stop("Boot classpath directory %s is not empty.", name); } } } } // Read the FileMapInfo information from the file. bool FileMapInfo::init_from_file(int fd) { ! ! size_t n = read(fd, &_header, sizeof(struct FileMapHeader)); ! if (n != sizeof(struct FileMapHeader)) { fail_continue("Unable to read the file header."); return false; } ! if (_header._version != current_version()) { fail_continue("The shared archive file has the wrong version."); return false; } _file_offset = (long)n; return true; } // Read the FileMapInfo information from the file. --- 135,339 ---- sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. } } + FileMapInfo::FileMapInfo() { + assert(_current_info == NULL, "must be singleton"); // not thread safe + _current_info = this; + memset(this, 0, sizeof(FileMapInfo)); + _file_offset = 0; + _file_open = false; + _header = SharedClassUtil::allocate_file_map_header(); + _header->_version = _invalid_version; + } + + FileMapInfo::~FileMapInfo() { + assert(_current_info == this, "must be singleton"); // not thread safe + _current_info = NULL; + } + void FileMapInfo::populate_header(size_t alignment) { ! _header->populate(this, alignment); ! } ! ! size_t FileMapInfo::FileMapHeader::data_size() { ! return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase); ! } ! ! void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) { ! _magic = 0xf00baba2; ! _version = _current_version; ! _alignment = alignment; ! _obj_alignment = ObjectAlignmentInBytes; ! _classpath_entry_table_size = mapinfo->_classpath_entry_table_size; ! _classpath_entry_table = mapinfo->_classpath_entry_table; ! _classpath_entry_size = mapinfo->_classpath_entry_size; // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's // invoked with. // JVM version string ... changes on each build. ! get_header_version(_jvm_ident); ! } ! ! void FileMapInfo::allocate_classpath_entry_table() { ! int bytes = 0; ! int count = 0; ! char* strptr = NULL; ! char* strptr_max = NULL; ! Thread* THREAD = Thread::current(); ! ! ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); ! size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); ! for (int pass=0; pass<2; pass++) { ClassPathEntry *cpe = ClassLoader::classpath_entry(0); ! for (int cur_entry = 0 ; cpe != NULL; cpe = cpe->next(), cur_entry++) { ! const char *name = cpe->name(); ! int name_bytes = (int)(strlen(name) + 1); ! ! if (pass == 0) { ! count ++; ! bytes += (int)entry_size; ! bytes += name_bytes; ! if (TraceClassPaths || (TraceClassLoading && Verbose)) { ! tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name); } ! } else { ! SharedClassPathEntry* ent = shared_classpath(cur_entry); ! if (cpe->is_jar_file()) { struct stat st; ! if (os::stat(name, &st) != 0) { ! // The file/dir must exist, or else it would not have been added ! // into ClassLoader::classpath_entry(). ! // // If we can't access a jar file in the boot path, then we can't // make assumptions about where classes get loaded from. ! FileMapInfo::fail_stop("Unable to open jar file %s.", name); } ! ! EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. ! SharedClassUtil::update_shared_classpath(cpe, ent, st.st_mtime, st.st_size, THREAD); } else { + ent->_filesize = -1; + if (!os::dir_is_empty(name)) { + ClassLoader::exit_with_path_failure("Cannot have non-empty directory in archived classpaths", name); + } + } + ent->_name = strptr; + if (strptr + name_bytes <= strptr_max) { + strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0. + strptr += name_bytes; + } else { + assert(0, "miscalculated buffer size"); + } + } + } + + if (pass == 0) { + EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. + Array<u8>* arr = MetadataFactory::new_array<u8>(loader_data, (bytes + 7)/8, THREAD); + strptr = (char*)(arr->data()); + strptr_max = strptr + bytes; + SharedClassPathEntry* table = (SharedClassPathEntry*)strptr; + strptr += entry_size * count; ! _classpath_entry_table_size = count; ! _classpath_entry_table = table; ! _classpath_entry_size = entry_size; ! } ! } ! } ! ! bool FileMapInfo::validate_classpath_entry_table() { ! _validating_classpath_entry_table = true; ! ! int count = _header->_classpath_entry_table_size; ! ! _classpath_entry_table = _header->_classpath_entry_table; ! _classpath_entry_size = _header->_classpath_entry_size; ! ! for (int i=0; i<count; i++) { ! SharedClassPathEntry* ent = shared_classpath(i); ! struct stat st; ! const char* name = ent->_name; ! bool ok = true; ! if (TraceClassPaths || (TraceClassLoading && Verbose)) { ! tty->print_cr("[Checking shared classpath entry: %s]", name); ! } ! if (os::stat(name, &st) != 0) { ! fail_continue("Required classpath entry does not exist: %s", name); ! ok = false; ! } else if (ent->is_dir()) { if (!os::dir_is_empty(name)) { ! fail_continue("directory is not empty: %s", name); ! ok = false; ! } ! } else { ! if (ent->_timestamp != st.st_mtime || ! ent->_filesize != st.st_size) { ! ok = false; ! if (PrintSharedArchiveAndExit) { ! fail_continue(ent->_timestamp != st.st_mtime ? ! "Timestamp mismatch" : ! "File size mismatch"); ! } else { ! fail_continue("A jar file is not the one used while building" ! " the shared archive file: %s", name); ! } } } + if (ok) { + if (TraceClassPaths || (TraceClassLoading && Verbose)) { + tty->print_cr("[ok]"); } + } else if (!PrintSharedArchiveAndExit) { + _validating_classpath_entry_table = false; + return false; + } + } + + _classpath_entry_table_size = _header->_classpath_entry_table_size; + _validating_classpath_entry_table = false; + return true; } // Read the FileMapInfo information from the file. bool FileMapInfo::init_from_file(int fd) { ! size_t sz = _header->data_size(); ! char* addr = _header->data(); ! size_t n = os::read(fd, addr, (unsigned int)sz); ! if (n != sz) { fail_continue("Unable to read the file header."); return false; } ! if (_header->_version != current_version()) { fail_continue("The shared archive file has the wrong version."); return false; } _file_offset = (long)n; + + size_t info_size = _header->_paths_misc_info_size; + _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass); + if (_paths_misc_info == NULL) { + fail_continue("Unable to read the file header."); + return false; + } + n = os::read(fd, _paths_misc_info, (unsigned int)info_size); + if (n != info_size) { + fail_continue("Unable to read the shared path info header."); + FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass); + _paths_misc_info = NULL; + return false; + } + + _file_offset += (long)n; return true; } // Read the FileMapInfo information from the file.
*** 235,265 **** // Write the header to the file, seek to the next allocation boundary. void FileMapInfo::write_header() { ! write_bytes_aligned(&_header, sizeof(FileMapHeader)); } // Dump shared spaces to file. void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) { align_file_position(); size_t used = space->used_bytes_slow(Metaspace::NonClassType); size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType); ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; write_region(i, (char*)space->bottom(), used, capacity, read_only, false); } // Dump region to file. void FileMapInfo::write_region(int region, char* base, size_t size, size_t capacity, bool read_only, bool allow_exec) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[region]; if (_file_open) { guarantee(si->_file_offset == _file_offset, "file offset mismatch."); if (PrintSharedSpaces) { tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT --- 384,423 ---- // Write the header to the file, seek to the next allocation boundary. void FileMapInfo::write_header() { ! int info_size = ClassLoader::get_shared_paths_misc_info_size(); ! ! _header->_paths_misc_info_size = info_size; ! ! align_file_position(); ! size_t sz = _header->data_size(); ! char* addr = _header->data(); ! write_bytes(addr, (int)sz); // skip the C++ vtable ! write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size); ! align_file_position(); } // Dump shared spaces to file. void FileMapInfo::write_space(int i, Metaspace* space, bool read_only) { align_file_position(); size_t used = space->used_bytes_slow(Metaspace::NonClassType); size_t capacity = space->capacity_bytes_slow(Metaspace::NonClassType); ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; write_region(i, (char*)space->bottom(), used, capacity, read_only, false); } // Dump region to file. void FileMapInfo::write_region(int region, char* base, size_t size, size_t capacity, bool read_only, bool allow_exec) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[region]; if (_file_open) { guarantee(si->_file_offset == _file_offset, "file offset mismatch."); if (PrintSharedSpaces) { tty->print_cr("Shared file region %d: 0x%6x bytes, addr " INTPTR_FORMAT
*** 337,347 **** // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private. bool FileMapInfo::remap_shared_readonly_as_readwrite() { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; if (!si->_read_only) { // the space is already readwrite so we are done return true; } size_t used = si->_used; --- 495,505 ---- // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private. bool FileMapInfo::remap_shared_readonly_as_readwrite() { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0]; if (!si->_read_only) { // the space is already readwrite so we are done return true; } size_t used = si->_used;
*** 365,375 **** return true; } // Map the whole region at once, assumed to be allocated contiguously. ReservedSpace FileMapInfo::reserve_shared_memory() { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0]; char* requested_addr = si->_base; size_t size = FileMapInfo::shared_spaces_size(); // Reserve the space first, then map otherwise map will go right over some --- 523,533 ---- return true; } // Map the whole region at once, assumed to be allocated contiguously. ReservedSpace FileMapInfo::reserve_shared_memory() { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[0]; char* requested_addr = si->_base; size_t size = FileMapInfo::shared_spaces_size(); // Reserve the space first, then map otherwise map will go right over some
*** 387,397 **** // Memory map a region in the address space. static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"}; char* FileMapInfo::map_region(int i) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; size_t used = si->_used; size_t alignment = os::vm_allocation_granularity(); size_t size = align_size_up(used, alignment); char *requested_addr = si->_base; --- 545,555 ---- // Memory map a region in the address space. static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode"}; char* FileMapInfo::map_region(int i) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; size_t used = si->_used; size_t alignment = os::vm_allocation_granularity(); size_t size = align_size_up(used, alignment); char *requested_addr = si->_base;
*** 413,423 **** // Unmap a memory region in the address space. void FileMapInfo::unmap_region(int i) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; size_t used = si->_used; size_t size = align_size_up(used, os::vm_allocation_granularity()); if (!os::unmap_memory(si->_base, size)) { fail_stop("Unable to unmap shared space."); } --- 571,581 ---- // Unmap a memory region in the address space. void FileMapInfo::unmap_region(int i) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; size_t used = si->_used; size_t size = align_size_up(used, os::vm_allocation_granularity()); if (!os::unmap_memory(si->_base, size)) { fail_stop("Unable to unmap shared space."); }
*** 430,445 **** } } FileMapInfo* FileMapInfo::_current_info = NULL; ! // Open the shared archive file, read and validate the header // information (version, boot classpath, etc.). If initialization // fails, shared spaces are disabled and the file is closed. [See // fail_continue.] bool FileMapInfo::initialize() { assert(UseSharedSpaces, "UseSharedSpaces expected."); if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { fail_continue("Tool agent requires sharing to be disabled."); --- 588,612 ---- } } FileMapInfo* FileMapInfo::_current_info = NULL; ! SharedClassPathEntry* FileMapInfo::_classpath_entry_table = NULL; ! int FileMapInfo::_classpath_entry_table_size = 0; ! size_t FileMapInfo::_classpath_entry_size = 0x1234baad; ! bool FileMapInfo::_validating_classpath_entry_table = false; // Open the shared archive file, read and validate the header // information (version, boot classpath, etc.). If initialization // fails, shared spaces are disabled and the file is closed. [See // fail_continue.] + // + // Validation of the archive is done in two steps: + // + // [1] validate_header() - done here. This checks the header, including _paths_misc_info. + // [2] validate_classpath_entry_table - this is done later, because the table is in the RW + // region of the archive, which is not mapped yet. bool FileMapInfo::initialize() { assert(UseSharedSpaces, "UseSharedSpaces expected."); if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { fail_continue("Tool agent requires sharing to be disabled.");
*** 449,565 **** if (!open_for_read()) { return false; } init_from_file(_fd); ! if (!validate()) { return false; } ! SharedReadOnlySize = _header._space[0]._capacity; ! SharedReadWriteSize = _header._space[1]._capacity; ! SharedMiscDataSize = _header._space[2]._capacity; ! SharedMiscCodeSize = _header._space[3]._capacity; return true; } ! ! bool FileMapInfo::validate() { ! if (_header._version != current_version()) { ! fail_continue("The shared archive file is the wrong version."); return false; } ! if (_header._magic != (int)0xf00baba2) { ! fail_continue("The shared archive file has a bad magic number."); return false; } char header_version[JVM_IDENT_MAX]; get_header_version(header_version); ! if (strncmp(_header._jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { ! fail_continue("The shared archive file was created by a different" ! " version or build of HotSpot."); ! return false; } ! if (_header._obj_alignment != ObjectAlignmentInBytes) { ! fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" ! " does not equal the current ObjectAlignmentInBytes of %d.", ! _header._obj_alignment, ObjectAlignmentInBytes); return false; } ! ! // Cannot verify interpreter yet, as it can only be created after the GC ! // heap has been initialized. ! ! if (_header._num_jars >= JVM_SHARED_JARS_MAX) { ! fail_continue("Too many jar files to share."); return false; } ! // Build checks on classpath and jar files ! int num_jars_now = 0; ! ClassPathEntry *cpe = ClassLoader::classpath_entry(0); ! for ( ; cpe != NULL; cpe = cpe->next()) { ! if (cpe->is_jar_file()) { ! if (num_jars_now < _header._num_jars) { ! // Jar file - verify timestamp and file size. ! struct stat st; ! const char *path = cpe->name(); ! if (os::stat(path, &st) != 0) { ! fail_continue("Unable to open jar file %s.", path); ! return false; } - if (_header._jar[num_jars_now]._timestamp != st.st_mtime || - _header._jar[num_jars_now]._filesize != st.st_size) { - fail_continue("A jar file is not the one used while building" - " the shared archive file."); - return false; } } - ++num_jars_now; - } else { ! // If directories appear in boot classpath, they must be empty to ! // avoid having to verify each individual class file. ! const char* name = ((ClassPathDirEntry*)cpe)->name(); ! if (!os::dir_is_empty(name)) { ! fail_continue("Boot classpath directory %s is not empty.", name); ! return false; ! } } ! } ! if (num_jars_now < _header._num_jars) { ! fail_continue("The number of jar files in the boot classpath is" ! " less than the number the shared archive was created with."); ! return false; ! } ! ! return true; } // The following method is provided to see whether a given pointer // falls in the mapped shared space. // Param: // p, The given pointer // Return: // True if the p is within the mapped shared space, otherwise, false. bool FileMapInfo::is_in_shared_space(const void* p) { for (int i = 0; i < MetaspaceShared::n_regions; i++) { ! if (p >= _header._space[i]._base && ! p < _header._space[i]._base + _header._space[i]._used) { return true; } } return false; } void FileMapInfo::print_shared_spaces() { gclog_or_tty->print_cr("Shared Spaces:"); for (int i = 0; i < MetaspaceShared::n_regions; i++) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT, shared_region_name[i], si->_base, si->_base + si->_used); } } --- 616,706 ---- if (!open_for_read()) { return false; } init_from_file(_fd); ! if (!validate_header()) { return false; } ! SharedReadOnlySize = _header->_space[0]._capacity; ! SharedReadWriteSize = _header->_space[1]._capacity; ! SharedMiscDataSize = _header->_space[2]._capacity; ! SharedMiscCodeSize = _header->_space[3]._capacity; return true; } ! bool FileMapInfo::FileMapHeader::validate() { ! if (_version != current_version()) { ! FileMapInfo::fail_continue("The shared archive file is the wrong version."); return false; } ! if (_magic != (int)0xf00baba2) { ! FileMapInfo::fail_continue("The shared archive file has a bad magic number."); return false; } char header_version[JVM_IDENT_MAX]; get_header_version(header_version); ! if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { ! if (TraceClassPaths) { ! tty->print_cr("Expected: %s", header_version); ! tty->print_cr("Actual: %s", _jvm_ident); } ! FileMapInfo::fail_continue("The shared archive file was created by a different" ! " version or build of HotSpot"); return false; } ! if (_obj_alignment != ObjectAlignmentInBytes) { ! FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" ! " does not equal the current ObjectAlignmentInBytes of %d.", ! _obj_alignment, ObjectAlignmentInBytes); return false; } ! return true; ! } ! bool FileMapInfo::validate_header() { ! bool status = _header->validate(); ! if (status) { ! if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) { ! if (!PrintSharedArchiveAndExit) { ! fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)"); ! status = false; } } } ! if (_paths_misc_info != NULL) { ! FREE_C_HEAP_ARRAY(char, _paths_misc_info, mtClass); ! _paths_misc_info = NULL; } ! return status; } // The following method is provided to see whether a given pointer // falls in the mapped shared space. // Param: // p, The given pointer // Return: // True if the p is within the mapped shared space, otherwise, false. bool FileMapInfo::is_in_shared_space(const void* p) { for (int i = 0; i < MetaspaceShared::n_regions; i++) { ! if (p >= _header->_space[i]._base && ! p < _header->_space[i]._base + _header->_space[i]._used) { return true; } } return false; } void FileMapInfo::print_shared_spaces() { gclog_or_tty->print_cr("Shared Spaces:"); for (int i = 0; i < MetaspaceShared::n_regions; i++) { ! struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i]; gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT, shared_region_name[i], si->_base, si->_base + si->_used); } }
*** 568,580 **** void FileMapInfo::stop_sharing_and_unmap(const char* msg) { FileMapInfo *map_info = FileMapInfo::current_info(); if (map_info) { map_info->fail_continue(msg); for (int i = 0; i < MetaspaceShared::n_regions; i++) { ! if (map_info->_header._space[i]._base != NULL) { map_info->unmap_region(i); ! map_info->_header._space[i]._base = NULL; } } } else if (DumpSharedSpaces) { fail_stop(msg, NULL); } --- 709,721 ---- void FileMapInfo::stop_sharing_and_unmap(const char* msg) { FileMapInfo *map_info = FileMapInfo::current_info(); if (map_info) { map_info->fail_continue(msg); for (int i = 0; i < MetaspaceShared::n_regions; i++) { ! if (map_info->_header->_space[i]._base != NULL) { map_info->unmap_region(i); ! map_info->_header->_space[i]._base = NULL; } } } else if (DumpSharedSpaces) { fail_stop(msg, NULL); }