< prev index next >

src/hotspot/share/cds/archiveBuilder.cpp

Print this page
*** 30,10 ***
--- 30,11 ---
  #include "cds/archiveUtils.hpp"
  #include "cds/cdsConfig.hpp"
  #include "cds/cppVtables.hpp"
  #include "cds/dumpAllocStats.hpp"
  #include "cds/dynamicArchive.hpp"
+ #include "cds/finalImageRecipes.hpp"
  #include "cds/heapShared.hpp"
  #include "cds/metaspaceShared.hpp"
  #include "cds/regeneratedClasses.hpp"
  #include "classfile/classLoader.hpp"
  #include "classfile/classLoaderDataShared.hpp"

*** 51,13 ***
--- 52,16 ---
  #include "memory/memoryReserver.hpp"
  #include "memory/memRegion.hpp"
  #include "memory/resourceArea.hpp"
  #include "oops/compressedKlass.inline.hpp"
  #include "oops/instanceKlass.hpp"
+ #include "oops/methodCounters.hpp"
+ #include "oops/methodData.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oopHandle.inline.hpp"
+ #include "oops/trainingData.hpp"
  #include "runtime/arguments.hpp"
  #include "runtime/fieldDescriptor.inline.hpp"
  #include "runtime/globals_extension.hpp"
  #include "runtime/javaThread.hpp"
  #include "runtime/sharedRuntime.hpp"

*** 128,17 ***
  
    bool do_bit(BitMap::idx_t bit_offset) {
      size_t field_offset = size_t(bit_offset - _start_idx) * sizeof(address);
      address* ptr_loc = (address*)(_buffered_obj + field_offset);
  
!     address old_p = *ptr_loc;
      address new_p = _builder->get_buffered_addr(old_p);
  
!     log_trace(cds)("Ref: [" PTR_FORMAT "] -> " PTR_FORMAT " => " PTR_FORMAT,
!                    p2i(ptr_loc), p2i(old_p), p2i(new_p));
  
      ArchivePtrMarker::set_and_mark_pointer(ptr_loc, new_p);
      return true; // keep iterating the bitmap
    }
  };
  
  void ArchiveBuilder::SourceObjList::relocate(int i, ArchiveBuilder* builder) {
--- 132,31 ---
  
    bool do_bit(BitMap::idx_t bit_offset) {
      size_t field_offset = size_t(bit_offset - _start_idx) * sizeof(address);
      address* ptr_loc = (address*)(_buffered_obj + field_offset);
  
!     address old_p_with_tags = *ptr_loc;
+     assert(old_p_with_tags != nullptr, "null ptrs shouldn't have been marked");
+ 
+     address old_p = MetaspaceClosure::strip_tags(old_p_with_tags);
+     uintx tags = MetaspaceClosure::decode_tags(old_p_with_tags);
      address new_p = _builder->get_buffered_addr(old_p);
  
!     bool nulled;
!     if (new_p == nullptr) {
+       // old_p had a FollowMode of set_to_null
+       nulled = true;
+     } else {
+       new_p = MetaspaceClosure::add_tags(new_p, tags);
+       nulled = false;
+     }
+ 
+     log_trace(cds)("Ref: [" PTR_FORMAT "] -> " PTR_FORMAT " => " PTR_FORMAT " %zu",
+                    p2i(ptr_loc), p2i(old_p) + tags, p2i(new_p), tags);
  
      ArchivePtrMarker::set_and_mark_pointer(ptr_loc, new_p);
+     ArchiveBuilder::current()->count_relocated_pointer(tags != 0, nulled);
      return true; // keep iterating the bitmap
    }
  };
  
  void ArchiveBuilder::SourceObjList::relocate(int i, ArchiveBuilder* builder) {

*** 166,19 ***
--- 184,23 ---
    _ro_region("ro", MAX_SHARED_DELTA),
    _ac_region("ac", MAX_SHARED_DELTA),
    _ptrmap(mtClassShared),
    _rw_ptrmap(mtClassShared),
    _ro_ptrmap(mtClassShared),
+   _ac_ptrmap(mtClassShared),
    _rw_src_objs(),
    _ro_src_objs(),
    _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
    _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
    _total_heap_region_size(0)
  {
    _klasses = new (mtClassShared) GrowableArray<Klass*>(4 * K, mtClassShared);
    _symbols = new (mtClassShared) GrowableArray<Symbol*>(256 * K, mtClassShared);
    _entropy_seed = 0x12345678;
+   _relocated_ptr_info._num_ptrs = 0;
+   _relocated_ptr_info._num_tagged_ptrs = 0;
+   _relocated_ptr_info._num_nulled_ptrs = 0;
    assert(_current == nullptr, "must be");
    _current = this;
  }
  
  ArchiveBuilder::~ArchiveBuilder() {

*** 434,10 ***
--- 456,15 ---
      assert(!RegeneratedClasses::has_been_regenerated((address)m->method_holder()),
             "Should not archive methods in a class that has been regenerated");
    }
  #endif
  
+   if (ref->msotype() == MetaspaceObj::MethodDataType) {
+     MethodData* md = (MethodData*)ref->obj();
+     md->clean_method_data(false /* always_clean */);
+   }
+ 
    assert(p->read_only() == src_info.read_only(), "must be");
  
    if (created && src_info.should_copy()) {
      if (read_only) {
        _ro_src_objs.append(p);

*** 531,14 ***
    address obj = ref->obj();
    if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_in_shared_metaspace(obj)) {
      // Don't dump existing shared metadata again.
      return point_to_it;
    } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
!              ref->msotype() == MetaspaceObj::MethodCountersType) {
!     return set_to_null;
    } else if (ref->msotype() == MetaspaceObj::AdapterHandlerEntryType) {
!     if (AOTCodeCache::is_dumping_adapters()) {
        AdapterHandlerEntry* entry = (AdapterHandlerEntry*)ref->obj();
        return AdapterHandlerLibrary::is_abstract_method_adapter(entry) ? set_to_null : make_a_copy;
      } else {
        return set_to_null;
      }
--- 558,17 ---
    address obj = ref->obj();
    if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_in_shared_metaspace(obj)) {
      // Don't dump existing shared metadata again.
      return point_to_it;
    } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
!              ref->msotype() == MetaspaceObj::MethodCountersType ||
!              ref->msotype() == MetaspaceObj::KlassTrainingDataType ||
+              ref->msotype() == MetaspaceObj::MethodTrainingDataType ||
+              ref->msotype() == MetaspaceObj::CompileTrainingDataType) {
+       return (TrainingData::need_data() || TrainingData::assembling_data()) ? make_a_copy : set_to_null;
    } else if (ref->msotype() == MetaspaceObj::AdapterHandlerEntryType) {
!     if (AOTCodeCache::is_dumping_adapter()) {
        AdapterHandlerEntry* entry = (AdapterHandlerEntry*)ref->obj();
        return AdapterHandlerLibrary::is_abstract_method_adapter(entry) ? set_to_null : make_a_copy;
      } else {
        return set_to_null;
      }

*** 713,15 ***
      *ptr_location = get_buffered_addr(*ptr_location);
    }
    ArchivePtrMarker::mark_pointer(ptr_location);
  }
  
- bool ArchiveBuilder::has_been_archived(address src_addr) const {
-   SourceObjInfo* p = _src_obj_table.get(src_addr);
-   return (p != nullptr);
- }
- 
  bool ArchiveBuilder::has_been_buffered(address src_addr) const {
    if (RegeneratedClasses::has_been_regenerated(src_addr) ||
        _src_obj_table.get(src_addr) == nullptr ||
        get_buffered_addr(src_addr) == nullptr) {
      return false;
--- 743,10 ---

*** 736,10 ***
--- 761,15 ---
           p2i(src_addr));
  
    return p->buffered_addr();
  }
  
+ bool ArchiveBuilder::has_been_archived(address src_addr) const {
+   SourceObjInfo* p = _src_obj_table.get(src_addr);
+   return (p != nullptr);
+ }
+ 
  address ArchiveBuilder::get_source_addr(address buffered_addr) const {
    assert(is_in_buffer_space(buffered_addr), "must be");
    address* src_p = _buffered_to_src_table.get(buffered_addr);
    assert(src_p != nullptr && *src_p != nullptr, "must be");
    return *src_p;

*** 753,10 ***
--- 783,14 ---
  
  void ArchiveBuilder::relocate_metaspaceobj_embedded_pointers() {
    log_info(cds)("Relocating embedded pointers in core regions ... ");
    relocate_embedded_pointers(&_rw_src_objs);
    relocate_embedded_pointers(&_ro_src_objs);
+   log_info(cds)("Relocating %zu pointers, %zu tagged, %zu nulled",
+                 _relocated_ptr_info._num_ptrs,
+                 _relocated_ptr_info._num_tagged_ptrs,
+                 _relocated_ptr_info._num_nulled_ptrs);
  }
  
  #define ADD_COUNT(x) \
    x += 1; \
    x ## _a += aotlinked ? 1 : 0; \

*** 954,10 ***
--- 988,32 ---
  #undef STATS_PARAMS
  
    DynamicArchive::make_array_klasses_shareable();
  }
  
+ void ArchiveBuilder::make_training_data_shareable() {
+   auto clean_td = [&] (address& src_obj,  SourceObjInfo& info) {
+     if (!is_in_buffer_space(info.buffered_addr())) {
+       return;
+     }
+ 
+     if (info.msotype() == MetaspaceObj::KlassTrainingDataType ||
+         info.msotype() == MetaspaceObj::MethodTrainingDataType ||
+         info.msotype() == MetaspaceObj::CompileTrainingDataType) {
+       TrainingData* buffered_td = (TrainingData*)info.buffered_addr();
+       buffered_td->remove_unshareable_info();
+     } else if (info.msotype() == MetaspaceObj::MethodDataType) {
+       MethodData* buffered_mdo = (MethodData*)info.buffered_addr();
+       buffered_mdo->remove_unshareable_info();
+     } else if (info.msotype() == MetaspaceObj::MethodCountersType) {
+       MethodCounters* buffered_mc = (MethodCounters*)info.buffered_addr();
+       buffered_mc->remove_unshareable_info();
+     }
+   };
+   _src_obj_table.iterate_all(clean_td);
+ }
+ 
  void ArchiveBuilder::serialize_dynamic_archivable_items(SerializeClosure* soc) {
    SymbolTable::serialize_shared_table_header(soc, false);
    SystemDictionaryShared::serialize_dictionary_headers(soc, false);
    DynamicArchive::serialize_array_klasses(soc);
    AOTLinkedClassBulkLoader::serialize(soc, false);

*** 979,26 ***
      p = get_buffered_addr(p);
    }
    return buffer_to_offset(p);
  }
  
- address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
-   address requested_addr = _requested_static_archive_bottom + offset;
-   address buffered_addr = requested_addr - _buffer_to_requested_delta;
-   assert(is_in_buffer_space(buffered_addr), "bad offset");
-   return buffered_addr;
- }
- 
  void ArchiveBuilder::start_ac_region() {
    ro_region()->pack();
    start_dump_region(&_ac_region);
  }
  
  void ArchiveBuilder::end_ac_region() {
    _ac_region.pack();
  }
  
  #if INCLUDE_CDS_JAVA_HEAP
  narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
    assert(CDSConfig::is_dumping_heap(), "sanity");
    k = get_buffered_klass(k);
    Klass* requested_k = to_requested(k);
--- 1035,26 ---
      p = get_buffered_addr(p);
    }
    return buffer_to_offset(p);
  }
  
  void ArchiveBuilder::start_ac_region() {
    ro_region()->pack();
    start_dump_region(&_ac_region);
  }
  
  void ArchiveBuilder::end_ac_region() {
    _ac_region.pack();
  }
  
+ address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
+   address requested_addr = _requested_static_archive_bottom + offset;
+   address buffered_addr = requested_addr - _buffer_to_requested_delta;
+   assert(is_in_buffer_space(buffered_addr), "bad offset");
+   return buffered_addr;
+ }
+ 
  #if INCLUDE_CDS_JAVA_HEAP
  narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
    assert(CDSConfig::is_dumping_heap(), "sanity");
    k = get_buffered_klass(k);
    Klass* requested_k = to_requested(k);

*** 1107,10 ***
--- 1163,11 ---
  
  void ArchiveBuilder::relocate_to_requested() {
    if (!ro_region()->is_packed()) {
      ro_region()->pack();
    }
+ 
    size_t my_archive_size = buffer_top() - buffer_bottom();
  
    if (CDSConfig::is_dumping_static_archive()) {
      _requested_static_archive_top = _requested_static_archive_bottom + my_archive_size;
      RelocateBufferToRequested<true> patcher(this);

*** 1431,11 ***
    static void log_heap_roots() {
      LogStreamHandle(Trace, cds, map, oops) st;
      if (st.is_enabled()) {
        for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
          st.print("roots[%4d]: ", i);
!         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i));
        }
      }
    }
  
    // Example output:
--- 1488,11 ---
    static void log_heap_roots() {
      LogStreamHandle(Trace, cds, map, oops) st;
      if (st.is_enabled()) {
        for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
          st.print("roots[%4d]: ", i);
!         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i).resolve());
        }
      }
    }
  
    // Example output:

*** 1462,10 ***
--- 1519,13 ---
          st->print("%s", source_oop->klass()->external_name());
  
          if (java_lang_String::is_instance(source_oop)) {
            st->print(" ");
            java_lang_String::print(source_oop, st);
+         } else if (java_lang_invoke_MethodType::is_instance(source_oop)) {
+           st->print(" ");
+           java_lang_invoke_MethodType::print_signature(source_oop, st);
          } else if (java_lang_Class::is_instance(source_oop)) {
            oop scratch_mirror = source_oop;
  
            st->print(" ");
            print_class_signature_for_mirror(st, scratch_mirror);

*** 1553,14 ***
    write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
    write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
    write_region(mapinfo, MetaspaceShared::ac, &_ac_region, /*read_only=*/false,/*allow_exec=*/false);
  
    // Split pointer map into read-write and read-only bitmaps
!   ArchivePtrMarker::initialize_rw_ro_maps(&_rw_ptrmap, &_ro_ptrmap);
  
    size_t bitmap_size_in_bytes;
!   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(), ArchivePtrMarker::ro_ptrmap(), heap_info,
                                                bitmap_size_in_bytes);
  
    if (heap_info->is_used()) {
      _total_heap_region_size = mapinfo->write_heap_region(heap_info);
    }
--- 1613,17 ---
    write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
    write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
    write_region(mapinfo, MetaspaceShared::ac, &_ac_region, /*read_only=*/false,/*allow_exec=*/false);
  
    // Split pointer map into read-write and read-only bitmaps
!   ArchivePtrMarker::initialize_rw_ro_ac_maps(&_rw_ptrmap, &_ro_ptrmap, &_ac_ptrmap);
  
    size_t bitmap_size_in_bytes;
!   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(),
+                                               ArchivePtrMarker::ro_ptrmap(),
+                                               ArchivePtrMarker::ac_ptrmap(),
+                                               heap_info,
                                                bitmap_size_in_bytes);
  
    if (heap_info->is_used()) {
      _total_heap_region_size = mapinfo->write_heap_region(heap_info);
    }

*** 1589,10 ***
--- 1652,16 ---
  
  void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only,  bool allow_exec) {
    mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
  }
  
+ void ArchiveBuilder::count_relocated_pointer(bool tagged, bool nulled) {
+   _relocated_ptr_info._num_ptrs ++;
+   _relocated_ptr_info._num_tagged_ptrs += tagged ? 1 : 0;
+   _relocated_ptr_info._num_nulled_ptrs += nulled ? 1 : 0;
+ }
+ 
  void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, ArchiveHeapInfo* heap_info) {
    // Print statistics of all the regions
    const size_t bitmap_used = mapinfo->region_at(MetaspaceShared::bm)->used();
    const size_t bitmap_reserved = mapinfo->region_at(MetaspaceShared::bm)->used_aligned();
    const size_t total_reserved = _ro_region.reserved()  + _rw_region.reserved() +
< prev index next >