8206009: Move CDS java heap object archiving code to heapShared.hpp and heapShared.cpp
Restructure and cleanup java heap object archiving code. Reviewed-by: coleenp, iklam
This commit is contained in:
parent
4f4a2385c5
commit
a2ad8f419f
@ -36,8 +36,9 @@
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/heapShared.inline.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/metaspaceShared.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/fieldStreams.hpp"
|
||||
@ -750,7 +751,7 @@ static void initialize_static_field(fieldDescriptor* fd, Handle mirror, TRAPS) {
|
||||
{
|
||||
assert(fd->signature() == vmSymbols::string_signature(),
|
||||
"just checking");
|
||||
if (DumpSharedSpaces && MetaspaceShared::is_archive_object(mirror())) {
|
||||
if (DumpSharedSpaces && HeapShared::is_archived_object(mirror())) {
|
||||
// Archive the String field and update the pointer.
|
||||
oop s = mirror()->obj_field(fd->offset());
|
||||
oop archived_s = StringTable::create_archived_string(s, CHECK);
|
||||
@ -788,7 +789,7 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) {
|
||||
}
|
||||
|
||||
if (k->is_shared() && k->has_raw_archived_mirror()) {
|
||||
if (MetaspaceShared::open_archive_heap_region_mapped()) {
|
||||
if (HeapShared::open_archive_heap_region_mapped()) {
|
||||
bool present = restore_archived_mirror(k, Handle(), Handle(), Handle(), CHECK);
|
||||
assert(present, "Missing archived mirror for %s", k->external_name());
|
||||
return;
|
||||
@ -1011,14 +1012,14 @@ class ResetMirrorField: public FieldClosure {
|
||||
};
|
||||
|
||||
void java_lang_Class::archive_basic_type_mirrors(TRAPS) {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(),
|
||||
"MetaspaceShared::is_heap_object_archiving_allowed() must be true");
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(),
|
||||
"HeapShared::is_heap_object_archiving_allowed() must be true");
|
||||
|
||||
for (int t = 0; t <= T_VOID; t++) {
|
||||
oop m = Universe::_mirrors[t];
|
||||
if (m != NULL) {
|
||||
// Update the field at _array_klass_offset to point to the relocated array klass.
|
||||
oop archived_m = MetaspaceShared::archive_heap_object(m, THREAD);
|
||||
oop archived_m = HeapShared::archive_heap_object(m, THREAD);
|
||||
assert(archived_m != NULL, "sanity");
|
||||
Klass *ak = (Klass*)(archived_m->metadata_field(_array_klass_offset));
|
||||
assert(ak != NULL || t == T_VOID, "should not be NULL");
|
||||
@ -1071,8 +1072,8 @@ void java_lang_Class::archive_basic_type_mirrors(TRAPS) {
|
||||
// be used at runtime, new mirror object is created for the shared
|
||||
// class. The _has_archived_raw_mirror is cleared also during the process.
|
||||
oop java_lang_Class::archive_mirror(Klass* k, TRAPS) {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(),
|
||||
"MetaspaceShared::is_heap_object_archiving_allowed() must be true");
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(),
|
||||
"HeapShared::is_heap_object_archiving_allowed() must be true");
|
||||
|
||||
// Mirror is already archived
|
||||
if (k->has_raw_archived_mirror()) {
|
||||
@ -1101,7 +1102,7 @@ oop java_lang_Class::archive_mirror(Klass* k, TRAPS) {
|
||||
}
|
||||
|
||||
// Now start archiving the mirror object
|
||||
oop archived_mirror = MetaspaceShared::archive_heap_object(mirror, THREAD);
|
||||
oop archived_mirror = HeapShared::archive_heap_object(mirror, THREAD);
|
||||
if (archived_mirror == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1139,7 +1140,7 @@ oop java_lang_Class::process_archived_mirror(Klass* k, oop mirror,
|
||||
if (k->is_typeArray_klass()) {
|
||||
// The primitive type mirrors are already archived. Get the archived mirror.
|
||||
oop comp_mirror = java_lang_Class::component_mirror(mirror);
|
||||
archived_comp_mirror = MetaspaceShared::find_archived_heap_object(comp_mirror);
|
||||
archived_comp_mirror = HeapShared::find_archived_heap_object(comp_mirror);
|
||||
assert(archived_comp_mirror != NULL, "Must be");
|
||||
} else {
|
||||
assert(k->is_objArray_klass(), "Must be");
|
||||
@ -1202,7 +1203,7 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
|
||||
return true;
|
||||
}
|
||||
|
||||
oop m = MetaspaceShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
|
||||
oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
|
||||
|
||||
if (m == NULL) {
|
||||
return false;
|
||||
@ -1211,7 +1212,7 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
|
||||
log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
|
||||
|
||||
// mirror is archived, restore
|
||||
assert(MetaspaceShared::is_archive_object(m), "must be archived mirror object");
|
||||
assert(HeapShared::is_archived_object(m), "must be archived mirror object");
|
||||
Handle mirror(THREAD, m);
|
||||
|
||||
if (!k->is_array_klass()) {
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/heapShared.inline.hpp"
|
||||
#include "memory/metaspaceShared.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
@ -798,18 +797,17 @@ oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) {
|
||||
oop StringTable::create_archived_string(oop s, Thread* THREAD) {
|
||||
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
|
||||
|
||||
if (MetaspaceShared::is_archive_object(s)) {
|
||||
if (HeapShared::is_archived_object(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
oop new_s = NULL;
|
||||
typeArrayOop v = java_lang_String::value_no_keepalive(s);
|
||||
typeArrayOop new_v =
|
||||
(typeArrayOop)MetaspaceShared::archive_heap_object(v, THREAD);
|
||||
typeArrayOop new_v = (typeArrayOop)HeapShared::archive_heap_object(v, THREAD);
|
||||
if (new_v == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
new_s = MetaspaceShared::archive_heap_object(s, THREAD);
|
||||
new_s = HeapShared::archive_heap_object(s, THREAD);
|
||||
if (new_s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -847,14 +845,14 @@ struct CopyToArchive : StackObj {
|
||||
};
|
||||
|
||||
void StringTable::copy_shared_string_table(CompactHashtableWriter* writer) {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
|
||||
|
||||
CopyToArchive copy(writer);
|
||||
StringTable::the_table()->_local_table->do_scan(Thread::current(), copy);
|
||||
}
|
||||
|
||||
void StringTable::write_to_archive() {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
|
||||
|
||||
_shared_table.reset();
|
||||
int num_buckets = CompactHashtableWriter::default_num_buckets(
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -2037,13 +2038,13 @@ void SystemDictionary::resolve_preloaded_classes(TRAPS) {
|
||||
// ConstantPool::restore_unshareable_info (restores the archived
|
||||
// resolved_references array object).
|
||||
//
|
||||
// MetaspaceShared::fixup_mapped_heap_regions() fills the empty
|
||||
// HeapShared::fixup_mapped_heap_regions() fills the empty
|
||||
// spaces in the archived heap regions and may use
|
||||
// SystemDictionary::Object_klass(), so we can do this only after
|
||||
// Object_klass is resolved. See the above resolve_wk_klasses_through()
|
||||
// call. No mirror objects are accessed/restored in the above call.
|
||||
// Mirrors are restored after java.lang.Class is loaded.
|
||||
MetaspaceShared::fixup_mapped_heap_regions();
|
||||
HeapShared::fixup_mapped_heap_regions();
|
||||
|
||||
// Initialize the constant pool for the Object_class
|
||||
Object_klass()->constants()->restore_unshareable_info(CHECK);
|
||||
|
@ -270,7 +270,7 @@ public:
|
||||
// Check if the object is in open archive
|
||||
static inline bool is_open_archive_object(oop object);
|
||||
// Check if the object is either in closed archive or open archive
|
||||
static inline bool is_archive_object(oop object);
|
||||
static inline bool is_archived_object(oop object);
|
||||
|
||||
private:
|
||||
static bool _archive_check_enabled;
|
||||
|
@ -141,7 +141,7 @@ inline bool G1ArchiveAllocator::is_open_archive_object(oop object) {
|
||||
return (archive_check_enabled() && in_open_archive_range(object));
|
||||
}
|
||||
|
||||
inline bool G1ArchiveAllocator::is_archive_object(oop object) {
|
||||
inline bool G1ArchiveAllocator::is_archived_object(oop object) {
|
||||
return (archive_check_enabled() && (in_closed_archive_range(object) ||
|
||||
in_open_archive_range(object)));
|
||||
}
|
||||
|
@ -80,7 +80,6 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "memory/metaspaceShared.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "oops/compressedOops.inline.hpp"
|
||||
@ -827,7 +826,7 @@ void G1CollectedHeap::dealloc_archive_regions(MemRegion* ranges, size_t count) {
|
||||
|
||||
oop G1CollectedHeap::materialize_archived_object(oop obj) {
|
||||
assert(obj != NULL, "archived obj is NULL");
|
||||
assert(MetaspaceShared::is_archive_object(obj), "must be archived object");
|
||||
assert(G1ArchiveAllocator::is_archived_object(obj), "must be archived object");
|
||||
|
||||
// Loading an archived object makes it strongly reachable. If it is
|
||||
// loaded during concurrent marking, it must be enqueued to the SATB
|
||||
|
@ -68,7 +68,7 @@ template <class T> inline void G1AdjustClosure::adjust_pointer(T* p) {
|
||||
|
||||
oop obj = CompressedOops::decode_not_null(heap_oop);
|
||||
assert(Universe::heap()->is_in(obj), "should be in heap");
|
||||
if (G1ArchiveAllocator::is_archive_object(obj)) {
|
||||
if (G1ArchiveAllocator::is_archived_object(obj)) {
|
||||
// We never forward archive objects.
|
||||
return;
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ public:
|
||||
oop obj = RawAccess<>::oop_load(p);
|
||||
|
||||
if (_hr->is_open_archive()) {
|
||||
guarantee(obj == NULL || G1ArchiveAllocator::is_archive_object(obj),
|
||||
guarantee(obj == NULL || G1ArchiveAllocator::is_archived_object(obj),
|
||||
"Archive object at " PTR_FORMAT " references a non-archive object at " PTR_FORMAT,
|
||||
p2i(p), p2i(obj));
|
||||
} else {
|
||||
|
@ -191,7 +191,7 @@ void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
|
||||
_shared_path_table_size = mapinfo->_shared_path_table_size;
|
||||
_shared_path_table = mapinfo->_shared_path_table;
|
||||
_shared_path_entry_size = mapinfo->_shared_path_entry_size;
|
||||
if (MetaspaceShared::is_heap_object_archiving_allowed()) {
|
||||
if (HeapShared::is_heap_object_archiving_allowed()) {
|
||||
_heap_reserved = Universe::heap()->reserved_region();
|
||||
}
|
||||
|
||||
@ -908,7 +908,7 @@ MemRegion FileMapInfo::get_heap_regions_range_with_current_oop_encoding_mode() {
|
||||
// regions may be added. GC may mark and update references in the mapped
|
||||
// open archive objects.
|
||||
void FileMapInfo::map_heap_regions_impl() {
|
||||
if (!MetaspaceShared::is_heap_object_archiving_allowed()) {
|
||||
if (!HeapShared::is_heap_object_archiving_allowed()) {
|
||||
log_info(cds)("CDS heap data is being ignored. UseG1GC, "
|
||||
"UseCompressedOops and UseCompressedClassPointers are required.");
|
||||
return;
|
||||
@ -1000,7 +1000,7 @@ void FileMapInfo::map_heap_regions_impl() {
|
||||
MetaspaceShared::max_open_archive_heap_region,
|
||||
&num_open_archive_heap_ranges,
|
||||
true /* open */)) {
|
||||
MetaspaceShared::set_open_archive_heap_region_mapped();
|
||||
HeapShared::set_open_archive_heap_region_mapped();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1014,7 +1014,7 @@ void FileMapInfo::map_heap_regions() {
|
||||
assert(string_ranges == NULL && num_string_ranges == 0, "sanity");
|
||||
}
|
||||
|
||||
if (!MetaspaceShared::open_archive_heap_region_mapped()) {
|
||||
if (!HeapShared::open_archive_heap_region_mapped()) {
|
||||
assert(open_archive_heap_ranges == NULL && num_open_archive_heap_ranges == 0, "sanity");
|
||||
}
|
||||
}
|
||||
@ -1160,7 +1160,7 @@ bool FileMapInfo::verify_region_checksum(int i) {
|
||||
if ((MetaspaceShared::is_string_region(i) &&
|
||||
!StringTable::shared_string_mapped()) ||
|
||||
(MetaspaceShared::is_open_archive_heap_region(i) &&
|
||||
!MetaspaceShared::open_archive_heap_region_mapped())) {
|
||||
!HeapShared::open_archive_heap_region_mapped())) {
|
||||
return true; // archived heap data is not mapped
|
||||
}
|
||||
const char* buf = region_addr(i);
|
||||
|
@ -24,25 +24,200 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logMessage.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/heapShared.inline.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
#include "memory/metaspaceShared.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compressedOops.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/fieldDescriptor.inline.hpp"
|
||||
#include "runtime/safepointVerifiers.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#if INCLUDE_G1GC
|
||||
#include "gc/g1/g1CollectedHeap.hpp"
|
||||
#endif
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
bool HeapShared::_open_archive_heap_region_mapped = false;
|
||||
bool HeapShared::_archive_heap_region_fixed = false;
|
||||
|
||||
address HeapShared::_narrow_oop_base;
|
||||
int HeapShared::_narrow_oop_shift;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Java heap object archiving support
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void HeapShared::fixup_mapped_heap_regions() {
|
||||
FileMapInfo *mapinfo = FileMapInfo::current_info();
|
||||
mapinfo->fixup_mapped_heap_regions();
|
||||
set_archive_heap_region_fixed();
|
||||
}
|
||||
|
||||
unsigned HeapShared::oop_hash(oop const& p) {
|
||||
assert(!p->mark()->has_bias_pattern(),
|
||||
"this object should never have been locked"); // so identity_hash won't safepoin
|
||||
unsigned hash = (unsigned)p->identity_hash();
|
||||
return hash;
|
||||
}
|
||||
|
||||
HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = NULL;
|
||||
oop HeapShared::find_archived_heap_object(oop obj) {
|
||||
assert(DumpSharedSpaces, "dump-time only");
|
||||
ArchivedObjectCache* cache = archived_object_cache();
|
||||
oop* p = cache->get(obj);
|
||||
if (p != NULL) {
|
||||
return *p;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
oop HeapShared::archive_heap_object(oop obj, Thread* THREAD) {
|
||||
assert(DumpSharedSpaces, "dump-time only");
|
||||
|
||||
oop ao = find_archived_heap_object(obj);
|
||||
if (ao != NULL) {
|
||||
// already archived
|
||||
return ao;
|
||||
}
|
||||
|
||||
int len = obj->size();
|
||||
if (G1CollectedHeap::heap()->is_archive_alloc_too_large(len)) {
|
||||
log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT,
|
||||
p2i(obj), (size_t)obj->size());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Pre-compute object identity hash at CDS dump time.
|
||||
obj->identity_hash();
|
||||
|
||||
oop archived_oop = (oop)G1CollectedHeap::heap()->archive_mem_allocate(len);
|
||||
if (archived_oop != NULL) {
|
||||
Copy::aligned_disjoint_words((HeapWord*)obj, (HeapWord*)archived_oop, len);
|
||||
MetaspaceShared::relocate_klass_ptr(archived_oop);
|
||||
ArchivedObjectCache* cache = archived_object_cache();
|
||||
cache->put(obj, archived_oop);
|
||||
log_debug(cds, heap)("Archived heap object " PTR_FORMAT " ==> " PTR_FORMAT,
|
||||
p2i(obj), p2i(archived_oop));
|
||||
} else {
|
||||
log_error(cds, heap)(
|
||||
"Cannot allocate space for object " PTR_FORMAT " in archived heap region",
|
||||
p2i(obj));
|
||||
vm_exit(1);
|
||||
}
|
||||
return archived_oop;
|
||||
}
|
||||
|
||||
oop HeapShared::materialize_archived_object(narrowOop v) {
|
||||
assert(archive_heap_region_fixed(),
|
||||
"must be called after archive heap regions are fixed");
|
||||
if (!CompressedOops::is_null(v)) {
|
||||
oop obj = HeapShared::decode_from_archive(v);
|
||||
return G1CollectedHeap::heap()->materialize_archived_object(obj);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void HeapShared::archive_klass_objects(Thread* THREAD) {
|
||||
GrowableArray<Klass*>* klasses = MetaspaceShared::collected_klasses();
|
||||
assert(klasses != NULL, "sanity");
|
||||
for (int i = 0; i < klasses->length(); i++) {
|
||||
Klass* k = klasses->at(i);
|
||||
|
||||
// archive mirror object
|
||||
java_lang_Class::archive_mirror(k, CHECK);
|
||||
|
||||
// archive the resolved_referenes array
|
||||
if (k->is_instance_klass()) {
|
||||
InstanceKlass* ik = InstanceKlass::cast(k);
|
||||
ik->constants()->archive_resolved_references(THREAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HeapShared::archive_java_heap_objects(GrowableArray<MemRegion> *closed,
|
||||
GrowableArray<MemRegion> *open) {
|
||||
if (!is_heap_object_archiving_allowed()) {
|
||||
if (log_is_enabled(Info, cds)) {
|
||||
log_info(cds)(
|
||||
"Archived java heap is not supported 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));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
NoSafepointVerifier nsv;
|
||||
|
||||
// Cache for recording where the archived objects are copied to
|
||||
create_archived_object_cache();
|
||||
|
||||
tty->print_cr("Dumping objects to closed archive heap region ...");
|
||||
NOT_PRODUCT(StringTable::verify());
|
||||
copy_closed_archive_heap_objects(closed);
|
||||
|
||||
tty->print_cr("Dumping objects to open archive heap region ...");
|
||||
copy_open_archive_heap_objects(open);
|
||||
|
||||
destroy_archived_object_cache();
|
||||
}
|
||||
|
||||
G1HeapVerifier::verify_archive_regions();
|
||||
}
|
||||
|
||||
void HeapShared::copy_closed_archive_heap_objects(
|
||||
GrowableArray<MemRegion> * closed_archive) {
|
||||
assert(is_heap_object_archiving_allowed(), "Cannot archive java heap objects");
|
||||
|
||||
Thread* THREAD = Thread::current();
|
||||
G1CollectedHeap::heap()->begin_archive_alloc_range();
|
||||
|
||||
// Archive interned string objects
|
||||
StringTable::write_to_archive();
|
||||
|
||||
G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
|
||||
os::vm_allocation_granularity());
|
||||
}
|
||||
|
||||
void HeapShared::copy_open_archive_heap_objects(
|
||||
GrowableArray<MemRegion> * open_archive) {
|
||||
assert(is_heap_object_archiving_allowed(), "Cannot archive java heap objects");
|
||||
|
||||
Thread* THREAD = Thread::current();
|
||||
G1CollectedHeap::heap()->begin_archive_alloc_range(true /* open */);
|
||||
|
||||
java_lang_Class::archive_basic_type_mirrors(THREAD);
|
||||
|
||||
archive_klass_objects(THREAD);
|
||||
|
||||
archive_object_subgraphs(THREAD);
|
||||
|
||||
G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
|
||||
os::vm_allocation_granularity());
|
||||
}
|
||||
|
||||
void HeapShared::init_narrow_oop_decoding(address base, int shift) {
|
||||
_narrow_oop_base = base;
|
||||
_narrow_oop_shift = shift;
|
||||
}
|
||||
|
||||
//
|
||||
// Subgraph archiving support
|
||||
//
|
||||
HeapShared::DumpTimeKlassSubGraphInfoTable* HeapShared::_dump_time_subgraph_info_table = NULL;
|
||||
HeapShared::RunTimeKlassSubGraphInfoTable HeapShared::_run_time_subgraph_info_table;
|
||||
|
||||
@ -214,7 +389,7 @@ void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) {
|
||||
}
|
||||
|
||||
void HeapShared::initialize_from_archived_subgraph(Klass* k) {
|
||||
if (!MetaspaceShared::open_archive_heap_region_mapped()) {
|
||||
if (!open_archive_heap_region_mapped()) {
|
||||
return; // nothing to do
|
||||
}
|
||||
assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces");
|
||||
@ -274,8 +449,7 @@ void HeapShared::initialize_from_archived_subgraph(Klass* k) {
|
||||
// The object refereced by the field becomes 'known' by GC from this
|
||||
// point. All objects in the subgraph reachable from the object are
|
||||
// also 'known' by GC.
|
||||
oop v = MetaspaceShared::materialize_archived_object(
|
||||
entry_field_records->at(i+1));
|
||||
oop v = materialize_archived_object(entry_field_records->at(i+1));
|
||||
m->obj_field_put(field_offset, v);
|
||||
i += 2;
|
||||
|
||||
@ -310,7 +484,7 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
|
||||
template <class T> void do_oop_work(T *p) {
|
||||
oop obj = RawAccess<>::oop_load(p);
|
||||
if (!CompressedOops::is_null(obj)) {
|
||||
assert(!MetaspaceShared::is_archive_object(obj),
|
||||
assert(!HeapShared::is_archived_object(obj),
|
||||
"original objects must not point to archived objects");
|
||||
|
||||
size_t field_delta = pointer_delta(p, _orig_referencing_obj, sizeof(char));
|
||||
@ -329,7 +503,7 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
|
||||
|
||||
oop archived = HeapShared::archive_reachable_objects_from(_level + 1, _subgraph_info, obj, THREAD);
|
||||
assert(archived != NULL, "VM should have exited with unarchivable objects for _level > 1");
|
||||
assert(MetaspaceShared::is_archive_object(archived), "must be");
|
||||
assert(HeapShared::is_archived_object(archived), "must be");
|
||||
|
||||
if (!_record_klasses_only) {
|
||||
// Update the reference in the archived copy of the referencing object.
|
||||
@ -347,7 +521,7 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
|
||||
// (3) Record the klasses of all orig_obj and all reachable objects.
|
||||
oop HeapShared::archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, oop orig_obj, TRAPS) {
|
||||
assert(orig_obj != NULL, "must be");
|
||||
assert(!MetaspaceShared::is_archive_object(orig_obj), "sanity");
|
||||
assert(!is_archived_object(orig_obj), "sanity");
|
||||
|
||||
// java.lang.Class instances cannot be included in an archived
|
||||
// object sub-graph.
|
||||
@ -356,7 +530,7 @@ oop HeapShared::archive_reachable_objects_from(int level, KlassSubGraphInfo* sub
|
||||
vm_exit(1);
|
||||
}
|
||||
|
||||
oop archived_obj = MetaspaceShared::find_archived_heap_object(orig_obj);
|
||||
oop archived_obj = find_archived_heap_object(orig_obj);
|
||||
if (java_lang_String::is_instance(orig_obj) && archived_obj != NULL) {
|
||||
// To save time, don't walk strings that are already archived. They just contain
|
||||
// pointers to a type array, whose klass doesn't need to be recorded.
|
||||
@ -373,7 +547,7 @@ oop HeapShared::archive_reachable_objects_from(int level, KlassSubGraphInfo* sub
|
||||
bool record_klasses_only = (archived_obj != NULL);
|
||||
if (archived_obj == NULL) {
|
||||
++_num_new_archived_objs;
|
||||
archived_obj = MetaspaceShared::archive_heap_object(orig_obj, THREAD);
|
||||
archived_obj = archive_heap_object(orig_obj, THREAD);
|
||||
if (archived_obj == NULL) {
|
||||
// Skip archiving the sub-graph referenced from the current entry field.
|
||||
ResourceMark rm;
|
||||
@ -447,7 +621,7 @@ void HeapShared::archive_reachable_objects_from_static_field(InstanceKlass *k,
|
||||
assert(k->is_shared_boot_class(), "must be boot class");
|
||||
|
||||
oop m = k->java_mirror();
|
||||
oop archived_m = MetaspaceShared::find_archived_heap_object(m);
|
||||
oop archived_m = find_archived_heap_object(m);
|
||||
if (CompressedOops::is_null(archived_m)) {
|
||||
return;
|
||||
}
|
||||
@ -508,7 +682,7 @@ void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_o
|
||||
assert(k->is_shared_boot_class(), "must be boot class");
|
||||
|
||||
oop m = k->java_mirror();
|
||||
oop archived_m = MetaspaceShared::find_archived_heap_object(m);
|
||||
oop archived_m = find_archived_heap_object(m);
|
||||
if (CompressedOops::is_null(archived_m)) {
|
||||
return;
|
||||
}
|
||||
@ -519,7 +693,7 @@ void HeapShared::verify_subgraph_from_static_field(InstanceKlass* k, int field_o
|
||||
}
|
||||
|
||||
void HeapShared::verify_subgraph_from(oop orig_obj) {
|
||||
oop archived_obj = MetaspaceShared::find_archived_heap_object(orig_obj);
|
||||
oop archived_obj = find_archived_heap_object(orig_obj);
|
||||
if (archived_obj == NULL) {
|
||||
// It's OK for the root of a subgraph to be not archived. See comments in
|
||||
// archive_reachable_objects_from().
|
||||
@ -546,11 +720,11 @@ void HeapShared::verify_reachable_objects_from(oop obj, bool is_archived) {
|
||||
set_has_been_seen_during_subgraph_recording(obj);
|
||||
|
||||
if (is_archived) {
|
||||
assert(MetaspaceShared::is_archive_object(obj), "must be");
|
||||
assert(MetaspaceShared::find_archived_heap_object(obj) == NULL, "must be");
|
||||
assert(is_archived_object(obj), "must be");
|
||||
assert(find_archived_heap_object(obj) == NULL, "must be");
|
||||
} else {
|
||||
assert(!MetaspaceShared::is_archive_object(obj), "must be");
|
||||
assert(MetaspaceShared::find_archived_heap_object(obj) != NULL, "must be");
|
||||
assert(!is_archived_object(obj), "must be");
|
||||
assert(find_archived_heap_object(obj) != NULL, "must be");
|
||||
}
|
||||
|
||||
VerifySharedOopClosure walker(is_archived);
|
||||
@ -670,7 +844,7 @@ void HeapShared::init_archivable_static_fields(Thread* THREAD) {
|
||||
}
|
||||
}
|
||||
|
||||
void HeapShared::archive_static_fields(Thread* THREAD) {
|
||||
void HeapShared::archive_object_subgraphs(Thread* THREAD) {
|
||||
// For each class X that has one or more archived fields:
|
||||
// [1] Dump the subgraph of each archived field
|
||||
// [2] Create a list of all the class of the objects that can be reached
|
||||
@ -767,11 +941,6 @@ ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) {
|
||||
return oopmap;
|
||||
}
|
||||
|
||||
void HeapShared::init_narrow_oop_decoding(address base, int shift) {
|
||||
_narrow_oop_base = base;
|
||||
_narrow_oop_shift = shift;
|
||||
}
|
||||
|
||||
// Patch all the embedded oop pointers inside an archived heap region,
|
||||
// to be consistent with the runtime oop encoding.
|
||||
class PatchEmbeddedPointers: public BitMapClosure {
|
||||
|
@ -107,7 +107,22 @@ class ArchivedKlassSubGraphInfoRecord {
|
||||
class HeapShared: AllStatic {
|
||||
friend class VerifySharedOopClosure;
|
||||
private:
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
static bool _open_archive_heap_region_mapped;
|
||||
static bool _archive_heap_region_fixed;
|
||||
|
||||
static bool oop_equals(oop const& p1, oop const& p2) {
|
||||
return oopDesc::equals(p1, p2);
|
||||
}
|
||||
static unsigned oop_hash(oop const& p);
|
||||
|
||||
typedef ResourceHashtable<oop, oop,
|
||||
HeapShared::oop_hash,
|
||||
HeapShared::oop_equals,
|
||||
15889, // prime number
|
||||
ResourceObj::C_HEAP> ArchivedObjectCache;
|
||||
static ArchivedObjectCache* _archived_object_cache;
|
||||
|
||||
static bool klass_equals(Klass* const& p1, Klass* const& p2) {
|
||||
return primitive_equals<Klass*>(p1, p2);
|
||||
@ -164,14 +179,6 @@ class HeapShared: AllStatic {
|
||||
static address _narrow_oop_base;
|
||||
static int _narrow_oop_shift;
|
||||
|
||||
static bool oop_equals(oop const& p1, oop const& p2) {
|
||||
return primitive_equals<oop>(p1, p2);
|
||||
}
|
||||
|
||||
static unsigned oop_hash(oop const& p) {
|
||||
return primitive_hash<address>((address)p);
|
||||
}
|
||||
|
||||
typedef ResourceHashtable<oop, bool,
|
||||
HeapShared::oop_hash,
|
||||
HeapShared::oop_equals,
|
||||
@ -207,8 +214,60 @@ class HeapShared: AllStatic {
|
||||
|
||||
static bool has_been_seen_during_subgraph_recording(oop obj);
|
||||
static void set_has_been_seen_during_subgraph_recording(oop obj);
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
public:
|
||||
static void create_archived_object_cache() {
|
||||
_archived_object_cache =
|
||||
new (ResourceObj::C_HEAP, mtClass)ArchivedObjectCache();
|
||||
}
|
||||
static void destroy_archived_object_cache() {
|
||||
delete _archived_object_cache;
|
||||
_archived_object_cache = NULL;
|
||||
}
|
||||
static ArchivedObjectCache* archived_object_cache() {
|
||||
return _archived_object_cache;
|
||||
}
|
||||
|
||||
static oop find_archived_heap_object(oop obj);
|
||||
static oop archive_heap_object(oop obj, Thread* THREAD);
|
||||
static oop materialize_archived_object(narrowOop v);
|
||||
|
||||
static void archive_klass_objects(Thread* THREAD);
|
||||
|
||||
static void set_archive_heap_region_fixed() {
|
||||
_archive_heap_region_fixed = true;
|
||||
}
|
||||
static bool archive_heap_region_fixed() {
|
||||
return _archive_heap_region_fixed;
|
||||
}
|
||||
|
||||
static void archive_java_heap_objects(GrowableArray<MemRegion> *closed,
|
||||
GrowableArray<MemRegion> *open);
|
||||
static void copy_closed_archive_heap_objects(GrowableArray<MemRegion> * closed_archive);
|
||||
static void copy_open_archive_heap_objects(GrowableArray<MemRegion> * open_archive);
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
public:
|
||||
static bool is_heap_object_archiving_allowed() {
|
||||
CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);)
|
||||
NOT_CDS_JAVA_HEAP(return false;)
|
||||
}
|
||||
|
||||
static void set_open_archive_heap_region_mapped() {
|
||||
CDS_JAVA_HEAP_ONLY(_open_archive_heap_region_mapped = true);
|
||||
NOT_CDS_JAVA_HEAP_RETURN;
|
||||
}
|
||||
static bool open_archive_heap_region_mapped() {
|
||||
CDS_JAVA_HEAP_ONLY(return _open_archive_heap_region_mapped);
|
||||
NOT_CDS_JAVA_HEAP_RETURN_(false);
|
||||
}
|
||||
|
||||
static void fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
inline static bool is_archived_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
|
||||
|
||||
static void archive_java_heap_objects() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
static char* read_archived_subgraph_infos(char* buffer) NOT_CDS_JAVA_HEAP_RETURN_(buffer);
|
||||
static void write_archived_subgraph_infos() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void initialize_from_archived_subgraph(Klass* k) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
@ -225,7 +284,7 @@ class HeapShared: AllStatic {
|
||||
size_t oopmap_in_bits) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
static void init_archivable_static_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void archive_static_fields(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void archive_object_subgraphs(Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void write_subgraph_info_table() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void serialize_subgraph_info_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
|
@ -27,9 +27,16 @@
|
||||
|
||||
#include "oops/compressedOops.inline.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#if INCLUDE_G1GC
|
||||
#include "gc/g1/g1Allocator.inline.hpp"
|
||||
#endif
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
bool HeapShared::is_archived_object(oop p) {
|
||||
return (p == NULL) ? false : G1ArchiveAllocator::is_archived_object(p);
|
||||
}
|
||||
|
||||
inline oop HeapShared::decode_from_archive(narrowOop v) {
|
||||
assert(!CompressedOops::is_null(v), "narrow oop value can never be zero");
|
||||
oop result = (oop)(void*)((uintptr_t)_narrow_oop_base + ((uintptr_t)v << _narrow_oop_shift));
|
||||
|
@ -75,8 +75,6 @@ MetaspaceSharedStats MetaspaceShared::_stats;
|
||||
bool MetaspaceShared::_has_error_classes;
|
||||
bool MetaspaceShared::_archive_loading_failed = false;
|
||||
bool MetaspaceShared::_remapped_readwrite = false;
|
||||
bool MetaspaceShared::_open_archive_heap_region_mapped = false;
|
||||
bool MetaspaceShared::_archive_heap_region_fixed = false;
|
||||
address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
|
||||
size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
|
||||
size_t MetaspaceShared::_core_spaces_size = 0;
|
||||
@ -108,7 +106,7 @@ size_t MetaspaceShared::_core_spaces_size = 0;
|
||||
// [5] C++ vtables are copied into the md region.
|
||||
// [6] Original class files are copied into the od region.
|
||||
//
|
||||
// The s0/s1 and oa0/oa1 regions are populated inside MetaspaceShared::dump_java_heap_objects.
|
||||
// The s0/s1 and oa0/oa1 regions are populated inside HeapShared::archive_java_heap_objects.
|
||||
// Their layout is independent of the other 5 regions.
|
||||
|
||||
class DumpRegion {
|
||||
@ -454,6 +452,10 @@ address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
|
||||
// is run at a safepoint just before exit, this is the entire set of classes.
|
||||
static GrowableArray<Klass*>* _global_klass_objects;
|
||||
|
||||
GrowableArray<Klass*>* MetaspaceShared::collected_klasses() {
|
||||
return _global_klass_objects;
|
||||
}
|
||||
|
||||
static void collect_array_classes(Klass* k) {
|
||||
_global_klass_objects->append_if_missing(k);
|
||||
if (k->is_array_klass()) {
|
||||
@ -512,7 +514,7 @@ static void remove_java_mirror_in_classes() {
|
||||
}
|
||||
|
||||
static void clear_basic_type_mirrors() {
|
||||
assert(!MetaspaceShared::is_heap_object_archiving_allowed(), "Sanity");
|
||||
assert(!HeapShared::is_heap_object_archiving_allowed(), "Sanity");
|
||||
Universe::set_int_mirror(NULL);
|
||||
Universe::set_float_mirror(NULL);
|
||||
Universe::set_double_mirror(NULL);
|
||||
@ -850,7 +852,7 @@ public:
|
||||
if (*o == NULL) {
|
||||
_dump_region->append_intptr_t(0);
|
||||
} else {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(),
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(),
|
||||
"Archiving heap object is not allowed");
|
||||
_dump_region->append_intptr_t(
|
||||
(intptr_t)CompressedOops::encode_not_null(*o));
|
||||
@ -1329,7 +1331,7 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables() {
|
||||
SystemDictionary::reorder_dictionary_for_sharing();
|
||||
|
||||
tty->print("Removing java_mirror ... ");
|
||||
if (!MetaspaceShared::is_heap_object_archiving_allowed()) {
|
||||
if (!HeapShared::is_heap_object_archiving_allowed()) {
|
||||
clear_basic_type_mirrors();
|
||||
}
|
||||
remove_java_mirror_in_classes();
|
||||
@ -1798,47 +1800,18 @@ bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) {
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
void VM_PopulateDumpSharedSpace::dump_java_heap_objects() {
|
||||
if (!MetaspaceShared::is_heap_object_archiving_allowed()) {
|
||||
if (log_is_enabled(Info, cds)) {
|
||||
log_info(cds)(
|
||||
"Archived java heap is not supported 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));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
NoSafepointVerifier nsv;
|
||||
|
||||
// Cache for recording where the archived objects are copied to
|
||||
MetaspaceShared::create_archive_object_cache();
|
||||
|
||||
tty->print_cr("Dumping objects to closed archive heap region ...");
|
||||
NOT_PRODUCT(StringTable::verify());
|
||||
// The closed space has maximum two regions. See FileMapInfo::write_archive_heap_regions() for details.
|
||||
_closed_archive_heap_regions = new GrowableArray<MemRegion>(2);
|
||||
MetaspaceShared::dump_closed_archive_heap_objects(_closed_archive_heap_regions);
|
||||
|
||||
tty->print_cr("Dumping objects to open archive heap region ...");
|
||||
_open_archive_heap_regions = new GrowableArray<MemRegion>(2);
|
||||
MetaspaceShared::dump_open_archive_heap_objects(_open_archive_heap_regions);
|
||||
|
||||
MetaspaceShared::destroy_archive_object_cache();
|
||||
}
|
||||
|
||||
G1HeapVerifier::verify_archive_regions();
|
||||
|
||||
{
|
||||
ArchiveCompactor::OtherROAllocMark mark;
|
||||
HeapShared::write_subgraph_info_table();
|
||||
}
|
||||
// The closed and open archive heap space has maximum two regions.
|
||||
// See FileMapInfo::write_archive_heap_regions() for details.
|
||||
_closed_archive_heap_regions = new GrowableArray<MemRegion>(2);
|
||||
_open_archive_heap_regions = new GrowableArray<MemRegion>(2);
|
||||
HeapShared::archive_java_heap_objects(_closed_archive_heap_regions,
|
||||
_open_archive_heap_regions);
|
||||
ArchiveCompactor::OtherROAllocMark mark;
|
||||
HeapShared::write_subgraph_info_table();
|
||||
}
|
||||
|
||||
void VM_PopulateDumpSharedSpace::dump_archive_heap_oopmaps() {
|
||||
if (MetaspaceShared::is_heap_object_archiving_allowed()) {
|
||||
if (HeapShared::is_heap_object_archiving_allowed()) {
|
||||
_closed_archive_heap_oopmaps = new GrowableArray<ArchiveHeapOopmapInfo>(2);
|
||||
dump_archive_heap_oopmaps(_closed_archive_heap_regions, _closed_archive_heap_oopmaps);
|
||||
|
||||
@ -1866,124 +1839,6 @@ void VM_PopulateDumpSharedSpace::dump_archive_heap_oopmaps(GrowableArray<MemRegi
|
||||
oopmaps->append(info);
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceShared::dump_closed_archive_heap_objects(
|
||||
GrowableArray<MemRegion> * closed_archive) {
|
||||
assert(is_heap_object_archiving_allowed(), "Cannot dump java heap objects");
|
||||
|
||||
Thread* THREAD = Thread::current();
|
||||
G1CollectedHeap::heap()->begin_archive_alloc_range();
|
||||
|
||||
// Archive interned string objects
|
||||
StringTable::write_to_archive();
|
||||
|
||||
G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
|
||||
os::vm_allocation_granularity());
|
||||
}
|
||||
|
||||
void MetaspaceShared::dump_open_archive_heap_objects(
|
||||
GrowableArray<MemRegion> * open_archive) {
|
||||
assert(UseG1GC, "Only support G1 GC");
|
||||
assert(UseCompressedOops && UseCompressedClassPointers,
|
||||
"Only support UseCompressedOops and UseCompressedClassPointers enabled");
|
||||
|
||||
Thread* THREAD = Thread::current();
|
||||
G1CollectedHeap::heap()->begin_archive_alloc_range(true /* open */);
|
||||
|
||||
java_lang_Class::archive_basic_type_mirrors(THREAD);
|
||||
|
||||
MetaspaceShared::archive_klass_objects(THREAD);
|
||||
|
||||
HeapShared::archive_static_fields(THREAD);
|
||||
|
||||
G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
|
||||
os::vm_allocation_granularity());
|
||||
}
|
||||
|
||||
unsigned MetaspaceShared::obj_hash(oop const& p) {
|
||||
assert(!p->mark()->has_bias_pattern(),
|
||||
"this object should never have been locked"); // so identity_hash won't safepoint
|
||||
unsigned hash = (unsigned)p->identity_hash();
|
||||
return hash;
|
||||
}
|
||||
|
||||
MetaspaceShared::ArchivedObjectCache* MetaspaceShared::_archive_object_cache = NULL;
|
||||
oop MetaspaceShared::find_archived_heap_object(oop obj) {
|
||||
assert(DumpSharedSpaces, "dump-time only");
|
||||
ArchivedObjectCache* cache = MetaspaceShared::archive_object_cache();
|
||||
oop* p = cache->get(obj);
|
||||
if (p != NULL) {
|
||||
return *p;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
oop MetaspaceShared::archive_heap_object(oop obj, Thread* THREAD) {
|
||||
assert(DumpSharedSpaces, "dump-time only");
|
||||
|
||||
oop ao = find_archived_heap_object(obj);
|
||||
if (ao != NULL) {
|
||||
// already archived
|
||||
return ao;
|
||||
}
|
||||
|
||||
int len = obj->size();
|
||||
if (G1CollectedHeap::heap()->is_archive_alloc_too_large(len)) {
|
||||
log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT,
|
||||
p2i(obj), (size_t)obj->size());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hash = obj->identity_hash();
|
||||
oop archived_oop = (oop)G1CollectedHeap::heap()->archive_mem_allocate(len);
|
||||
if (archived_oop != NULL) {
|
||||
Copy::aligned_disjoint_words((HeapWord*)obj, (HeapWord*)archived_oop, len);
|
||||
relocate_klass_ptr(archived_oop);
|
||||
ArchivedObjectCache* cache = MetaspaceShared::archive_object_cache();
|
||||
cache->put(obj, archived_oop);
|
||||
log_debug(cds, heap)("Archived heap object " PTR_FORMAT " ==> " PTR_FORMAT,
|
||||
p2i(obj), p2i(archived_oop));
|
||||
} else {
|
||||
log_error(cds, heap)(
|
||||
"Cannot allocate space for object " PTR_FORMAT " in archived heap region",
|
||||
p2i(obj));
|
||||
vm_exit(1);
|
||||
}
|
||||
return archived_oop;
|
||||
}
|
||||
|
||||
oop MetaspaceShared::materialize_archived_object(narrowOop v) {
|
||||
assert(archive_heap_region_fixed(),
|
||||
"must be called after archive heap regions are fixed");
|
||||
if (!CompressedOops::is_null(v)) {
|
||||
oop obj = HeapShared::decode_from_archive(v);
|
||||
return G1CollectedHeap::heap()->materialize_archived_object(obj);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MetaspaceShared::archive_klass_objects(Thread* THREAD) {
|
||||
int i;
|
||||
for (i = 0; i < _global_klass_objects->length(); i++) {
|
||||
Klass* k = _global_klass_objects->at(i);
|
||||
|
||||
// archive mirror object
|
||||
java_lang_Class::archive_mirror(k, CHECK);
|
||||
|
||||
// archive the resolved_referenes array
|
||||
if (k->is_instance_klass()) {
|
||||
InstanceKlass* ik = InstanceKlass::cast(k);
|
||||
ik->constants()->archive_resolved_references(THREAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetaspaceShared::fixup_mapped_heap_regions() {
|
||||
FileMapInfo *mapinfo = FileMapInfo::current_info();
|
||||
mapinfo->fixup_mapped_heap_regions();
|
||||
set_archive_heap_region_fixed();
|
||||
}
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
// Closure for serializing initialization data in from a data area
|
||||
@ -2023,12 +1878,12 @@ public:
|
||||
|
||||
void do_oop(oop *p) {
|
||||
narrowOop o = (narrowOop)nextPtr();
|
||||
if (o == 0 || !MetaspaceShared::open_archive_heap_region_mapped()) {
|
||||
if (o == 0 || !HeapShared::open_archive_heap_region_mapped()) {
|
||||
p = NULL;
|
||||
} else {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(),
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(),
|
||||
"Archived heap object is not allowed");
|
||||
assert(MetaspaceShared::open_archive_heap_region_mapped(),
|
||||
assert(HeapShared::open_archive_heap_region_mapped(),
|
||||
"Open archive heap region is not mapped");
|
||||
*p = HeapShared::decode_from_archive(o);
|
||||
}
|
||||
|
@ -58,8 +58,6 @@ class MetaspaceShared : AllStatic {
|
||||
static bool _has_error_classes;
|
||||
static bool _archive_loading_failed;
|
||||
static bool _remapped_readwrite;
|
||||
static bool _open_archive_heap_region_mapped;
|
||||
static bool _archive_heap_region_fixed;
|
||||
static address _cds_i2i_entry_code_buffers;
|
||||
static size_t _cds_i2i_entry_code_buffers_size;
|
||||
static size_t _core_spaces_size;
|
||||
@ -93,63 +91,7 @@ class MetaspaceShared : AllStatic {
|
||||
static int preload_classes(const char * class_list_path,
|
||||
TRAPS) NOT_CDS_RETURN_(0);
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
private:
|
||||
static bool obj_equals(oop const& p1, oop const& p2) {
|
||||
return p1 == p2;
|
||||
}
|
||||
static unsigned obj_hash(oop const& p);
|
||||
|
||||
typedef ResourceHashtable<oop, oop,
|
||||
MetaspaceShared::obj_hash,
|
||||
MetaspaceShared::obj_equals,
|
||||
15889, // prime number
|
||||
ResourceObj::C_HEAP> ArchivedObjectCache;
|
||||
static ArchivedObjectCache* _archive_object_cache;
|
||||
|
||||
public:
|
||||
static ArchivedObjectCache* archive_object_cache() {
|
||||
return _archive_object_cache;
|
||||
}
|
||||
static oop find_archived_heap_object(oop obj);
|
||||
static oop archive_heap_object(oop obj, Thread* THREAD);
|
||||
static oop materialize_archived_object(narrowOop v);
|
||||
static void archive_klass_objects(Thread* THREAD);
|
||||
|
||||
static void set_archive_heap_region_fixed() {
|
||||
_archive_heap_region_fixed = true;
|
||||
}
|
||||
|
||||
static bool archive_heap_region_fixed() {
|
||||
return _archive_heap_region_fixed;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline static bool is_archive_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
|
||||
|
||||
static bool is_heap_object_archiving_allowed() {
|
||||
CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);)
|
||||
NOT_CDS_JAVA_HEAP(return false;)
|
||||
}
|
||||
static void create_archive_object_cache() {
|
||||
CDS_JAVA_HEAP_ONLY(_archive_object_cache = new (ResourceObj::C_HEAP, mtClass)ArchivedObjectCache(););
|
||||
}
|
||||
static void destroy_archive_object_cache() {
|
||||
CDS_JAVA_HEAP_ONLY(delete _archive_object_cache; _archive_object_cache = NULL;);
|
||||
}
|
||||
static void fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
static void dump_closed_archive_heap_objects(GrowableArray<MemRegion> * closed_archive) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
static void dump_open_archive_heap_objects(GrowableArray<MemRegion> * open_archive) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void set_open_archive_heap_region_mapped() {
|
||||
CDS_JAVA_HEAP_ONLY(_open_archive_heap_region_mapped = true);
|
||||
NOT_CDS_JAVA_HEAP_RETURN;
|
||||
}
|
||||
static bool open_archive_heap_region_mapped() {
|
||||
CDS_JAVA_HEAP_ONLY(return _open_archive_heap_region_mapped);
|
||||
NOT_CDS_JAVA_HEAP_RETURN_(false);
|
||||
}
|
||||
static GrowableArray<Klass*>* collected_klasses();
|
||||
|
||||
static ReservedSpace* shared_rs() {
|
||||
CDS_ONLY(return &_shared_rs);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
@ -242,8 +243,15 @@ void Universe::serialize(SerializeClosure* f) {
|
||||
|
||||
f->do_ptr((void**)&_objectArrayKlassObj);
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
// The mirrors are NULL if MetaspaceShared::is_heap_object_archiving_allowed
|
||||
// is false.
|
||||
#ifdef ASSERT
|
||||
if (DumpSharedSpaces && !HeapShared::is_heap_object_archiving_allowed()) {
|
||||
assert(_int_mirror == NULL && _float_mirror == NULL &&
|
||||
_double_mirror == NULL && _byte_mirror == NULL &&
|
||||
_bool_mirror == NULL && _char_mirror == NULL &&
|
||||
_long_mirror == NULL && _short_mirror == NULL &&
|
||||
_void_mirror == NULL, "mirrors should be NULL");
|
||||
}
|
||||
#endif
|
||||
f->do_oop(&_int_mirror);
|
||||
f->do_oop(&_float_mirror);
|
||||
f->do_oop(&_double_mirror);
|
||||
@ -422,9 +430,9 @@ void Universe::genesis(TRAPS) {
|
||||
void Universe::initialize_basic_type_mirrors(TRAPS) {
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
if (UseSharedSpaces &&
|
||||
MetaspaceShared::open_archive_heap_region_mapped() &&
|
||||
HeapShared::open_archive_heap_region_mapped() &&
|
||||
_int_mirror != NULL) {
|
||||
assert(MetaspaceShared::is_heap_object_archiving_allowed(), "Sanity");
|
||||
assert(HeapShared::is_heap_object_archiving_allowed(), "Sanity");
|
||||
assert(_float_mirror != NULL && _double_mirror != NULL &&
|
||||
_byte_mirror != NULL && _byte_mirror != NULL &&
|
||||
_bool_mirror != NULL && _char_mirror != NULL &&
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
@ -295,7 +296,7 @@ void ConstantPool::archive_resolved_references(Thread* THREAD) {
|
||||
}
|
||||
}
|
||||
|
||||
oop archived = MetaspaceShared::archive_heap_object(rr, THREAD);
|
||||
oop archived = HeapShared::archive_heap_object(rr, THREAD);
|
||||
// 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_heap_object here. At runtime, the
|
||||
@ -340,7 +341,7 @@ void ConstantPool::restore_unshareable_info(TRAPS) {
|
||||
if (SystemDictionary::Object_klass_loaded()) {
|
||||
ClassLoaderData* loader_data = pool_holder()->class_loader_data();
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
if (MetaspaceShared::open_archive_heap_region_mapped() &&
|
||||
if (HeapShared::open_archive_heap_region_mapped() &&
|
||||
_cache->archived_references() != NULL) {
|
||||
oop archived = _cache->archived_references();
|
||||
// Create handle for the archived resolved reference array object
|
||||
@ -373,7 +374,7 @@ void ConstantPool::remove_unshareable_info() {
|
||||
// If archiving heap objects is not allowed, clear the resolved references.
|
||||
// Otherwise, it is cleared after the resolved references array is cached
|
||||
// (see archive_resolved_references()).
|
||||
if (!MetaspaceShared::is_heap_object_archiving_allowed()) {
|
||||
if (!HeapShared::is_heap_object_archiving_allowed()) {
|
||||
set_resolved_references(NULL);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "interpreter/rewriter.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
@ -777,7 +778,7 @@ oop ConstantPoolCache::archived_references() {
|
||||
if (CompressedOops::is_null(_archived_references)) {
|
||||
return NULL;
|
||||
}
|
||||
return MetaspaceShared::materialize_archived_object(_archived_references);
|
||||
return HeapShared::materialize_archived_object(_archived_references);
|
||||
}
|
||||
|
||||
void ConstantPoolCache::set_archived_references(oop o) {
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "gc/shared/collectedHeap.inline.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
@ -542,7 +543,7 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec
|
||||
if (this->has_raw_archived_mirror()) {
|
||||
ResourceMark rm;
|
||||
log_debug(cds, mirror)("%s has raw archived mirror", external_name());
|
||||
if (MetaspaceShared::open_archive_heap_region_mapped()) {
|
||||
if (HeapShared::open_archive_heap_region_mapped()) {
|
||||
bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle,
|
||||
protection_domain,
|
||||
CHECK);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/altHashing.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "memory/metaspaceShared.inline.hpp"
|
||||
#include "memory/heapShared.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
@ -144,8 +144,8 @@ bool oopDesc::is_unlocked_oop() const {
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
bool oopDesc::is_archive_object(oop p) {
|
||||
return MetaspaceShared::is_archive_object(p);
|
||||
bool oopDesc::is_archived_object(oop p) {
|
||||
return HeapShared::is_archived_object(p);
|
||||
}
|
||||
#endif
|
||||
#endif // PRODUCT
|
||||
|
@ -255,7 +255,7 @@ class oopDesc {
|
||||
static bool is_oop_or_null(oop obj, bool ignore_mark_word = false);
|
||||
#ifndef PRODUCT
|
||||
inline bool is_unlocked_oop() const;
|
||||
static bool is_archive_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
|
||||
static bool is_archived_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
|
||||
#endif
|
||||
|
||||
// garbage collection
|
||||
|
@ -351,8 +351,8 @@ void oopDesc::forward_to(oop p) {
|
||||
"forwarding to something not aligned");
|
||||
assert(Universe::heap()->is_in_reserved(p),
|
||||
"forwarding to something not in heap");
|
||||
assert(!is_archive_object(oop(this)) &&
|
||||
!is_archive_object(p),
|
||||
assert(!is_archived_object(oop(this)) &&
|
||||
!is_archived_object(p),
|
||||
"forwarding archive object");
|
||||
markOop m = markOopDesc::encode_pointer_as_mark(p);
|
||||
assert(m->decode_pointer() == p, "encoding must be reversable");
|
||||
|
@ -36,8 +36,9 @@
|
||||
#include "gc/shared/gcConfig.hpp"
|
||||
#include "gc/shared/genCollectedHeap.hpp"
|
||||
#include "jvmtifiles/jvmtiEnv.hpp"
|
||||
#include "memory/heapShared.inline.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceShared.inline.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
@ -1765,7 +1766,7 @@ WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_IsShared(JNIEnv* env, jobject wb, jobject obj))
|
||||
oop obj_oop = JNIHandles::resolve(obj);
|
||||
return MetaspaceShared::is_archive_object(obj_oop);
|
||||
return HeapShared::is_archived_object(obj_oop);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz))
|
||||
@ -1789,7 +1790,7 @@ WB_ENTRY(jobject, WB_GetResolvedReferences(JNIEnv* env, jobject wb, jclass clazz
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env))
|
||||
return MetaspaceShared::open_archive_heap_region_mapped();
|
||||
return HeapShared::open_archive_heap_region_mapped();
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env))
|
||||
@ -1807,7 +1808,7 @@ WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env))
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env))
|
||||
return MetaspaceShared::is_heap_object_archiving_allowed();
|
||||
return HeapShared::is_heap_object_archiving_allowed();
|
||||
WB_END
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user