mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 18:33:41 +00:00
8343493: Perform module checks during MetaspaceShared::map_archives()
Reviewed-by: ccheung, matsaave
This commit is contained in:
parent
ccda8159f6
commit
fac89f471c
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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); }
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user