mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8179302: Pre-resolve constant pool string entries and cache resolved_reference arrays in CDS archive
8185924: G1NoteEndOfConcMarkClosure::doHeapRegion() does not do remembered set cleanup work for archive region Shared class' constant pool resolved_references array is cached. Co-authored-by: Thomas Schatzl <thomas.schatzl@oracle.com> Reviewed-by: coleenp, iklam, tschatzl
This commit is contained in:
parent
85fedbbb12
commit
4a77945c89
36 changed files with 931 additions and 418 deletions
|
@ -90,7 +90,7 @@ class StableMemoryChecker : public StackObj {
|
|||
|
||||
// --------------------------------------------------------------------------
|
||||
StringTable* StringTable::_the_table = NULL;
|
||||
bool StringTable::_ignore_shared_strings = false;
|
||||
bool StringTable::_shared_string_mapped = false;
|
||||
bool StringTable::_needs_rehashing = false;
|
||||
|
||||
volatile int StringTable::_parallel_claimed_idx = 0;
|
||||
|
@ -678,13 +678,30 @@ int StringtableDCmd::num_arguments() {
|
|||
}
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
// Sharing
|
||||
oop StringTable::create_archived_string(oop s, Thread* THREAD) {
|
||||
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
|
||||
|
||||
oop new_s = NULL;
|
||||
typeArrayOop v = java_lang_String::value(s);
|
||||
typeArrayOop new_v = (typeArrayOop)MetaspaceShared::archive_heap_object(v, THREAD);
|
||||
if (new_v == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new_s = MetaspaceShared::archive_heap_object(s, THREAD);
|
||||
if (new_s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// adjust the pointer to the 'value' field in the new String oop
|
||||
java_lang_String::set_value_raw(new_s, new_v);
|
||||
return new_s;
|
||||
}
|
||||
|
||||
bool StringTable::copy_shared_string(GrowableArray<MemRegion> *string_space,
|
||||
CompactStringTableWriter* writer) {
|
||||
#if INCLUDE_CDS && INCLUDE_ALL_GCS && defined(_LP64) && !defined(_WINDOWS)
|
||||
assert(UseG1GC, "Only support G1 GC");
|
||||
assert(UseCompressedOops && UseCompressedClassPointers,
|
||||
"Only support UseCompressedOops and UseCompressedClassPointers enabled");
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
|
||||
|
||||
Thread* THREAD = Thread::current();
|
||||
G1CollectedHeap::heap()->begin_archive_alloc_range();
|
||||
|
@ -697,94 +714,54 @@ bool StringTable::copy_shared_string(GrowableArray<MemRegion> *string_space,
|
|||
continue;
|
||||
}
|
||||
|
||||
// allocate the new 'value' array first
|
||||
typeArrayOop v = java_lang_String::value(s);
|
||||
int v_len = v->size();
|
||||
typeArrayOop new_v;
|
||||
if (G1CollectedHeap::heap()->is_archive_alloc_too_large(v_len)) {
|
||||
continue; // skip the current String. The 'value' array is too large to handle
|
||||
} else {
|
||||
new_v = (typeArrayOop)G1CollectedHeap::heap()->archive_mem_allocate(v_len);
|
||||
if (new_v == NULL) {
|
||||
return false; // allocation failed
|
||||
}
|
||||
}
|
||||
// now allocate the new String object
|
||||
int s_len = s->size();
|
||||
oop new_s = (oop)G1CollectedHeap::heap()->archive_mem_allocate(s_len);
|
||||
java_lang_String::set_hash(s, hash);
|
||||
oop new_s = create_archived_string(s, THREAD);
|
||||
if (new_s == NULL) {
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
s->identity_hash();
|
||||
v->identity_hash();
|
||||
|
||||
// copy the objects' data
|
||||
Copy::aligned_disjoint_words((HeapWord*)s, (HeapWord*)new_s, s_len);
|
||||
Copy::aligned_disjoint_words((HeapWord*)v, (HeapWord*)new_v, v_len);
|
||||
|
||||
// adjust the pointer to the 'value' field in the new String oop. Also pre-compute and set the
|
||||
// 'hash' field. That avoids "write" to the shared strings at runtime by the deduplication process.
|
||||
java_lang_String::set_value_raw(new_s, new_v);
|
||||
if (java_lang_String::hash(new_s) == 0) {
|
||||
java_lang_String::set_hash(new_s, hash);
|
||||
}
|
||||
// set the archived string in bucket
|
||||
bucket->set_literal(new_s);
|
||||
|
||||
// add to the compact table
|
||||
writer->add(hash, new_s);
|
||||
|
||||
MetaspaceShared::relocate_klass_ptr(new_s);
|
||||
MetaspaceShared::relocate_klass_ptr(new_v);
|
||||
}
|
||||
}
|
||||
|
||||
G1CollectedHeap::heap()->end_archive_alloc_range(string_space, os::vm_allocation_granularity());
|
||||
assert(string_space->length() <= 2, "sanity");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void StringTable::write_to_archive(GrowableArray<MemRegion> *string_space) {
|
||||
#if INCLUDE_CDS
|
||||
_shared_table.reset();
|
||||
if (!(UseG1GC && UseCompressedOops && UseCompressedClassPointers)) {
|
||||
log_info(cds)(
|
||||
"Shared strings are excluded from the archive as UseG1GC, "
|
||||
"UseCompressedOops and UseCompressedClassPointers are required."
|
||||
"Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.",
|
||||
BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops),
|
||||
BOOL_TO_STR(UseCompressedClassPointers));
|
||||
} else {
|
||||
int num_buckets = the_table()->number_of_entries() /
|
||||
SharedSymbolTableBucketSize;
|
||||
// calculation of num_buckets can result in zero buckets, we need at least one
|
||||
CompactStringTableWriter writer(num_buckets > 1 ? num_buckets : 1,
|
||||
&MetaspaceShared::stats()->string);
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
|
||||
|
||||
// Copy the interned strings into the "string space" within the java heap
|
||||
if (copy_shared_string(string_space, &writer)) {
|
||||
writer.dump(&_shared_table);
|
||||
}
|
||||
_shared_table.reset();
|
||||
int num_buckets = the_table()->number_of_entries() /
|
||||
SharedSymbolTableBucketSize;
|
||||
// calculation of num_buckets can result in zero buckets, we need at least one
|
||||
CompactStringTableWriter writer(num_buckets > 1 ? num_buckets : 1,
|
||||
&MetaspaceShared::stats()->string);
|
||||
|
||||
// Copy the interned strings into the "string space" within the java heap
|
||||
if (copy_shared_string(string_space, &writer)) {
|
||||
writer.dump(&_shared_table);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void StringTable::serialize(SerializeClosure* soc) {
|
||||
#if INCLUDE_CDS && defined(_LP64) && !defined(_WINDOWS)
|
||||
_shared_table.set_type(CompactHashtable<oop, char>::_string_table);
|
||||
_shared_table.serialize(soc);
|
||||
|
||||
if (soc->writing()) {
|
||||
_shared_table.reset(); // Sanity. Make sure we don't use the shared table at dump time
|
||||
} else if (_ignore_shared_strings) {
|
||||
} else if (!_shared_string_mapped) {
|
||||
_shared_table.reset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void StringTable::shared_oops_do(OopClosure* f) {
|
||||
#if INCLUDE_CDS && defined(_LP64) && !defined(_WINDOWS)
|
||||
_shared_table.oops_do(f);
|
||||
#endif
|
||||
}
|
||||
#endif //INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue