< prev index next >

src/share/vm/memory/filemap.cpp

Print this page

*** 34,43 **** --- 34,45 ---- #endif #include "logging/log.hpp" #include "logging/logMessage.hpp" #include "memory/filemap.hpp" #include "memory/metadataFactory.hpp" + #include "memory/metaspaceClosure.hpp" + #include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "oops/objArrayOop.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/java.hpp"
*** 190,307 **** // 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++) { - // Process the modular java runtime image first - ClassPathEntry* jrt_entry = ClassLoader::get_jrt_entry(); - assert(jrt_entry != NULL, - "No modular java runtime image present when allocating the CDS classpath entry table"); - const char *name = jrt_entry->name(); - int name_bytes = (int)(strlen(name) + 1); - if (pass == 0) { - count++; - bytes += (int)entry_size; - bytes += name_bytes; - log_info(class, path)("add main shared path for modular java runtime image %s", name); - } else { - // The java runtime image is always in slot 0 on the shared class path. - SharedClassPathEntry* ent = shared_classpath(0); struct stat st; if (os::stat(name, &st) == 0) { ! ent->_timestamp = st.st_mtime; ! ent->_filesize = st.st_size; } - if (ent->_filesize == 0) { - // unknown - ent->_filesize = -2; - } - ent->_name = strptr; - assert(strptr + name_bytes <= strptr_max, "miscalculated buffer size"); - strncpy(strptr, name, (size_t)name_bytes); // name_bytes includes trailing 0. - strptr += name_bytes; - } - - // Walk the appended entries, which includes the entries added for the classpath. - ClassPathEntry *cpe = ClassLoader::classpath_entry(1); - - // Since the java runtime image is always in slot 0 on the shared class path, the - // appended entries are started at slot 1 immediately after. - for (int cur_entry = 1 ; cpe != NULL; cpe = cpe->next(), cur_entry++) { - const char *name = cpe->name(); - int name_bytes = (int)(strlen(name) + 1); - assert(!cpe->is_jrt(), "A modular java runtime image is present on the list of appended entries"); - - if (pass == 0) { - count ++; - bytes += (int)entry_size; - bytes += name_bytes; - log_info(class, path)("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 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 { struct stat st; ! if (os::stat(name, &st) == 0) { ! if ((st.st_mode & S_IFMT) == S_IFDIR) { if (!os::dir_is_empty(name)) { ! ClassLoader::exit_with_path_failure( ! "Cannot have non-empty directory in archived classpaths", name); ! } ! ent->_filesize = -1; ! } ! } ! if (ent->_filesize == 0) { ! // unknown ! ent->_filesize = -2; ! } } ! 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() { --- 192,292 ---- // JVM version string ... changes on each build. get_header_version(_jvm_ident); } ! void SharedClassPathEntry::init(const char* name, TRAPS) { ! _timestamp = 0; ! _filesize = 0; struct stat st; if (os::stat(name, &st) == 0) { ! if ((st.st_mode & S_IFMT) == S_IFDIR) { ! if (!os::dir_is_empty(name)) { ! ClassLoader::exit_with_path_failure( ! "Cannot have non-empty directory in archived classpaths", name); ! } ! _is_dir = true; ! } else { ! _is_dir = false; ! _timestamp = st.st_mtime; ! _filesize = st.st_size; } } else { // The file/dir must exist, or 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 file %s.", name); } ! size_t len = strlen(name) + 1; ! _name = MetadataFactory::new_array<char>(ClassLoaderData::the_null_class_loader_data(), (int)len, THREAD); ! strcpy(_name->data(), name); ! } ! ! bool SharedClassPathEntry::validate() { struct stat st; ! const char* name = this->name(); ! bool ok = true; ! log_info(class, path)("checking shared classpath entry: %s", name); ! if (os::stat(name, &st) != 0) { ! FileMapInfo::fail_continue("Required classpath entry does not exist: %s", name); ! ok = false; ! } else if (is_dir()) { if (!os::dir_is_empty(name)) { ! FileMapInfo::fail_continue("directory is not empty: %s", name); ! ok = false; } ! } else if (is_jar_or_bootimage()) { ! if (_timestamp != st.st_mtime || ! _filesize != st.st_size) { ! ok = false; ! if (PrintSharedArchiveAndExit) { ! FileMapInfo::fail_continue(_timestamp != st.st_mtime ? ! "Timestamp mismatch" : ! "File size mismatch"); } else { ! FileMapInfo::fail_continue("A jar/jimage file is not the one used while building" ! " the shared archive file: %s", name); } } } + return ok; + } ! void SharedClassPathEntry::metaspace_pointers_do(MetaspaceClosure* it) { ! it->push(&_name); ! it->push(&_manifest); ! } ! ! void FileMapInfo::allocate_classpath_entry_table() { ! Thread* THREAD = Thread::current(); ! ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); ! size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??) ! int num_entries = ClassLoader::number_of_classpath_entries(); ! size_t bytes = entry_size * num_entries; ! _classpath_entry_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD); ! _classpath_entry_table_size = num_entries; _classpath_entry_size = entry_size; + + assert(ClassLoader::get_jrt_entry() != NULL, + "No modular java runtime image present when allocating the CDS classpath entry table"); + + for (int i=0; i<num_entries; i++) { + ClassPathEntry *cpe = ClassLoader::classpath_entry(i); + const char* type = ((i == 0) ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir")); + + log_info(class, path)("add main shared path (%s) %s", type, cpe->name()); + SharedClassPathEntry* ent = shared_classpath(i); + ent->init(cpe->name(), THREAD); + + if (i > 0) { // No need to do jimage. + EXCEPTION_MARK; // The following call should never throw, but would exit VM on error. + SharedClassUtil::update_shared_classpath(cpe, ent, THREAD); } } } bool FileMapInfo::validate_classpath_entry_table() {
*** 309,356 **** 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; ! log_info(class, path)("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->is_jar_or_bootimage()) { ! 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/jimage file is not the one used while building" ! " the shared archive file: %s", name); ! } ! } ! } ! if (ok) { log_info(class, path)("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; } --- 294,316 ---- int count = _header->_classpath_entry_table_size; _classpath_entry_table = _header->_classpath_entry_table; _classpath_entry_size = _header->_classpath_entry_size; + _classpath_entry_table_size = _header->_classpath_entry_table_size; for (int i=0; i<count; i++) { ! if (shared_classpath(i)->validate()) { log_info(class, path)("ok"); } else if (!PrintSharedArchiveAndExit) { _validating_classpath_entry_table = false; + _classpath_entry_table = NULL; + _classpath_entry_table_size = 0; return false; } } _validating_classpath_entry_table = false; return true; }
*** 384,394 **** return false; } size_t len = lseek(fd, 0, SEEK_END); struct FileMapInfo::FileMapHeader::space_info* si = ! &_header->_space[MetaspaceShared::mc]; if (si->_file_offset >= len || len - si->_file_offset < si->_used) { fail_continue("The shared archive file has been truncated."); return false; } --- 344,354 ---- return false; } size_t len = lseek(fd, 0, SEEK_END); struct FileMapInfo::FileMapHeader::space_info* si = ! &_header->_space[MetaspaceShared::last_valid_region]; if (si->_file_offset >= len || len - si->_file_offset < si->_used) { fail_continue("The shared archive file has been truncated."); return false; }
*** 463,494 **** 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."); ! log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(6) ! " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(6), region, size, p2i(base), _file_offset); } else { si->_file_offset = _file_offset; } if (MetaspaceShared::is_string_region(region)) { --- 423,442 ---- write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size); align_file_position(); } // Dump region to file. void FileMapInfo::write_region(int region, char* base, size_t size, ! 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."); ! log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08) ! " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08), region, size, p2i(base), _file_offset); } else { si->_file_offset = _file_offset; } if (MetaspaceShared::is_string_region(region)) {
*** 500,510 **** } } else { si->_addr._base = base; } si->_used = size; - si->_capacity = capacity; si->_read_only = read_only; si->_allow_exec = allow_exec; si->_crc = ClassLoader::crc32(0, base, (jint)size); write_bytes_aligned(base, (int)size); } --- 448,457 ----
*** 535,545 **** start = (char*)regions->at(1).start(); size = (char*)regions->at(len - 1).end() - start; } } } ! write_region(i, start, size, size, false, false); } } // Dump bytes to file -- at the current file position. --- 482,492 ---- start = (char*)regions->at(1).start(); size = (char*)regions->at(len - 1).end() - start; } } } ! write_region(i, start, size, false, false); } } // Dump bytes to file -- at the current file position.
*** 603,613 **** // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private. bool FileMapInfo::remap_shared_readonly_as_readwrite() { ! int idx = 0; struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[idx]; if (!si->_read_only) { // the space is already readwrite so we are done return true; } --- 550,560 ---- // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private. bool FileMapInfo::remap_shared_readonly_as_readwrite() { ! int idx = MetaspaceShared::ro; struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[idx]; if (!si->_read_only) { // the space is already readwrite so we are done return true; }
*** 633,646 **** 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 = _header->region_addr(0); ! ! size_t size = FileMapInfo::shared_spaces_size(); // Reserve the space first, then map otherwise map will go right over some // other reserved memory (like the code cache). ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr); if (!rs.is_reserved()) { --- 580,591 ---- return true; } // Map the whole region at once, assumed to be allocated contiguously. ReservedSpace FileMapInfo::reserve_shared_memory() { char* requested_addr = _header->region_addr(0); ! size_t size = FileMapInfo::core_spaces_size(); // Reserve the space first, then map otherwise map will go right over some // other reserved memory (like the code cache). ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr); if (!rs.is_reserved()) {
*** 856,868 **** if (!check) { fail_stop("Mark mismatch while restoring from shared file."); } } 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 --- 801,820 ---- if (!check) { fail_stop("Mark mismatch while restoring from shared file."); } } + void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it) { + it->push(&_classpath_entry_table); + for (int i=0; i<_classpath_entry_table_size; i++) { + shared_classpath(i)->metaspace_pointers_do(it); + } + } + FileMapInfo* FileMapInfo::_current_info = NULL; ! Array<u8>* 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
*** 884,898 **** 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; } char* FileMapInfo::FileMapHeader::region_addr(int idx) { if (MetaspaceShared::is_string_region(idx)) { --- 836,845 ----
*** 995,1007 **** } return false; } ! // Check if a given address is within one of the shared regions (ro, rw, md, mc) bool FileMapInfo::is_in_shared_region(const void* p, int idx) { ! assert((idx >= MetaspaceShared::ro) && (idx <= MetaspaceShared::mc), "invalid region index"); char* base = _header->region_addr(idx); if (p >= base && p < base + _header->_space[idx]._used) { return true; } return false; --- 942,957 ---- } return false; } ! // Check if a given address is within one of the shared regions ( ro, rw, mc or md) bool FileMapInfo::is_in_shared_region(const void* p, int idx) { ! assert(idx == MetaspaceShared::ro || ! idx == MetaspaceShared::rw || ! idx == MetaspaceShared::mc || ! idx == MetaspaceShared::md, "invalid region index"); char* base = _header->region_addr(idx); if (p >= base && p < base + _header->_space[idx]._used) { return true; } return false;
< prev index next >