< prev index next > src/hotspot/share/cds/archiveHeapWriter.cpp
Print this page
#include "cds/aotReferenceObjSupport.hpp"
#include "cds/archiveHeapWriter.hpp"
#include "cds/cdsConfig.hpp"
#include "cds/filemap.hpp"
#include "cds/heapShared.hpp"
+ #include "cds/regeneratedClasses.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/modules.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "memory/iterator.inline.hpp"
HeapRootSegments ArchiveHeapWriter::_heap_root_segments;
address ArchiveHeapWriter::_requested_bottom;
address ArchiveHeapWriter::_requested_top;
+ static size_t _num_strings = 0;
+ static size_t _string_bytes = 0;
+ static size_t _num_packages = 0;
+ static size_t _num_protection_domains = 0;
+
GrowableArrayCHeap<ArchiveHeapWriter::NativePointerInfo, mtClassShared>* ArchiveHeapWriter::_native_pointers;
GrowableArrayCHeap<oop, mtClassShared>* ArchiveHeapWriter::_source_objs;
GrowableArrayCHeap<ArchiveHeapWriter::HeapObjOrder, mtClassShared>* ArchiveHeapWriter::_source_objs_order;
ArchiveHeapWriter::BufferOffsetToSourceObjectTable*
guarantee(MIN_GC_REGION_ALIGNMENT <= G1HeapRegion::min_region_size_in_words() * HeapWordSize, "must be");
}
}
+ void ArchiveHeapWriter::delete_tables_with_raw_oops() {
+ delete _source_objs;
+ _source_objs = nullptr;
+ }
+
void ArchiveHeapWriter::add_source_obj(oop src_obj) {
_source_objs->append(src_obj);
}
void ArchiveHeapWriter::write(GrowableArrayCHeap<oop, mtClassShared>* roots,
return req_obj;
}
oop ArchiveHeapWriter::source_obj_to_requested_obj(oop src_obj) {
assert(CDSConfig::is_dumping_heap(), "dump-time only");
- HeapShared::CachedOopInfo* p = HeapShared::archived_object_cache()->get(src_obj);
+ HeapShared::CachedOopInfo* p = HeapShared::get_cached_oop_info(src_obj);
if (p != nullptr) {
return requested_obj_from_buffer_offset(p->buffer_offset());
} else {
return nullptr;
}
}
oop ArchiveHeapWriter::buffered_addr_to_source_obj(address buffered_addr) {
- oop* p = _buffer_offset_to_source_obj_table->get(buffered_address_to_offset(buffered_addr));
- if (p != nullptr) {
- return *p;
+ OopHandle* oh = _buffer_offset_to_source_obj_table->get(buffered_address_to_offset(buffered_addr));
+ if (oh != nullptr) {
+ return oh->resolve();
} else {
return nullptr;
}
}
sort_source_objs();
for (int i = 0; i < _source_objs_order->length(); i++) {
int src_obj_index = _source_objs_order->at(i)._index;
oop src_obj = _source_objs->at(src_obj_index);
- HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache()->get(src_obj);
+ HeapShared::CachedOopInfo* info = HeapShared::get_cached_oop_info(src_obj);
assert(info != nullptr, "must be");
size_t buffer_offset = copy_one_source_obj_to_buffer(src_obj);
info->set_buffer_offset(buffer_offset);
+ assert(buffer_offset <= 0x7fffffff, "sanity");
+ HeapShared::add_to_permanent_oop_table(src_obj, (int)buffer_offset);
- _buffer_offset_to_source_obj_table->put_when_absent(buffer_offset, src_obj);
+ OopHandle handle(Universe::vm_global(), src_obj);
+ _buffer_offset_to_source_obj_table->put_when_absent(buffer_offset, handle);
_buffer_offset_to_source_obj_table->maybe_grow();
if (java_lang_Module::is_instance(src_obj)) {
Modules::check_archived_module_oop(src_obj);
}
}
log_info(aot)("Size of heap region = %zu bytes, %d objects, %d roots, %d native ptrs",
_buffer_used, _source_objs->length() + 1, roots->length(), _num_native_ptrs);
+ log_info(cds)(" strings = %8zu (%zu bytes)", _num_strings, _string_bytes);
+ log_info(cds)(" packages = %8zu", _num_packages);
+ log_info(cds)(" protection domains = %8zu", _num_protection_domains);
}
size_t ArchiveHeapWriter::filler_array_byte_size(int length) {
size_t byte_size = objArrayOopDesc::object_size(length) * HeapWordSize;
return byte_size;
void update_buffered_object_field(address buffered_obj, int field_offset, T value) {
T* field_addr = cast_to_oop(buffered_obj)->field_addr<T>(field_offset);
*field_addr = value;
}
+ void ArchiveHeapWriter::update_stats(oop src_obj) {
+ if (java_lang_String::is_instance(src_obj)) {
+ _num_strings ++;
+ _string_bytes += src_obj->size() * HeapWordSize;
+ _string_bytes += java_lang_String::value(src_obj)->size() * HeapWordSize;
+ } else {
+ Klass* k = src_obj->klass();
+ Symbol* name = k->name();
+ if (name->equals("java/lang/NamedPackage") || name->equals("java/lang/Package")) {
+ _num_packages ++;
+ } else if (name->equals("java/security/ProtectionDomain")) {
+ _num_protection_domains ++;
+ }
+ }
+ }
+
size_t ArchiveHeapWriter::copy_one_source_obj_to_buffer(oop src_obj) {
+ update_stats(src_obj);
+
assert(!is_too_large_to_archive(src_obj), "already checked");
size_t byte_size = src_obj->size() * HeapWordSize;
assert(byte_size > 0, "no zero-size objects");
// For region-based collectors such as G1, the archive heap may be mapped into
heap_info->oopmap()->resize(heap_region_byte_size / oopmap_unit);
for (int i = 0; i < _source_objs_order->length(); i++) {
int src_obj_index = _source_objs_order->at(i)._index;
oop src_obj = _source_objs->at(src_obj_index);
- HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache()->get(src_obj);
+ HeapShared::CachedOopInfo* info = HeapShared::get_cached_oop_info(src_obj);
assert(info != nullptr, "must be");
oop requested_obj = requested_obj_from_buffer_offset(info->buffer_offset());
update_header_for_requested_obj(requested_obj, src_obj, src_obj->klass());
address buffered_obj = offset_to_buffered_address<address>(info->buffer_offset());
EmbeddedOopRelocator relocator(src_obj, buffered_obj, heap_info->oopmap());
_num_native_ptrs ++;
}
}
// Do we have a jlong/jint field that's actually a pointer to a MetaspaceObj?
- bool ArchiveHeapWriter::is_marked_as_native_pointer(ArchiveHeapInfo* heap_info, oop src_obj, int field_offset) {
- HeapShared::CachedOopInfo* p = HeapShared::archived_object_cache()->get(src_obj);
- assert(p != nullptr, "must be");
-
- // requested_field_addr = the address of this field in the requested space
- oop requested_obj = requested_obj_from_buffer_offset(p->buffer_offset());
- Metadata** requested_field_addr = (Metadata**)(cast_from_oop<address>(requested_obj) + field_offset);
- assert((Metadata**)_requested_bottom <= requested_field_addr && requested_field_addr < (Metadata**) _requested_top, "range check");
-
- BitMap::idx_t idx = requested_field_addr - (Metadata**) _requested_bottom;
+ bool ArchiveHeapWriter::is_marked_as_native_pointer(ArchiveHeapInfo* heap_info, address buffered_obj, int field_offset) {
+ size_t offset = buffered_address_to_offset(buffered_obj) + checked_cast<size_t>(field_offset); // in bytes
+ BitMap::idx_t idx = checked_cast<BitMap::idx_t>(offset) / HeapWordSize;
// Leading zeros have been removed so some addresses may not be in the ptrmap
size_t start_pos = FileMapInfo::current_info()->heap_ptrmap_start_pos();
if (idx < start_pos) {
return false;
} else {
BitMap::idx_t max_idx = 32; // paranoid - don't make it too small
for (int i = 0; i < _native_pointers->length(); i++) {
NativePointerInfo info = _native_pointers->at(i);
oop src_obj = info._src_obj;
int field_offset = info._field_offset;
- HeapShared::CachedOopInfo* p = HeapShared::archived_object_cache()->get(src_obj);
+ HeapShared::CachedOopInfo* p = HeapShared::get_cached_oop_info(src_obj);
// requested_field_addr = the address of this field in the requested space
oop requested_obj = requested_obj_from_buffer_offset(p->buffer_offset());
Metadata** requested_field_addr = (Metadata**)(cast_from_oop<address>(requested_obj) + field_offset);
assert(bottom <= requested_field_addr && requested_field_addr < top, "range check");
Metadata* native_ptr = *buffered_field_addr;
guarantee(native_ptr != nullptr, "sanity");
guarantee(ArchiveBuilder::current()->has_been_buffered((address)native_ptr),
"Metadata %p should have been archived", native_ptr);
+ if (RegeneratedClasses::has_been_regenerated((address)native_ptr)) {
+ native_ptr = (Metadata*)RegeneratedClasses::get_regenerated_object((address)native_ptr);
+ }
+
address buffered_native_ptr = ArchiveBuilder::current()->get_buffered_addr((address)native_ptr);
address requested_native_ptr = ArchiveBuilder::current()->to_requested(buffered_native_ptr);
*buffered_field_addr = (Metadata*)requested_native_ptr;
}
< prev index next >