8238000: Crash in ClassLoader::record_result while dynamic dumping netty

Make a copy of the _shared_path_table for use during dynamic CDS dump.

Reviewed-by: iklam, minqi
This commit is contained in:
Calvin Cheung 2020-03-12 16:05:07 -07:00
parent 0610992a8f
commit 38940d166a
4 changed files with 53 additions and 11 deletions

View file

@ -293,6 +293,23 @@ void SharedClassPathEntry::set_name(const char* name, TRAPS) {
strcpy(_name->data(), name);
}
void SharedClassPathEntry::copy_from(SharedClassPathEntry* ent, ClassLoaderData* loader_data, TRAPS) {
_type = ent->_type;
_timestamp = ent->_timestamp;
_filesize = ent->_filesize;
_from_class_path_attr = ent->_from_class_path_attr;
set_name(ent->name(), THREAD);
if (ent->is_jar() && !ent->is_signed() && ent->manifest() != NULL) {
Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
ent->manifest_size(),
THREAD);
char* p = (char*)(buf->data());
memcpy(p, ent->manifest(), ent->manifest_size());
set_manifest(buf);
}
}
const char* SharedClassPathEntry::name() const {
if (UseSharedSpaces && is_modules_image()) {
// In order to validate the runtime modules image file size against the archived
@ -381,10 +398,26 @@ void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD
num_entries += FileMapInfo::num_non_existent_class_paths();
size_t bytes = entry_size * num_entries;
_table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
_table = MetadataFactory::new_array<u8>(loader_data, (int)bytes, THREAD);
_size = num_entries;
}
// Make a copy of the _shared_path_table for use during dynamic CDS dump.
// It is needed because some Java code continues to execute after dynamic dump has finished.
// However, during dynamic dump, we have modified FileMapInfo::_shared_path_table so
// FileMapInfo::shared_path(i) returns incorrect information in ClassLoader::record_result().
void FileMapInfo::copy_shared_path_table(ClassLoaderData* loader_data, Thread* THREAD) {
size_t entry_size = sizeof(SharedClassPathEntry);
size_t bytes = entry_size * _shared_path_table.size();
_saved_shared_path_table = SharedPathTable(MetadataFactory::new_array<u8>(loader_data, (int)bytes, THREAD),
_shared_path_table.size());
for (int i = 0; i < _shared_path_table.size(); i++) {
_saved_shared_path_table.path_at(i)->copy_from(shared_path(i), loader_data, THREAD);
}
}
void FileMapInfo::allocate_shared_path_table() {
Arguments::assert_is_dumping_archive();
@ -409,6 +442,8 @@ void FileMapInfo::allocate_shared_path_table() {
}
assert(i == _shared_path_table.size(), "number of shared path entry mismatch");
copy_shared_path_table(loader_data, THREAD);
}
int FileMapInfo::add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS) {
@ -937,10 +972,6 @@ bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name,
return true;
}
void FileMapInfo::restore_shared_path_table() {
_shared_path_table = _current_info->header()->shared_path_table();
}
// Read the FileMapInfo information from the file.
bool FileMapInfo::init_from_file(int fd) {
@ -1926,14 +1957,19 @@ void FileMapInfo::assert_mark(bool check) {
}
}
void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it) {
_shared_path_table.metaspace_pointers_do(it);
void FileMapInfo::metaspace_pointers_do(MetaspaceClosure* it, bool use_copy) {
if (use_copy) {
_saved_shared_path_table.metaspace_pointers_do(it);
} else {
_shared_path_table.metaspace_pointers_do(it);
}
}
FileMapInfo* FileMapInfo::_current_info = NULL;
FileMapInfo* FileMapInfo::_dynamic_archive_info = NULL;
bool FileMapInfo::_heap_pointers_need_patching = false;
SharedPathTable FileMapInfo::_shared_path_table;
SharedPathTable FileMapInfo::_saved_shared_path_table;
bool FileMapInfo::_validating_shared_path_table = false;
bool FileMapInfo::_memory_mapping_failed = false;
GrowableArray<const char*>* FileMapInfo::_non_existent_class_paths = NULL;