Skip to content

Commit fac89f4

Browse files
committedNov 7, 2024
8343493: Perform module checks during MetaspaceShared::map_archives()
Reviewed-by: ccheung, matsaave
1 parent ccda815 commit fac89f4

File tree

7 files changed

+84
-15
lines changed

7 files changed

+84
-15
lines changed
 

‎src/hotspot/share/cds/archiveUtils.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,8 @@ void WriteClosure::do_ptr(void** p) {
320320
void ReadClosure::do_ptr(void** p) {
321321
assert(*p == nullptr, "initializing previous initialized pointer.");
322322
intptr_t obj = nextPtr();
323-
assert((intptr_t)obj >= 0 || (intptr_t)obj < -100,
324-
"hit tag while initializing ptrs.");
325-
*p = (void*)obj != nullptr ? (void*)(SharedBaseAddress + obj) : (void*)obj;
323+
assert(obj >= 0, "sanity.");
324+
*p = (obj != 0) ? (void*)(_base_address + obj) : (void*)obj;
326325
}
327326

328327
void ReadClosure::do_u4(u4* p) {

‎src/hotspot/share/cds/archiveUtils.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,14 @@ class WriteClosure : public SerializeClosure {
230230
class ReadClosure : public SerializeClosure {
231231
private:
232232
intptr_t** _ptr_array;
233-
233+
intptr_t _base_address;
234234
inline intptr_t nextPtr() {
235235
return *(*_ptr_array)++;
236236
}
237237

238238
public:
239-
ReadClosure(intptr_t** ptr_array) { _ptr_array = ptr_array; }
239+
ReadClosure(intptr_t** ptr_array, intptr_t base_address) :
240+
_ptr_array(ptr_array), _base_address(base_address) {}
240241

241242
void do_ptr(void** p);
242243
void do_u4(u4* p);

‎src/hotspot/share/cds/filemap.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ void FileMapHeader::print(outputStream* st) {
274274
st->print_cr("- compressed_oops: %d", _compressed_oops);
275275
st->print_cr("- compressed_class_ptrs: %d", _compressed_class_ptrs);
276276
st->print_cr("- cloned_vtables_offset: " SIZE_FORMAT_X, _cloned_vtables_offset);
277+
st->print_cr("- early_serialized_data_offset: " SIZE_FORMAT_X, _early_serialized_data_offset);
277278
st->print_cr("- serialized_data_offset: " SIZE_FORMAT_X, _serialized_data_offset);
278279
st->print_cr("- jvm_ident: %s", _jvm_ident);
279280
st->print_cr("- shared_path_table_offset: " SIZE_FORMAT_X, _shared_path_table_offset);

‎src/hotspot/share/cds/filemap.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
193193
bool _compressed_oops; // save the flag UseCompressedOops
194194
bool _compressed_class_ptrs; // save the flag UseCompressedClassPointers
195195
size_t _cloned_vtables_offset; // The address of the first cloned vtable
196+
size_t _early_serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
196197
size_t _serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
197198
bool _has_non_jar_in_classpath; // non-jar file entry exists in classpath
198199
unsigned int _common_app_classpath_prefix_size; // size of the common prefix of app class paths
@@ -261,6 +262,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
261262
uintx max_heap_size() const { return _max_heap_size; }
262263
CompressedOops::Mode narrow_oop_mode() const { return _narrow_oop_mode; }
263264
char* cloned_vtables() const { return from_mapped_offset(_cloned_vtables_offset); }
265+
char* early_serialized_data() const { return from_mapped_offset(_early_serialized_data_offset); }
264266
char* serialized_data() const { return from_mapped_offset(_serialized_data_offset); }
265267
const char* jvm_ident() const { return _jvm_ident; }
266268
char* requested_base_address() const { return _requested_base_address; }
@@ -283,6 +285,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
283285

284286
void set_has_platform_or_app_classes(bool v) { _has_platform_or_app_classes = v; }
285287
void set_cloned_vtables(char* p) { set_as_offset(p, &_cloned_vtables_offset); }
288+
void set_early_serialized_data(char* p) { set_as_offset(p, &_early_serialized_data_offset); }
286289
void set_serialized_data(char* p) { set_as_offset(p, &_serialized_data_offset); }
287290
void set_mapped_base_address(char* p) { _mapped_base_address = p; }
288291
void set_heap_root_segments(HeapRootSegments segments) { _heap_root_segments = segments; }
@@ -396,6 +399,8 @@ class FileMapInfo : public CHeapObj<mtInternal> {
396399

397400
char* cloned_vtables() const { return header()->cloned_vtables(); }
398401
void set_cloned_vtables(char* p) const { header()->set_cloned_vtables(p); }
402+
char* early_serialized_data() const { return header()->early_serialized_data(); }
403+
void set_early_serialized_data(char* p) const { header()->set_early_serialized_data(p); }
399404
char* serialized_data() const { return header()->serialized_data(); }
400405
void set_serialized_data(char* p) const { header()->set_serialized_data(p); }
401406

‎src/hotspot/share/cds/metaspaceShared.cpp

+66-10
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,43 @@ void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename)
359359
}
360360
}
361361

362-
// Read/write a data stream for restoring/preserving metadata pointers and
363-
// miscellaneous data from/to the shared archive file.
362+
// About "serialize" --
363+
//
364+
// This is (probably a badly named) way to read/write a data stream of pointers and
365+
// miscellaneous data from/to the shared archive file. The usual code looks like this:
366+
//
367+
// // These two global C++ variables are initialized during dump time.
368+
// static int _archived_int;
369+
// static MetaspaceObj* archived_ptr;
370+
//
371+
// void MyClass::serialize(SerializeClosure* soc) {
372+
// soc->do_int(&_archived_int);
373+
// soc->do_int(&_archived_ptr);
374+
// }
375+
//
376+
// At dumptime, these two variables are stored into the CDS archive.
377+
// At runtime, these two variables are loaded from the CDS archive.
378+
// In addition, the pointer is relocated as necessary.
379+
//
380+
// Some of the xxx::serialize() functions may have side effects and assume that
381+
// the archive is already mapped. For example, SymbolTable::serialize_shared_table_header()
382+
// unconditionally makes the set of archived symbols available. Therefore, we put most
383+
// of these xxx::serialize() functions inside MetaspaceShared::serialize(), which
384+
// is called AFTER we made the decision to map the archive.
385+
//
386+
// However, some of the "serialized" data are used to decide whether an archive should
387+
// be mapped or not (e.g., for checking if the -Djdk.module.main property is compatible
388+
// with the archive). The xxx::serialize() functions for these data must be put inside
389+
// MetaspaceShared::early_serialize(). Such functions must not produce side effects that
390+
// assume we will always decides to map the archive.
391+
392+
void MetaspaceShared::early_serialize(SerializeClosure* soc) {
393+
int tag = 0;
394+
soc->do_tag(--tag);
395+
CDS_JAVA_HEAP_ONLY(Modules::serialize(soc);)
396+
CDS_JAVA_HEAP_ONLY(Modules::serialize_addmods_names(soc);)
397+
soc->do_tag(666);
398+
}
364399

365400
void MetaspaceShared::serialize(SerializeClosure* soc) {
366401
int tag = 0;
@@ -402,8 +437,6 @@ void MetaspaceShared::serialize(SerializeClosure* soc) {
402437
SystemDictionaryShared::serialize_vm_classes(soc);
403438
soc->do_tag(--tag);
404439

405-
CDS_JAVA_HEAP_ONLY(Modules::serialize(soc);)
406-
CDS_JAVA_HEAP_ONLY(Modules::serialize_addmods_names(soc);)
407440
CDS_JAVA_HEAP_ONLY(ClassLoaderDataShared::serialize(soc);)
408441

409442
LambdaFormInvokers::serialize(soc);
@@ -455,6 +488,7 @@ class VM_PopulateDumpSharedSpace : public VM_Operation {
455488
log_info(cds)("Dumping symbol table ...");
456489
SymbolTable::write_to_archive(symbols);
457490
}
491+
char* dump_early_read_only_tables();
458492
char* dump_read_only_tables();
459493

460494
public:
@@ -494,17 +528,29 @@ class StaticArchiveBuilder : public ArchiveBuilder {
494528
}
495529
};
496530

531+
char* VM_PopulateDumpSharedSpace::dump_early_read_only_tables() {
532+
ArchiveBuilder::OtherROAllocMark mark;
533+
534+
// Write module name into archive
535+
CDS_JAVA_HEAP_ONLY(Modules::dump_main_module_name();)
536+
// Write module names from --add-modules into archive
537+
CDS_JAVA_HEAP_ONLY(Modules::dump_addmods_names();)
538+
539+
DumpRegion* ro_region = ArchiveBuilder::current()->ro_region();
540+
char* start = ro_region->top();
541+
WriteClosure wc(ro_region);
542+
MetaspaceShared::early_serialize(&wc);
543+
return start;
544+
}
545+
497546
char* VM_PopulateDumpSharedSpace::dump_read_only_tables() {
498547
ArchiveBuilder::OtherROAllocMark mark;
499548

500549
SystemDictionaryShared::write_to_archive();
501550

502551
// Write lambform lines into archive
503552
LambdaFormInvokers::dump_static_archive_invokers();
504-
// Write module name into archive
505-
CDS_JAVA_HEAP_ONLY(Modules::dump_main_module_name();)
506-
// Write module names from --add-modules into archive
507-
CDS_JAVA_HEAP_ONLY(Modules::dump_addmods_names();)
553+
508554
// Write the other data to the output array.
509555
DumpRegion* ro_region = ArchiveBuilder::current()->ro_region();
510556
char* start = ro_region->top();
@@ -543,6 +589,7 @@ void VM_PopulateDumpSharedSpace::doit() {
543589
log_info(cds)("Make classes shareable");
544590
_builder.make_klasses_shareable();
545591

592+
char* early_serialized_data = dump_early_read_only_tables();
546593
char* serialized_data = dump_read_only_tables();
547594

548595
SystemDictionaryShared::adjust_lambda_proxy_class_dictionary();
@@ -556,6 +603,7 @@ void VM_PopulateDumpSharedSpace::doit() {
556603
assert(static_archive != nullptr, "SharedArchiveFile not set?");
557604
_map_info = new FileMapInfo(static_archive, true);
558605
_map_info->populate_header(MetaspaceShared::core_region_alignment());
606+
_map_info->set_early_serialized_data(early_serialized_data);
559607
_map_info->set_serialized_data(serialized_data);
560608
_map_info->set_cloned_vtables(CppVtables::vtables_serialized_base());
561609
}
@@ -1473,6 +1521,14 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped
14731521
return MAP_ARCHIVE_OTHER_FAILURE;
14741522
}
14751523

1524+
if (mapinfo->is_static()) {
1525+
// Currently, only static archive uses early serialized data.
1526+
char* buffer = mapinfo->early_serialized_data();
1527+
intptr_t* array = (intptr_t*)buffer;
1528+
ReadClosure rc(&array, (intptr_t)mapped_base_address);
1529+
early_serialize(&rc);
1530+
}
1531+
14761532
mapinfo->set_is_mapped(true);
14771533
return MAP_ARCHIVE_SUCCESS;
14781534
}
@@ -1509,7 +1565,7 @@ void MetaspaceShared::initialize_shared_spaces() {
15091565
// shared string/symbol tables.
15101566
char* buffer = static_mapinfo->serialized_data();
15111567
intptr_t* array = (intptr_t*)buffer;
1512-
ReadClosure rc(&array);
1568+
ReadClosure rc(&array, (intptr_t)SharedBaseAddress);
15131569
serialize(&rc);
15141570

15151571
// Finish up archived heap initialization. These must be
@@ -1526,7 +1582,7 @@ void MetaspaceShared::initialize_shared_spaces() {
15261582
FileMapInfo *dynamic_mapinfo = FileMapInfo::dynamic_info();
15271583
if (dynamic_mapinfo != nullptr) {
15281584
intptr_t* buffer = (intptr_t*)dynamic_mapinfo->serialized_data();
1529-
ReadClosure rc(&buffer);
1585+
ReadClosure rc(&buffer, (intptr_t)SharedBaseAddress);
15301586
ArchiveBuilder::serialize_dynamic_archivable_items(&rc);
15311587
DynamicArchive::setup_array_klasses();
15321588
dynamic_mapinfo->close();

‎src/hotspot/share/cds/metaspaceShared.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class MetaspaceShared : AllStatic {
111111
static void unrecoverable_writing_error(const char* message = nullptr);
112112
static void writing_error(const char* message = nullptr);
113113

114+
static void early_serialize(SerializeClosure* sc) NOT_CDS_RETURN;
114115
static void serialize(SerializeClosure* sc) NOT_CDS_RETURN;
115116

116117
// JVM/TI RedefineClasses() support:

‎src/hotspot/share/classfile/modules.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,9 @@ void Modules::serialize(SerializeClosure* soc) {
599599
}
600600
log_info(cds)("optimized module handling: %s", CDSConfig::is_using_optimized_module_handling() ? "enabled" : "disabled");
601601
log_info(cds)("full module graph: %s", CDSConfig::is_using_full_module_graph() ? "enabled" : "disabled");
602+
603+
// Don't hold onto the pointer, in case we might decide to unmap the archive.
604+
_archived_main_module_name = nullptr;
602605
}
603606
}
604607

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

0 commit comments

Comments
 (0)
Please sign in to comment.