< 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"

@@ -50,13 +51,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"

@@ -163,13 +167,15 @@
    _mapped_static_archive_bottom(nullptr),
    _mapped_static_archive_top(nullptr),
    _buffer_to_requested_delta(0),
    _rw_region("rw", MAX_SHARED_DELTA),
    _ro_region("ro", MAX_SHARED_DELTA),
+   _cc_region("cc", MAX_SHARED_DELTA),
    _ptrmap(mtClassShared),
    _rw_ptrmap(mtClassShared),
    _ro_ptrmap(mtClassShared),
+   _cc_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),

@@ -317,11 +323,21 @@
  
  size_t ArchiveBuilder::estimate_archive_size() {
    // size of the symbol table and two dictionaries, plus the RunTimeClassInfo's
    size_t symbol_table_est = SymbolTable::estimate_size_for_archive();
    size_t dictionary_est = SystemDictionaryShared::estimate_size_for_archive();
-   _estimated_hashtable_bytes = symbol_table_est + dictionary_est;
+   size_t training_data_est = TrainingData::estimate_size_for_archive();
+   _estimated_hashtable_bytes = symbol_table_est + dictionary_est + training_data_est;
+ 
+   if (CDSConfig::is_dumping_final_static_archive()) {
+     _estimated_hashtable_bytes += 200 * 1024 * 1024; // FIXME -- need to iterate archived symbols??
+   }
+ 
+   if (CDSConfig::is_dumping_dynamic_archive()) {
+     // Some extra space for traning data. Be generous. Unused areas will be trimmed from the archive file.
+     _estimated_hashtable_bytes += 200 * 1024 * 1024;
+   }
  
    if (CDSConfig::is_dumping_aot_linked_classes()) {
      // This is difficult to estimate when dumping the dynamic archive, as the
      // AOTLinkedClassTable may need to contain classes in the static archive as well.
      //

@@ -548,11 +564,11 @@
    if (klass->is_instance_klass()) {
      InstanceKlass* ik = InstanceKlass::cast(klass);
      return SystemDictionaryShared::is_excluded_class(ik);
    } else if (klass->is_objArray_klass()) {
      Klass* bottom = ObjArrayKlass::cast(klass)->bottom_klass();
-     if (MetaspaceShared::is_shared_static(bottom)) {
+     if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_shared_static(bottom)) {
        // The bottom class is in the static archive so it's clearly not excluded.
        assert(CDSConfig::is_dumping_dynamic_archive(), "sanity");
        return false;
      } else if (bottom->is_instance_klass()) {
        return SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(bottom));

@@ -562,16 +578,19 @@
    return false;
  }
  
  ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref *ref) {
    address obj = ref->obj();
-   if (MetaspaceShared::is_in_shared_metaspace(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;
+              ref->msotype() == MetaspaceObj::MethodCountersType ||
+              ref->msotype() == MetaspaceObj::KlassTrainingDataType ||
+              ref->msotype() == MetaspaceObj::MethodTrainingDataType ||
+              ref->msotype() == MetaspaceObj::CompileTrainingDataType) {
+       return TrainingData::need_data() ? make_a_copy : set_to_null;
    } else {
      if (ref->msotype() == MetaspaceObj::ClassType) {
        Klass* klass = (Klass*)ref->obj();
        assert(klass->is_klass(), "must be");
        if (is_excluded(klass)) {

@@ -779,10 +798,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;

@@ -992,15 +1016,39 @@
  #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);
+   FinalImageRecipes::serialize(soc, false);
+   TrainingData::serialize_training_data(soc);
  }
  
  uintx ArchiveBuilder::buffer_to_offset(address p) const {
    address requested_p = to_requested(p);
    assert(requested_p >= _requested_static_archive_bottom, "must be");

@@ -1017,10 +1065,19 @@
      p = get_buffered_addr(p);
    }
    return buffer_to_offset(p);
  }
  
+ void ArchiveBuilder::start_cc_region() {
+   ro_region()->pack();
+   start_dump_region(&_cc_region);
+ }
+ 
+ void ArchiveBuilder::end_cc_region() {
+   _cc_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;

@@ -1133,11 +1190,13 @@
    return UseCompactObjectHeaders ?  CompressedKlassPointers::max_shift() : 0;
  }
  #endif // _LP64
  
  void ArchiveBuilder::relocate_to_requested() {
-   ro_region()->pack();
+   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;

@@ -1455,11 +1514,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));
+         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i).resolve());
        }
      }
    }
  
    // Example output:

@@ -1486,10 +1545,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);

@@ -1574,16 +1636,20 @@
    // MetaspaceShared::n_regions (internal to hotspot).
    assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
  
    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::cc, &_cc_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);
+   ArchivePtrMarker::initialize_rw_ro_cc_maps(&_rw_ptrmap, &_ro_ptrmap, &_cc_ptrmap);
  
    size_t bitmap_size_in_bytes;
-   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(), ArchivePtrMarker::ro_ptrmap(), heap_info,
+   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(),
+                                               ArchivePtrMarker::ro_ptrmap(),
+                                               ArchivePtrMarker::cc_ptrmap(),
+                                               heap_info,
                                                bitmap_size_in_bytes);
  
    if (heap_info->is_used()) {
      _total_heap_region_size = mapinfo->write_heap_region(heap_info);
    }

@@ -1625,10 +1691,11 @@
                               _total_heap_region_size;
    const double total_u_perc = percent_of(total_bytes, total_reserved);
  
    _rw_region.print(total_reserved);
    _ro_region.print(total_reserved);
+   _cc_region.print(total_reserved);
  
    print_bitmap_region_stats(bitmap_used, total_reserved);
  
    if (heap_info->is_used()) {
      print_heap_region_stats(heap_info, total_reserved);
< prev index next >