Skip to content

Commit cff25dd

Browse files
author
Matias Saavedra Silva
committed
8306582: Remove MetaspaceShared::exit_after_static_dump()
Reviewed-by: iklam, alanb, ccheung
1 parent 4ba81f6 commit cff25dd

File tree

9 files changed

+94
-44
lines changed

9 files changed

+94
-44
lines changed

src/hotspot/share/cds/archiveBuilder.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ void ArchiveBuilder::gather_klasses_and_symbols() {
262262
// TODO: in the future, if we want to produce deterministic contents in the
263263
// dynamic archive, we might need to sort the symbols alphabetically (also see
264264
// DynamicArchiveBuilder::sort_methods()).
265-
sort_symbols_and_fix_hash();
265+
log_info(cds)("Sorting symbols ... ");
266+
_symbols->sort(compare_symbols_by_address);
266267
sort_klasses();
267268

268269
// TODO -- we need a proper estimate for the archived modules, etc,
@@ -280,16 +281,6 @@ int ArchiveBuilder::compare_symbols_by_address(Symbol** a, Symbol** b) {
280281
}
281282
}
282283

283-
void ArchiveBuilder::sort_symbols_and_fix_hash() {
284-
log_info(cds)("Sorting symbols and fixing identity hash ... ");
285-
os::init_random(0x12345678);
286-
_symbols->sort(compare_symbols_by_address);
287-
for (int i = 0; i < _symbols->length(); i++) {
288-
assert(_symbols->at(i)->is_permanent(), "archived symbols must be permanent");
289-
_symbols->at(i)->update_identity_hash();
290-
}
291-
}
292-
293284
int ArchiveBuilder::compare_klass_by_name(Klass** a, Klass** b) {
294285
return a[0]->name()->fast_compare(b[0]->name());
295286
}
@@ -646,6 +637,14 @@ void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* s
646637
newtop = dump_region->top();
647638

648639
memcpy(dest, src, bytes);
640+
641+
// Update the hash of buffered sorted symbols for static dump so that the symbols have deterministic contents
642+
if (DumpSharedSpaces && (src_info->msotype() == MetaspaceObj::SymbolType)) {
643+
Symbol* buffered_symbol = (Symbol*)dest;
644+
assert(((Symbol*)src)->is_permanent(), "archived symbols must be permanent");
645+
buffered_symbol->update_identity_hash();
646+
}
647+
649648
{
650649
bool created;
651650
_buffered_to_src_table.put_if_absent((address)dest, src, &created);

src/hotspot/share/cds/archiveBuilder.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ class ArchiveBuilder : public StackObj {
241241
FollowMode get_follow_mode(MetaspaceClosure::Ref *ref);
242242

243243
void iterate_sorted_roots(MetaspaceClosure* it);
244-
void sort_symbols_and_fix_hash();
245244
void sort_klasses();
246245
static int compare_symbols_by_address(Symbol** a, Symbol** b);
247246
static int compare_klass_by_name(Klass** a, Klass** b);

src/hotspot/share/cds/heapShared.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ KlassSubGraphInfo* HeapShared::_default_subgraph_info;
133133
GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_pending_roots = nullptr;
134134
OopHandle HeapShared::_roots;
135135
OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
136-
KlassToOopHandleTable* HeapShared::_scratch_java_mirror_table = nullptr;
136+
MetaspaceObjToOopHandleTable* HeapShared::_scratch_java_mirror_table = nullptr;
137+
MetaspaceObjToOopHandleTable* HeapShared::_scratch_references_table = nullptr;
138+
ClassLoaderData* HeapShared::_saved_java_platform_loader_data = nullptr;
139+
ClassLoaderData* HeapShared::_saved_java_system_loader_data = nullptr;
137140

138141
static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], InstanceKlass* ik) {
139142
for (int i = 0; fields[i].valid(); i++) {
@@ -298,47 +301,66 @@ bool HeapShared::archive_object(oop obj) {
298301
}
299302
java_lang_Module::set_module_entry(obj, nullptr);
300303
} else if (java_lang_ClassLoader::is_instance(obj)) {
301-
// class_data will be restored explicitly at run time.
304+
// class_data will be restored explicitly at run time and after dumptime
302305
guarantee(obj == SystemDictionary::java_platform_loader() ||
303306
obj == SystemDictionary::java_system_loader() ||
304307
java_lang_ClassLoader::loader_data(obj) == nullptr, "must be");
308+
if (obj == SystemDictionary::java_platform_loader()) {
309+
_saved_java_platform_loader_data = java_lang_ClassLoader::loader_data_acquire(SystemDictionary::java_platform_loader());
310+
} else if (obj == SystemDictionary::java_system_loader()) {
311+
_saved_java_system_loader_data = java_lang_ClassLoader::loader_data_acquire(SystemDictionary::java_system_loader());
312+
}
305313
java_lang_ClassLoader::release_set_loader_data(obj, nullptr);
306314
}
307315

308316
return true;
309317
}
310318
}
311319

312-
class KlassToOopHandleTable: public ResourceHashtable<Klass*, OopHandle,
320+
void HeapShared::restore_loader_data() {
321+
log_info(cds)("Restoring java platform and system loaders");
322+
java_lang_ClassLoader::release_set_loader_data(SystemDictionary::java_platform_loader(), _saved_java_platform_loader_data);
323+
java_lang_ClassLoader::release_set_loader_data(SystemDictionary::java_system_loader(), _saved_java_system_loader_data);
324+
}
325+
326+
class MetaspaceObjToOopHandleTable: public ResourceHashtable<MetaspaceObj*, OopHandle,
313327
36137, // prime number
314328
AnyObj::C_HEAP,
315329
mtClassShared> {
316330
public:
317-
oop get_oop(Klass* k) {
331+
oop get_oop(MetaspaceObj* ptr) {
318332
MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
319-
OopHandle* handle = get(k);
333+
OopHandle* handle = get(ptr);
320334
if (handle != nullptr) {
321335
return handle->resolve();
322336
} else {
323337
return nullptr;
324338
}
325339
}
326-
void set_oop(Klass* k, oop o) {
340+
void set_oop(MetaspaceObj* ptr, oop o) {
327341
MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
328342
OopHandle handle(Universe::vm_global(), o);
329-
bool is_new = put(k, handle);
343+
bool is_new = put(ptr, handle);
330344
assert(is_new, "cannot set twice");
331345
}
332-
void remove_oop(Klass* k) {
346+
void remove_oop(MetaspaceObj* ptr) {
333347
MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
334-
OopHandle* handle = get(k);
348+
OopHandle* handle = get(ptr);
335349
if (handle != nullptr) {
336350
handle->release(Universe::vm_global());
337-
remove(k);
351+
remove(ptr);
338352
}
339353
}
340354
};
341355

356+
void HeapShared::add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) {
357+
_scratch_references_table->set_oop(src, dest);
358+
}
359+
360+
objArrayOop HeapShared::scratch_resolved_references(ConstantPool* src) {
361+
return (objArrayOop)_scratch_references_table->get_oop(src);
362+
}
363+
342364
void HeapShared::init_scratch_objects(TRAPS) {
343365
for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
344366
BasicType bt = (BasicType)i;
@@ -347,7 +369,8 @@ void HeapShared::init_scratch_objects(TRAPS) {
347369
_scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
348370
}
349371
}
350-
_scratch_java_mirror_table = new (mtClass)KlassToOopHandleTable();
372+
_scratch_java_mirror_table = new (mtClass)MetaspaceObjToOopHandleTable();
373+
_scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable();
351374
}
352375

353376
oop HeapShared::scratch_java_mirror(BasicType t) {
@@ -366,6 +389,9 @@ void HeapShared::set_scratch_java_mirror(Klass* k, oop mirror) {
366389

367390
void HeapShared::remove_scratch_objects(Klass* k) {
368391
_scratch_java_mirror_table->remove_oop(k);
392+
if (k->is_instance_klass()) {
393+
_scratch_references_table->remove(InstanceKlass::cast(k)->constants());
394+
}
369395
}
370396

371397
void HeapShared::archive_java_mirrors() {

src/hotspot/share/cds/heapShared.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
class DumpedInternedStrings;
4444
class FileMapInfo;
4545
class KlassSubGraphInfo;
46-
class KlassToOopHandleTable;
46+
class MetaspaceObjToOopHandleTable;
4747
class ResourceBitMap;
4848

4949
struct ArchivableStaticFieldInfo;
@@ -280,7 +280,11 @@ class HeapShared: AllStatic {
280280
static GrowableArrayCHeap<oop, mtClassShared>* _pending_roots;
281281
static OopHandle _roots;
282282
static OopHandle _scratch_basic_type_mirrors[T_VOID+1];
283-
static KlassToOopHandleTable* _scratch_java_mirror_table;
283+
static MetaspaceObjToOopHandleTable* _scratch_java_mirror_table;
284+
static MetaspaceObjToOopHandleTable* _scratch_references_table;
285+
286+
static ClassLoaderData* _saved_java_platform_loader_data;
287+
static ClassLoaderData* _saved_java_system_loader_data;
284288

285289
static void init_seen_objects_table() {
286290
assert(_seen_objects_table == nullptr, "must be");
@@ -394,7 +398,10 @@ class HeapShared: AllStatic {
394398
#endif // INCLUDE_CDS_JAVA_HEAP
395399

396400
public:
401+
static objArrayOop scratch_resolved_references(ConstantPool* src);
402+
static void add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) NOT_CDS_JAVA_HEAP_RETURN;
397403
static void init_scratch_objects(TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
404+
static void restore_loader_data() NOT_CDS_JAVA_HEAP_RETURN;
398405
static bool is_heap_region(int idx) {
399406
CDS_JAVA_HEAP_ONLY(return (idx == MetaspaceShared::hp);)
400407
NOT_CDS_JAVA_HEAP_RETURN_(false);

src/hotspot/share/cds/metaspaceShared.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,9 @@ void VM_PopulateDumpSharedSpace::doit() {
503503

504504
char* cloned_vtables = CppVtables::dumptime_init(&builder);
505505

506+
// Initialize random for updating the hash of symbols
507+
os::init_random(0x12345678);
508+
506509
builder.dump_rw_metadata();
507510
builder.dump_ro_metadata();
508511
builder.relocate_metaspaceobj_embedded_pointers();
@@ -543,8 +546,6 @@ void VM_PopulateDumpSharedSpace::doit() {
543546
log_warning(cds)("This archive was created with AllowArchivingWithJavaAgent. It should be used "
544547
"for testing purposes only and should not be used in a production environment");
545548
}
546-
547-
MetaspaceShared::exit_after_static_dump();
548549
}
549550

550551
class CollectCLDClosure : public CLDClosure {
@@ -661,11 +662,14 @@ void MetaspaceShared::preload_and_dump() {
661662
java_lang_String::as_utf8_string(java_lang_Throwable::message(PENDING_EXCEPTION)));
662663
MetaspaceShared::unrecoverable_writing_error("VM exits due to exception, use -Xlog:cds,exceptions=trace for detail");
663664
}
664-
} else {
665-
// On success, the VM_PopulateDumpSharedSpace op should have
666-
// exited the VM.
667-
ShouldNotReachHere();
668665
}
666+
667+
#if INCLUDE_CDS_JAVA_HEAP
668+
// Restore the java loaders that were cleared at dump time
669+
if (use_full_module_graph()) {
670+
HeapShared::restore_loader_data();
671+
}
672+
#endif
669673
}
670674

671675
#if INCLUDE_CDS_JAVA_HEAP && defined(_LP64)
@@ -902,14 +906,6 @@ void MetaspaceShared::unrecoverable_writing_error(const char* message) {
902906
vm_direct_exit(1);
903907
}
904908

905-
// We have finished dumping the static archive. At this point, there may be pending VM
906-
// operations. We have changed some global states (such as vmClasses::_klasses) that
907-
// may cause these VM operations to fail. For safety, forget these operations and
908-
// exit the VM directly.
909-
void MetaspaceShared::exit_after_static_dump() {
910-
os::_exit(0);
911-
}
912-
913909
void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
914910
assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled");
915911
MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE;

src/hotspot/share/cds/metaspaceShared.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ class MetaspaceShared : AllStatic {
105105

106106
static void unrecoverable_loading_error(const char* message = nullptr);
107107
static void unrecoverable_writing_error(const char* message = nullptr);
108-
static void exit_after_static_dump();
109108

110109
static void serialize(SerializeClosure* sc) NOT_CDS_RETURN;
111110

src/hotspot/share/oops/constantPool.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
216216
HandleMark hm(THREAD);
217217
Handle refs_handle (THREAD, stom); // must handleize.
218218
set_resolved_references(loader_data->add_handle(refs_handle));
219+
220+
// Create a "scratch" copy of the resolved references array to archive
221+
if (DumpSharedSpaces) {
222+
objArrayOop scratch_references = oopFactory::new_objArray(vmClasses::Object_klass(), map_length, CHECK);
223+
HeapShared::add_scratch_resolved_references(this, scratch_references);
224+
}
219225
}
220226
}
221227

@@ -286,22 +292,25 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
286292

287293
objArrayOop rr = resolved_references();
288294
if (rr != nullptr) {
295+
ConstantPool* orig_pool = ArchiveBuilder::current()->get_source_addr(this);
296+
objArrayOop scratch_rr = HeapShared::scratch_resolved_references(orig_pool);
289297
Array<u2>* ref_map = reference_map();
290298
int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
291299
int rr_len = rr->length();
292300
for (int i = 0; i < rr_len; i++) {
293301
oop obj = rr->obj_at(i);
294-
rr->obj_at_put(i, nullptr);
302+
scratch_rr->obj_at_put(i, nullptr);
295303
if (obj != nullptr && i < ref_map_len) {
296304
int index = object_to_cp_index(i);
297305
if (tag_at(index).is_string()) {
298306
assert(java_lang_String::is_instance(obj), "must be");
299307
if (!ArchiveHeapWriter::is_string_too_large_to_archive(obj)) {
300-
rr->obj_at_put(i, obj);
308+
scratch_rr->obj_at_put(i, obj);
301309
}
302310
}
303311
}
304312
}
313+
return scratch_rr;
305314
}
306315
return rr;
307316
}

src/hotspot/share/runtime/threads.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
814814

815815
if (DumpSharedSpaces) {
816816
MetaspaceShared::preload_and_dump();
817-
ShouldNotReachHere();
818817
}
819818

820819
return JNI_OK;

src/java.base/share/native/libjli/java.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static jboolean _is_java_args = JNI_FALSE;
8585
static jboolean _have_classpath = JNI_FALSE;
8686
static const char *_fVersion;
8787
static jboolean _wc_enabled = JNI_FALSE;
88+
static jboolean dumpSharedSpaces = JNI_FALSE; /* -Xshare:dump */
8889

8990
/*
9091
* Entries for splash screen environment variables.
@@ -455,6 +456,14 @@ JavaMain(void* _args)
455456
LEAVE();
456457
}
457458

459+
/*
460+
* -Xshare:dump does not have a main class so the VM can safely exit now
461+
*/
462+
if (dumpSharedSpaces) {
463+
CHECK_EXCEPTION_LEAVE(1);
464+
LEAVE();
465+
}
466+
458467
/* If the user specified neither a class name nor a JAR file */
459468
if (printXUsage || printUsage || what == 0 || mode == LM_UNKNOWN) {
460469
PrintUsage(env, printXUsage);
@@ -1432,6 +1441,13 @@ ParseArguments(int *pargc, char ***pargv,
14321441
}
14331442
AddOption(arg, NULL);
14341443
}
1444+
1445+
/*
1446+
* Check for CDS option
1447+
*/
1448+
if (JLI_StrCmp(arg, "-Xshare:dump") == 0) {
1449+
dumpSharedSpaces = JNI_TRUE;
1450+
}
14351451
}
14361452

14371453
if (*pwhat == NULL && --argc >= 0) {
@@ -1440,7 +1456,7 @@ ParseArguments(int *pargc, char ***pargv,
14401456

14411457
if (*pwhat == NULL) {
14421458
/* LM_UNKNOWN okay for options that exit */
1443-
if (!listModules && !describeModule && !validateModules) {
1459+
if (!listModules && !describeModule && !validateModules && !dumpSharedSpaces) {
14441460
*pret = 1;
14451461
}
14461462
} else if (mode == LM_UNKNOWN) {

0 commit comments

Comments
 (0)