< prev index next >

src/hotspot/share/cds/archiveHeapWriter.cpp

Print this page
@@ -25,10 +25,11 @@
  #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"

@@ -59,10 +60,15 @@
  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*

@@ -92,10 +98,15 @@
  
      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,

@@ -142,22 +153,22 @@
    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;
    }
  }
  

@@ -315,25 +326,31 @@
  
    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;

@@ -418,11 +435,29 @@
  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

@@ -651,11 +686,11 @@
    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());

@@ -703,20 +738,13 @@
      _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 {

@@ -734,11 +762,11 @@
    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");
  

@@ -755,10 +783,14 @@
      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 >