diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index b39c9c750a0..9d7671693ad 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -61,6 +61,7 @@ #include "utilities/copy.hpp" #if INCLUDE_G1GC #include "gc/g1/g1CollectedHeap.hpp" +#include "gc/g1/heapRegion.hpp" #endif #if INCLUDE_CDS_JAVA_HEAP @@ -289,6 +290,15 @@ void HeapShared::clear_root(int index) { } } +bool HeapShared::is_too_large_to_archive(oop o) { + // TODO: To make the CDS heap mappable for all collectors, this function should + // reject objects that may be too large for *any* collector. + assert(UseG1GC, "implementation limitation"); + size_t sz = align_up(o->size() * HeapWordSize, ObjectAlignmentInBytes); + size_t max = /*G1*/HeapRegion::min_region_size_in_words() * HeapWordSize; + return (sz > max); +} + oop HeapShared::archive_object(oop obj) { assert(DumpSharedSpaces, "dump-time only"); @@ -443,7 +453,14 @@ void HeapShared::archive_java_mirrors() { // archive the resolved_referenes array if (buffered_k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(buffered_k); - ik->constants()->archive_resolved_references(); + oop rr = ik->constants()->prepare_resolved_references_for_archiving(); + if (rr != nullptr && !is_too_large_to_archive(rr)) { + oop archived_obj = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr, + /*is_closed_archive=*/false); + assert(archived_obj != NULL, "already checked not too large to archive"); + int root_index = append_root(archived_obj); + ik->constants()->cache()->set_archived_references(root_index); + } } } } diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 6db5a5a306e..de3a8cec6ab 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -371,6 +371,7 @@ private: } } + static bool is_too_large_to_archive(oop o); static oop find_archived_heap_object(oop obj); static oop archive_object(oop obj); diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index cb6a6d03485..e30415fe087 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -267,10 +267,11 @@ void ConstantPool::klass_at_put(int class_index, Klass* k) { } #if INCLUDE_CDS_JAVA_HEAP -// Archive the resolved references -void ConstantPool::archive_resolved_references() { +// Returns the _resolved_reference array after removing unarchivable items from it. +// Returns nullptr if this class is not supported, or _resolved_reference doesn't exist. +objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { if (_cache == NULL) { - return; // nothing to do + return nullptr; // nothing to do } InstanceKlass *ik = pool_holder(); @@ -278,39 +279,30 @@ void ConstantPool::archive_resolved_references() { ik->is_shared_app_class())) { // Archiving resolved references for classes from non-builtin loaders // is not yet supported. - return; + return nullptr; } objArrayOop rr = resolved_references(); - Array* ref_map = reference_map(); - if (rr != NULL) { + if (rr != nullptr) { + Array* ref_map = reference_map(); int ref_map_len = ref_map == NULL ? 0 : ref_map->length(); int rr_len = rr->length(); for (int i = 0; i < rr_len; i++) { oop obj = rr->obj_at(i); - rr->obj_at_put(i, NULL); + rr->obj_at_put(i, nullptr); if (obj != NULL && i < ref_map_len) { int index = object_to_cp_index(i); if (tag_at(index).is_string()) { - oop archived_string = HeapShared::find_archived_heap_object(obj); - // Update the reference to point to the archived copy - // of this string. - // If the string is too large to archive, NULL is - // stored into rr. At run time, string_at_impl() will create and intern - // the string. - rr->obj_at_put(i, archived_string); + assert(java_lang_String::is_instance(obj), "must be"); + typeArrayOop value = java_lang_String::value_no_keepalive(obj); + if (!HeapShared::is_too_large_to_archive(value)) { + rr->obj_at_put(i, obj); + } } } } - - oop archived = HeapShared::archive_object(rr); - // If the resolved references array is not archived (too large), - // the 'archived' object is NULL. No need to explicitly check - // the return value of archive_object() here. At runtime, the - // resolved references will be created using the normal process - // when there is no archived value. - _cache->set_archived_references(archived); } + return rr; } void ConstantPool::add_dumped_interned_strings() { diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp index 0731a2e76b9..9f9c88f0734 100644 --- a/src/hotspot/share/oops/constantPool.hpp +++ b/src/hotspot/share/oops/constantPool.hpp @@ -697,7 +697,7 @@ class ConstantPool : public Metadata { #if INCLUDE_CDS // CDS support - void archive_resolved_references() NOT_CDS_JAVA_HEAP_RETURN; + objArrayOop prepare_resolved_references_for_archiving() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); void add_dumped_interned_strings() NOT_CDS_JAVA_HEAP_RETURN; bool maybe_archive_resolved_klass_at(int cp_index); void remove_unshareable_info(); diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 9eaa85be700..23fe7edf1fb 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -770,9 +770,9 @@ void ConstantPoolCache::clear_archived_references() { } } -void ConstantPoolCache::set_archived_references(oop o) { +void ConstantPoolCache::set_archived_references(int root_index) { assert(DumpSharedSpaces, "called only during runtime"); - _archived_references_index = HeapShared::append_root(o); + _archived_references_index = root_index; } #endif diff --git a/src/hotspot/share/oops/cpCache.hpp b/src/hotspot/share/oops/cpCache.hpp index 98b219384d6..2f81f4be135 100644 --- a/src/hotspot/share/oops/cpCache.hpp +++ b/src/hotspot/share/oops/cpCache.hpp @@ -444,7 +444,7 @@ class ConstantPoolCache: public MetaspaceObj { MetaspaceObj::Type type() const { return ConstantPoolCacheType; } oop archived_references() NOT_CDS_JAVA_HEAP_RETURN_(NULL); - void set_archived_references(oop o) NOT_CDS_JAVA_HEAP_RETURN; + void set_archived_references(int root_index) NOT_CDS_JAVA_HEAP_RETURN; void clear_archived_references() NOT_CDS_JAVA_HEAP_RETURN; inline objArrayOop resolved_references();