8343493: Perform module checks during MetaspaceShared::map_archives()

Reviewed-by: ccheung, matsaave
This commit is contained in:
Ioi Lam 2024-11-07 18:53:22 +00:00
parent ccda8159f6
commit fac89f471c
7 changed files with 84 additions and 15 deletions

View File

@ -320,9 +320,8 @@ void WriteClosure::do_ptr(void** p) {
void ReadClosure::do_ptr(void** p) {
assert(*p == nullptr, "initializing previous initialized pointer.");
intptr_t obj = nextPtr();
assert((intptr_t)obj >= 0 || (intptr_t)obj < -100,
"hit tag while initializing ptrs.");
*p = (void*)obj != nullptr ? (void*)(SharedBaseAddress + obj) : (void*)obj;
assert(obj >= 0, "sanity.");
*p = (obj != 0) ? (void*)(_base_address + obj) : (void*)obj;
}
void ReadClosure::do_u4(u4* p) {

View File

@ -230,13 +230,14 @@ public:
class ReadClosure : public SerializeClosure {
private:
intptr_t** _ptr_array;
intptr_t _base_address;
inline intptr_t nextPtr() {
return *(*_ptr_array)++;
}
public:
ReadClosure(intptr_t** ptr_array) { _ptr_array = ptr_array; }
ReadClosure(intptr_t** ptr_array, intptr_t base_address) :
_ptr_array(ptr_array), _base_address(base_address) {}
void do_ptr(void** p);
void do_u4(u4* p);

View File

@ -274,6 +274,7 @@ void FileMapHeader::print(outputStream* st) {
st->print_cr("- compressed_oops: %d", _compressed_oops);
st->print_cr("- compressed_class_ptrs: %d", _compressed_class_ptrs);
st->print_cr("- cloned_vtables_offset: " SIZE_FORMAT_X, _cloned_vtables_offset);
st->print_cr("- early_serialized_data_offset: " SIZE_FORMAT_X, _early_serialized_data_offset);
st->print_cr("- serialized_data_offset: " SIZE_FORMAT_X, _serialized_data_offset);
st->print_cr("- jvm_ident: %s", _jvm_ident);
st->print_cr("- shared_path_table_offset: " SIZE_FORMAT_X, _shared_path_table_offset);

View File

@ -193,6 +193,7 @@ private:
bool _compressed_oops; // save the flag UseCompressedOops
bool _compressed_class_ptrs; // save the flag UseCompressedClassPointers
size_t _cloned_vtables_offset; // The address of the first cloned vtable
size_t _early_serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
size_t _serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
bool _has_non_jar_in_classpath; // non-jar file entry exists in classpath
unsigned int _common_app_classpath_prefix_size; // size of the common prefix of app class paths
@ -261,6 +262,7 @@ public:
uintx max_heap_size() const { return _max_heap_size; }
CompressedOops::Mode narrow_oop_mode() const { return _narrow_oop_mode; }
char* cloned_vtables() const { return from_mapped_offset(_cloned_vtables_offset); }
char* early_serialized_data() const { return from_mapped_offset(_early_serialized_data_offset); }
char* serialized_data() const { return from_mapped_offset(_serialized_data_offset); }
const char* jvm_ident() const { return _jvm_ident; }
char* requested_base_address() const { return _requested_base_address; }
@ -283,6 +285,7 @@ public:
void set_has_platform_or_app_classes(bool v) { _has_platform_or_app_classes = v; }
void set_cloned_vtables(char* p) { set_as_offset(p, &_cloned_vtables_offset); }
void set_early_serialized_data(char* p) { set_as_offset(p, &_early_serialized_data_offset); }
void set_serialized_data(char* p) { set_as_offset(p, &_serialized_data_offset); }
void set_mapped_base_address(char* p) { _mapped_base_address = p; }
void set_heap_root_segments(HeapRootSegments segments) { _heap_root_segments = segments; }
@ -396,6 +399,8 @@ public:
char* cloned_vtables() const { return header()->cloned_vtables(); }
void set_cloned_vtables(char* p) const { header()->set_cloned_vtables(p); }
char* early_serialized_data() const { return header()->early_serialized_data(); }
void set_early_serialized_data(char* p) const { header()->set_early_serialized_data(p); }
char* serialized_data() const { return header()->serialized_data(); }
void set_serialized_data(char* p) const { header()->set_serialized_data(p); }

View File

@ -359,8 +359,43 @@ void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename)
}
}
// Read/write a data stream for restoring/preserving metadata pointers and
// miscellaneous data from/to the shared archive file.
// About "serialize" --
//
// This is (probably a badly named) way to read/write a data stream of pointers and
// miscellaneous data from/to the shared archive file. The usual code looks like this:
//
// // These two global C++ variables are initialized during dump time.
// static int _archived_int;
// static MetaspaceObj* archived_ptr;
//
// void MyClass::serialize(SerializeClosure* soc) {
// soc->do_int(&_archived_int);
// soc->do_int(&_archived_ptr);
// }
//
// At dumptime, these two variables are stored into the CDS archive.
// At runtime, these two variables are loaded from the CDS archive.
// In addition, the pointer is relocated as necessary.
//
// Some of the xxx::serialize() functions may have side effects and assume that
// the archive is already mapped. For example, SymbolTable::serialize_shared_table_header()
// unconditionally makes the set of archived symbols available. Therefore, we put most
// of these xxx::serialize() functions inside MetaspaceShared::serialize(), which
// is called AFTER we made the decision to map the archive.
//
// However, some of the "serialized" data are used to decide whether an archive should
// be mapped or not (e.g., for checking if the -Djdk.module.main property is compatible
// with the archive). The xxx::serialize() functions for these data must be put inside
// MetaspaceShared::early_serialize(). Such functions must not produce side effects that
// assume we will always decides to map the archive.
void MetaspaceShared::early_serialize(SerializeClosure* soc) {
int tag = 0;
soc->do_tag(--tag);
CDS_JAVA_HEAP_ONLY(Modules::serialize(soc);)
CDS_JAVA_HEAP_ONLY(Modules::serialize_addmods_names(soc);)
soc->do_tag(666);
}
void MetaspaceShared::serialize(SerializeClosure* soc) {
int tag = 0;
@ -402,8 +437,6 @@ void MetaspaceShared::serialize(SerializeClosure* soc) {
SystemDictionaryShared::serialize_vm_classes(soc);
soc->do_tag(--tag);
CDS_JAVA_HEAP_ONLY(Modules::serialize(soc);)
CDS_JAVA_HEAP_ONLY(Modules::serialize_addmods_names(soc);)
CDS_JAVA_HEAP_ONLY(ClassLoaderDataShared::serialize(soc);)
LambdaFormInvokers::serialize(soc);
@ -455,6 +488,7 @@ private:
log_info(cds)("Dumping symbol table ...");
SymbolTable::write_to_archive(symbols);
}
char* dump_early_read_only_tables();
char* dump_read_only_tables();
public:
@ -494,6 +528,21 @@ public:
}
};
char* VM_PopulateDumpSharedSpace::dump_early_read_only_tables() {
ArchiveBuilder::OtherROAllocMark mark;
// Write module name into archive
CDS_JAVA_HEAP_ONLY(Modules::dump_main_module_name();)
// Write module names from --add-modules into archive
CDS_JAVA_HEAP_ONLY(Modules::dump_addmods_names();)
DumpRegion* ro_region = ArchiveBuilder::current()->ro_region();
char* start = ro_region->top();
WriteClosure wc(ro_region);
MetaspaceShared::early_serialize(&wc);
return start;
}
char* VM_PopulateDumpSharedSpace::dump_read_only_tables() {
ArchiveBuilder::OtherROAllocMark mark;
@ -501,10 +550,7 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables() {
// Write lambform lines into archive
LambdaFormInvokers::dump_static_archive_invokers();
// Write module name into archive
CDS_JAVA_HEAP_ONLY(Modules::dump_main_module_name();)
// Write module names from --add-modules into archive
CDS_JAVA_HEAP_ONLY(Modules::dump_addmods_names();)
// Write the other data to the output array.
DumpRegion* ro_region = ArchiveBuilder::current()->ro_region();
char* start = ro_region->top();
@ -543,6 +589,7 @@ void VM_PopulateDumpSharedSpace::doit() {
log_info(cds)("Make classes shareable");
_builder.make_klasses_shareable();
char* early_serialized_data = dump_early_read_only_tables();
char* serialized_data = dump_read_only_tables();
SystemDictionaryShared::adjust_lambda_proxy_class_dictionary();
@ -556,6 +603,7 @@ void VM_PopulateDumpSharedSpace::doit() {
assert(static_archive != nullptr, "SharedArchiveFile not set?");
_map_info = new FileMapInfo(static_archive, true);
_map_info->populate_header(MetaspaceShared::core_region_alignment());
_map_info->set_early_serialized_data(early_serialized_data);
_map_info->set_serialized_data(serialized_data);
_map_info->set_cloned_vtables(CppVtables::vtables_serialized_base());
}
@ -1473,6 +1521,14 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped
return MAP_ARCHIVE_OTHER_FAILURE;
}
if (mapinfo->is_static()) {
// Currently, only static archive uses early serialized data.
char* buffer = mapinfo->early_serialized_data();
intptr_t* array = (intptr_t*)buffer;
ReadClosure rc(&array, (intptr_t)mapped_base_address);
early_serialize(&rc);
}
mapinfo->set_is_mapped(true);
return MAP_ARCHIVE_SUCCESS;
}
@ -1509,7 +1565,7 @@ void MetaspaceShared::initialize_shared_spaces() {
// shared string/symbol tables.
char* buffer = static_mapinfo->serialized_data();
intptr_t* array = (intptr_t*)buffer;
ReadClosure rc(&array);
ReadClosure rc(&array, (intptr_t)SharedBaseAddress);
serialize(&rc);
// Finish up archived heap initialization. These must be
@ -1526,7 +1582,7 @@ void MetaspaceShared::initialize_shared_spaces() {
FileMapInfo *dynamic_mapinfo = FileMapInfo::dynamic_info();
if (dynamic_mapinfo != nullptr) {
intptr_t* buffer = (intptr_t*)dynamic_mapinfo->serialized_data();
ReadClosure rc(&buffer);
ReadClosure rc(&buffer, (intptr_t)SharedBaseAddress);
ArchiveBuilder::serialize_dynamic_archivable_items(&rc);
DynamicArchive::setup_array_klasses();
dynamic_mapinfo->close();

View File

@ -111,6 +111,7 @@ public:
static void unrecoverable_writing_error(const char* message = nullptr);
static void writing_error(const char* message = nullptr);
static void early_serialize(SerializeClosure* sc) NOT_CDS_RETURN;
static void serialize(SerializeClosure* sc) NOT_CDS_RETURN;
// JVM/TI RedefineClasses() support:

View File

@ -599,6 +599,9 @@ void Modules::serialize(SerializeClosure* soc) {
}
log_info(cds)("optimized module handling: %s", CDSConfig::is_using_optimized_module_handling() ? "enabled" : "disabled");
log_info(cds)("full module graph: %s", CDSConfig::is_using_full_module_graph() ? "enabled" : "disabled");
// Don't hold onto the pointer, in case we might decide to unmap the archive.
_archived_main_module_name = nullptr;
}
}
@ -641,6 +644,9 @@ void Modules::serialize_addmods_names(SerializeClosure* soc) {
}
log_info(cds)("optimized module handling: %s", CDSConfig::is_using_optimized_module_handling() ? "enabled" : "disabled");
log_info(cds)("full module graph: %s", CDSConfig::is_using_full_module_graph() ? "enabled" : "disabled");
// Don't hold onto the pointer, in case we might decide to unmap the archive.
_archived_addmods_names = nullptr;
}
}