8316994: Avoid modifying ClassLoader and Module objects during -Xshare:dump

Reviewed-by: matsaave, ccheung
This commit is contained in:
Ioi Lam 2023-09-28 01:47:54 +00:00
parent 83c0e45160
commit 52073b27a3
7 changed files with 33 additions and 40 deletions

View File

@ -26,6 +26,7 @@
#include "cds/archiveHeapWriter.hpp"
#include "cds/filemap.hpp"
#include "cds/heapShared.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/oopFactory.hpp"
@ -317,6 +318,12 @@ size_t ArchiveHeapWriter::get_filler_size_at(address buffered_addr) {
}
}
template <typename T>
void update_buffered_object_field(address buffered_obj, int field_offset, T value) {
T* field_addr = cast_to_oop(buffered_obj)->field_addr<T>(field_offset);
*field_addr = value;
}
size_t ArchiveHeapWriter::copy_one_source_obj_to_buffer(oop src_obj) {
assert(!is_too_large_to_archive(src_obj), "already checked");
size_t byte_size = src_obj->size() * HeapWordSize;
@ -342,6 +349,20 @@ size_t ArchiveHeapWriter::copy_one_source_obj_to_buffer(oop src_obj) {
assert(is_object_aligned(byte_size), "sanity");
memcpy(to, from, byte_size);
// These native pointers will be restored explicitly at run time.
if (java_lang_Module::is_instance(src_obj)) {
update_buffered_object_field<ModuleEntry*>(to, java_lang_Module::module_entry_offset(), nullptr);
} else if (java_lang_ClassLoader::is_instance(src_obj)) {
#ifdef ASSERT
// We only archive these loaders
if (src_obj != SystemDictionary::java_platform_loader() &&
src_obj != SystemDictionary::java_system_loader()) {
assert(src_obj->klass()->name()->equals("jdk/internal/loader/ClassLoaders$BootClassLoader"), "must be");
}
#endif
update_buffered_object_field<ClassLoaderData*>(to, java_lang_ClassLoader::loader_data_offset(), nullptr);
}
size_t buffered_obj_offset = _buffer_used;
_buffer_used = new_used;

View File

@ -135,8 +135,6 @@ OopHandle HeapShared::_roots;
OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
MetaspaceObjToOopHandleTable* HeapShared::_scratch_java_mirror_table = nullptr;
MetaspaceObjToOopHandleTable* HeapShared::_scratch_references_table = nullptr;
ClassLoaderData* HeapShared::_saved_java_platform_loader_data = nullptr;
ClassLoaderData* HeapShared::_saved_java_system_loader_data = nullptr;
static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], InstanceKlass* ik) {
for (int i = 0; fields[i].valid(); i++) {
@ -295,34 +293,14 @@ bool HeapShared::archive_object(oop obj) {
p2i(obj), obj->klass()->external_name());
}
if (java_lang_Module::is_instance(obj)) {
if (Modules::check_module_oop(obj)) {
if (java_lang_Module::is_instance(obj) && Modules::check_archived_module_oop(obj)) {
Modules::update_oops_in_archived_module(obj, append_root(obj));
}
java_lang_Module::set_module_entry(obj, nullptr);
} else if (java_lang_ClassLoader::is_instance(obj)) {
// class_data will be restored explicitly at run time and after dumptime
guarantee(obj == SystemDictionary::java_platform_loader() ||
obj == SystemDictionary::java_system_loader() ||
java_lang_ClassLoader::loader_data(obj) == nullptr, "must be");
if (obj == SystemDictionary::java_platform_loader()) {
_saved_java_platform_loader_data = java_lang_ClassLoader::loader_data_acquire(SystemDictionary::java_platform_loader());
} else if (obj == SystemDictionary::java_system_loader()) {
_saved_java_system_loader_data = java_lang_ClassLoader::loader_data_acquire(SystemDictionary::java_system_loader());
}
java_lang_ClassLoader::release_set_loader_data(obj, nullptr);
}
return true;
}
}
void HeapShared::restore_loader_data() {
log_info(cds)("Restoring java platform and system loaders");
java_lang_ClassLoader::release_set_loader_data(SystemDictionary::java_platform_loader(), _saved_java_platform_loader_data);
java_lang_ClassLoader::release_set_loader_data(SystemDictionary::java_system_loader(), _saved_java_system_loader_data);
}
class MetaspaceObjToOopHandleTable: public ResourceHashtable<MetaspaceObj*, OopHandle,
36137, // prime number
AnyObj::C_HEAP,

View File

@ -283,9 +283,6 @@ private:
static MetaspaceObjToOopHandleTable* _scratch_java_mirror_table;
static MetaspaceObjToOopHandleTable* _scratch_references_table;
static ClassLoaderData* _saved_java_platform_loader_data;
static ClassLoaderData* _saved_java_system_loader_data;
static void init_seen_objects_table() {
assert(_seen_objects_table == nullptr, "must be");
_seen_objects_table = new (mtClass)SeenObjectsTable();
@ -401,7 +398,6 @@ private:
static objArrayOop scratch_resolved_references(ConstantPool* src);
static void add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) NOT_CDS_JAVA_HEAP_RETURN;
static void init_scratch_objects(TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
static void restore_loader_data() NOT_CDS_JAVA_HEAP_RETURN;
static bool is_heap_region(int idx) {
CDS_JAVA_HEAP_ONLY(return (idx == MetaspaceShared::hp);)
NOT_CDS_JAVA_HEAP_RETURN_(false);

View File

@ -663,13 +663,6 @@ void MetaspaceShared::preload_and_dump() {
MetaspaceShared::unrecoverable_writing_error("VM exits due to exception, use -Xlog:cds,exceptions=trace for detail");
}
}
#if INCLUDE_CDS_JAVA_HEAP
// Restore the java loaders that were cleared at dump time
if (use_full_module_graph()) {
HeapShared::restore_loader_data();
}
#endif
}
#if INCLUDE_CDS_JAVA_HEAP && defined(_LP64)

View File

@ -852,6 +852,9 @@ class java_lang_Module {
static oop loader(oop module);
static void set_loader(oop module, oop value);
// CDS
static int module_entry_offset() { return _module_entry_offset; }
static oop name(oop module);
static void set_name(oop module, oop value);
@ -1465,7 +1468,9 @@ class java_lang_ClassLoader : AllStatic {
static void compute_offsets();
public:
// Support for CDS
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
static int loader_data_offset() { return _loader_data_offset; }
static ClassLoaderData* loader_data_acquire(oop loader);
static ClassLoaderData* loader_data(oop loader);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -483,7 +483,7 @@ static bool _seen_system_unnamed_module = false;
// Validate the states of an java.lang.Module oop to be archived.
//
// Returns true iff the oop has an archived ModuleEntry.
bool Modules::check_module_oop(oop orig_module_obj) {
bool Modules::check_archived_module_oop(oop orig_module_obj) {
assert(DumpSharedSpaces, "must be");
assert(MetaspaceShared::use_full_module_graph(), "must be");
assert(java_lang_Module::is_instance(orig_module_obj), "must be");
@ -544,7 +544,7 @@ bool Modules::check_module_oop(oop orig_module_obj) {
void Modules::update_oops_in_archived_module(oop orig_module_obj, int archived_module_root_index) {
// This java.lang.Module oop must have an archived ModuleEntry
assert(check_module_oop(orig_module_obj) == true, "sanity");
assert(check_archived_module_oop(orig_module_obj) == true, "sanity");
// We remember the oop inside the ModuleEntry::_archived_module_index. At runtime, we use
// this index to reinitialize the ModuleEntry inside ModuleEntry::restore_archived_oops().

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -53,7 +53,7 @@ public:
static void define_module(Handle module, jboolean is_open, jstring version,
jstring location, jobjectArray packages, TRAPS);
static bool check_module_oop(oop orig_module_obj) NOT_CDS_JAVA_HEAP_RETURN_(false);
static bool check_archived_module_oop(oop orig_module_obj) NOT_CDS_JAVA_HEAP_RETURN_(false);
static void update_oops_in_archived_module(oop orig_module_obj, int archived_module_root_index)
NOT_CDS_JAVA_HEAP_RETURN;
static void define_archived_modules(Handle h_platform_loader, Handle h_system_loader,