< prev index next >

src/hotspot/share/cds/archiveHeapWriter.cpp

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
--- 1,7 ---
  /*
!  * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

*** 25,10 ***
--- 25,12 ---
  #include "precompiled.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/systemDictionary.hpp"
  #include "gc/shared/collectedHeap.hpp"
  #include "memory/iterator.inline.hpp"
  #include "memory/oopFactory.hpp"
  #include "memory/universe.hpp"

*** 57,10 ***
--- 59,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*

*** 313,17 ***
--- 320,22 ---
      oop src_obj = _source_objs->at(src_obj_index);
      HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache()->get(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);
      _buffer_offset_to_source_obj_table->maybe_grow();
    }
  
    log_info(cds)("Size of heap region = " SIZE_FORMAT " bytes, %d objects, %d roots, %d native ptrs",
                  _buffer_used, _source_objs->length() + 1, roots->length(), _num_native_ptrs);
+   log_info(cds)("   strings            = " SIZE_FORMAT_W(8) " (" SIZE_FORMAT " bytes)", _num_strings, _string_bytes);
+   log_info(cds)("   packages           = " SIZE_FORMAT_W(8), _num_packages);
+   log_info(cds)("   protection domains = " SIZE_FORMAT_W(8),_num_protection_domains);
  }
  
  size_t ArchiveHeapWriter::filler_array_byte_size(int length) {
    size_t byte_size = objArrayOopDesc::object_size(length) * HeapWordSize;
    return byte_size;

*** 404,11 ***
--- 416,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

*** 525,11 ***
    return CompressedOops::decode(*buffered_addr);
  }
  
  template <typename T> void ArchiveHeapWriter::relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap) {
    oop source_referent = load_source_oop_from_buffer<T>(field_addr_in_buffer);
!   if (!CompressedOops::is_null(source_referent)) {
      oop request_referent = source_obj_to_requested_obj(source_referent);
      store_requested_oop_in_buffer<T>(field_addr_in_buffer, request_referent);
      mark_oop_pointer<T>(field_addr_in_buffer, oopmap);
    }
  }
--- 555,15 ---
    return CompressedOops::decode(*buffered_addr);
  }
  
  template <typename T> void ArchiveHeapWriter::relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap) {
    oop source_referent = load_source_oop_from_buffer<T>(field_addr_in_buffer);
!   if (source_referent != nullptr) {
+     if (java_lang_Class::is_instance(source_referent)) {
+       source_referent = HeapShared::scratch_java_mirror(source_referent);
+       assert(source_referent != nullptr, "must be");
+     }
      oop request_referent = source_obj_to_requested_obj(source_referent);
      store_requested_oop_in_buffer<T>(field_addr_in_buffer, request_referent);
      mark_oop_pointer<T>(field_addr_in_buffer, oopmap);
    }
  }

*** 654,10 ***
--- 688,23 ---
    if (ptr != nullptr) {
      NativePointerInfo info;
      info._src_obj = src_obj;
      info._field_offset = field_offset;
      _native_pointers->append(info);
+     if (!ArchiveBuilder::current()->has_been_archived((address)ptr)) {
+       // Currently we supporting marking of only Method and Klass, both of which are
+       // subtypes of MetaData.
+       ResourceMark rm;
+       log_error(cds, heap)("Native pointer %p is not archived", ptr);
+       if (((Metadata*)ptr)->is_method()) {
+         log_error(cds, heap)("Method: %s", ((Method*)ptr)->external_name());
+       } else {
+         assert(((Metadata*)ptr)->is_klass(), "must be");
+         log_error(cds, heap)("Klass: %s", ((Klass*)ptr)->external_name());
+       }
+       HeapShared::exit_on_error();
+     }
      HeapShared::set_has_native_pointers(src_obj);
      _num_native_ptrs ++;
    }
  }
  

*** 710,10 ***
--- 757,14 ---
  
      Metadata** buffered_field_addr = requested_addr_to_buffered_addr(requested_field_addr);
      Metadata* native_ptr = *buffered_field_addr;
      assert(native_ptr != nullptr, "sanity");
  
+     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 >