Skip to content

Commit 1ff4646

Browse files
committed
8298612: Refactor archiving of java String objects
Reviewed-by: ccheung
1 parent d4e9f5e commit 1ff4646

File tree

4 files changed

+45
-48
lines changed

4 files changed

+45
-48
lines changed

src/hotspot/share/cds/heapShared.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ void HeapShared::archive_java_mirrors() {
457457
if (rr != nullptr && !is_too_large_to_archive(rr)) {
458458
oop archived_obj = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr,
459459
/*is_closed_archive=*/false);
460-
assert(archived_obj != NULL, "already checked not too large to archive");
460+
assert(archived_obj != nullptr, "already checked not too large to archive");
461461
int root_index = append_root(archived_obj);
462462
ik->constants()->cache()->set_archived_references(root_index);
463463
}
@@ -630,6 +630,27 @@ void HeapShared::archive_objects(GrowableArray<MemRegion>* closed_regions,
630630
}
631631

632632
G1HeapVerifier::verify_archive_regions();
633+
StringTable::write_shared_table(_dumped_interned_strings);
634+
}
635+
636+
void HeapShared::copy_interned_strings() {
637+
init_seen_objects_table();
638+
639+
auto copier = [&] (oop s, bool value_ignored) {
640+
assert(s != nullptr, "sanity");
641+
typeArrayOop value = java_lang_String::value_no_keepalive(s);
642+
if (!HeapShared::is_too_large_to_archive(value)) {
643+
oop archived_s = archive_reachable_objects_from(1, _default_subgraph_info,
644+
s, /*is_closed_archive=*/true);
645+
assert(archived_s != nullptr, "already checked not too large to archive");
646+
// Prevent string deduplication from changing the value field to
647+
// something not in the archive.
648+
java_lang_String::set_deduplication_forbidden(archived_s);
649+
}
650+
};
651+
_dumped_interned_strings->iterate_all(copier);
652+
653+
delete_seen_objects_table();
633654
}
634655

635656
void HeapShared::copy_closed_objects(GrowableArray<MemRegion>* closed_regions) {
@@ -638,7 +659,7 @@ void HeapShared::copy_closed_objects(GrowableArray<MemRegion>* closed_regions) {
638659
G1CollectedHeap::heap()->begin_archive_alloc_range();
639660

640661
// Archive interned string objects
641-
StringTable::write_to_archive(_dumped_interned_strings);
662+
copy_interned_strings();
642663

643664
archive_object_subgraphs(closed_archive_subgraph_entry_fields,
644665
true /* is_closed_archive */,

src/hotspot/share/cds/heapShared.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,9 @@ class HeapShared: AllStatic {
316316

317317
static bool has_been_seen_during_subgraph_recording(oop obj);
318318
static void set_has_been_seen_during_subgraph_recording(oop obj);
319+
static oop archive_object(oop obj);
319320

321+
static void copy_interned_strings();
320322
static void copy_roots();
321323

322324
static void resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]);
@@ -373,7 +375,6 @@ class HeapShared: AllStatic {
373375

374376
static bool is_too_large_to_archive(oop o);
375377
static oop find_archived_heap_object(oop obj);
376-
static oop archive_object(oop obj);
377378

378379
static void archive_java_mirrors();
379380

src/hotspot/share/classfile/stringTable.cpp

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -754,32 +754,7 @@ oop StringTable::lookup_shared(const jchar* name, int len) {
754754
return _shared_table.lookup(name, java_lang_String::hash_code(name, len), len);
755755
}
756756

757-
oop StringTable::create_archived_string(oop s) {
758-
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
759-
assert(java_lang_String::is_instance(s), "sanity");
760-
assert(!HeapShared::is_archived_object_during_dumptime(s), "sanity");
761-
762-
oop new_s = nullptr;
763-
typeArrayOop v = java_lang_String::value_no_keepalive(s);
764-
typeArrayOop new_v = (typeArrayOop)HeapShared::archive_object(v);
765-
if (new_v == nullptr) {
766-
return nullptr;
767-
}
768-
new_s = HeapShared::archive_object(s);
769-
if (new_s == nullptr) {
770-
return nullptr;
771-
}
772-
773-
// adjust the pointer to the 'value' field in the new String oop
774-
java_lang_String::set_value_raw(new_s, new_v);
775-
// Prevent string deduplication from changing the 'value' field to
776-
// something not in the archive before building the archive. Also marks
777-
// the shared string when loaded.
778-
java_lang_String::set_deduplication_forbidden(new_s);
779-
return new_s;
780-
}
781-
782-
class CopyToArchive : StackObj {
757+
class EncodeSharedStringsAsOffsets : StackObj {
783758
CompactHashtableWriter* _writer;
784759
private:
785760
u4 compute_delta(oop s) {
@@ -792,34 +767,35 @@ class CopyToArchive : StackObj {
792767
return (u4)offset;
793768
}
794769
public:
795-
CopyToArchive(CompactHashtableWriter* writer) : _writer(writer) {}
770+
EncodeSharedStringsAsOffsets(CompactHashtableWriter* writer) : _writer(writer) {}
796771
bool do_entry(oop s, bool value_ignored) {
797772
assert(s != nullptr, "sanity");
798-
unsigned int hash = java_lang_String::hash_code(s);
799-
oop new_s = StringTable::create_archived_string(s);
800-
if (new_s == nullptr) {
801-
return true;
802-
}
803-
804-
// add to the compact table
805-
if (UseCompressedOops) {
806-
_writer->add(hash, CompressedOops::narrow_oop_value(new_s));
807-
} else {
808-
_writer->add(hash, compute_delta(new_s));
773+
oop new_s = HeapShared::find_archived_heap_object(s);
774+
if (new_s != nullptr) { // could be null if the string is too big
775+
unsigned int hash = java_lang_String::hash_code(s);
776+
if (UseCompressedOops) {
777+
_writer->add(hash, CompressedOops::narrow_oop_value(new_s));
778+
} else {
779+
_writer->add(hash, compute_delta(new_s));
780+
}
809781
}
810-
return true;
782+
return true; // keep iterating
811783
}
812784
};
813785

814-
void StringTable::write_to_archive(const DumpedInternedStrings* dumped_interned_strings) {
786+
// Write the _shared_table (a CompactHashtable) into the CDS archive file.
787+
void StringTable::write_shared_table(const DumpedInternedStrings* dumped_interned_strings) {
815788
assert(HeapShared::can_write(), "must be");
816789

817790
_shared_table.reset();
818791
CompactHashtableWriter writer(_items_count, ArchiveBuilder::string_stats());
819792

820-
// Copy the interned strings into the "string space" within the java heap
821-
CopyToArchive copier(&writer);
822-
dumped_interned_strings->iterate(&copier);
793+
// Encode the strings in the CompactHashtable using offsets -- we know that the
794+
// strings will not move during runtime because they are inside the G1 closed
795+
// archive region.
796+
EncodeSharedStringsAsOffsets offset_finder(&writer);
797+
dumped_interned_strings->iterate(&offset_finder);
798+
823799
writer.dump(&_shared_table, "string");
824800
}
825801

src/hotspot/share/classfile/stringTable.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ class StringTable : public CHeapObj<mtSymbol>{
109109
public:
110110
static oop lookup_shared(const jchar* name, int len) NOT_CDS_JAVA_HEAP_RETURN_(nullptr);
111111
static size_t shared_entry_count() NOT_CDS_JAVA_HEAP_RETURN_(0);
112-
static oop create_archived_string(oop s) NOT_CDS_JAVA_HEAP_RETURN_(nullptr);
113-
static void write_to_archive(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN;
112+
static void write_shared_table(const DumpedInternedStrings* dumped_interned_strings) NOT_CDS_JAVA_HEAP_RETURN;
114113
static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
115114
static void transfer_shared_strings_to_local_table() NOT_CDS_JAVA_HEAP_RETURN;
116115

0 commit comments

Comments
 (0)