< 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 >