< prev index next >

src/hotspot/share/cds/archiveBuilder.cpp

Print this page

  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "cds/aotClassLinker.hpp"
  27 #include "cds/aotLinkedClassBulkLoader.hpp"
  28 #include "cds/archiveBuilder.hpp"
  29 #include "cds/archiveHeapWriter.hpp"
  30 #include "cds/archiveUtils.hpp"
  31 #include "cds/cdsConfig.hpp"
  32 #include "cds/cppVtables.hpp"
  33 #include "cds/dumpAllocStats.hpp"
  34 #include "cds/dynamicArchive.hpp"

  35 #include "cds/heapShared.hpp"
  36 #include "cds/metaspaceShared.hpp"
  37 #include "cds/regeneratedClasses.hpp"
  38 #include "classfile/classLoader.hpp"
  39 #include "classfile/classLoaderDataShared.hpp"
  40 #include "classfile/classLoaderExt.hpp"
  41 #include "classfile/javaClasses.hpp"
  42 #include "classfile/symbolTable.hpp"
  43 #include "classfile/systemDictionaryShared.hpp"
  44 #include "classfile/vmClasses.hpp"
  45 #include "interpreter/abstractInterpreter.hpp"
  46 #include "jvm.h"
  47 #include "logging/log.hpp"
  48 #include "logging/logStream.hpp"
  49 #include "memory/allStatic.hpp"
  50 #include "memory/memoryReserver.hpp"
  51 #include "memory/memRegion.hpp"
  52 #include "memory/resourceArea.hpp"
  53 #include "oops/compressedKlass.inline.hpp"
  54 #include "oops/instanceKlass.hpp"


  55 #include "oops/objArrayKlass.hpp"
  56 #include "oops/objArrayOop.inline.hpp"
  57 #include "oops/oopHandle.inline.hpp"

  58 #include "runtime/arguments.hpp"
  59 #include "runtime/fieldDescriptor.inline.hpp"
  60 #include "runtime/globals_extension.hpp"
  61 #include "runtime/javaThread.hpp"
  62 #include "runtime/sharedRuntime.hpp"
  63 #include "utilities/align.hpp"
  64 #include "utilities/bitMap.inline.hpp"
  65 #include "utilities/formatBuffer.hpp"
  66 
  67 ArchiveBuilder* ArchiveBuilder::_current = nullptr;
  68 
  69 ArchiveBuilder::OtherROAllocMark::~OtherROAllocMark() {
  70   char* newtop = ArchiveBuilder::current()->_ro_region.top();
  71   ArchiveBuilder::alloc_stats()->record_other_type(int(newtop - _oldtop), true);
  72 }
  73 
  74 ArchiveBuilder::SourceObjList::SourceObjList() : _ptrmap(16 * K, mtClassShared) {
  75   _total_bytes = 0;
  76   _objs = new (mtClassShared) GrowableArray<SourceObjInfo*>(128 * K, mtClassShared);
  77 }

 148 
 149   RelocateEmbeddedPointers relocator(builder, src_info->buffered_addr(), start);
 150   _ptrmap.iterate(&relocator, start, end);
 151 }
 152 
 153 ArchiveBuilder::ArchiveBuilder() :
 154   _current_dump_region(nullptr),
 155   _buffer_bottom(nullptr),
 156   _last_verified_top(nullptr),
 157   _num_dump_regions_used(0),
 158   _other_region_used_bytes(0),
 159   _requested_static_archive_bottom(nullptr),
 160   _requested_static_archive_top(nullptr),
 161   _requested_dynamic_archive_bottom(nullptr),
 162   _requested_dynamic_archive_top(nullptr),
 163   _mapped_static_archive_bottom(nullptr),
 164   _mapped_static_archive_top(nullptr),
 165   _buffer_to_requested_delta(0),
 166   _rw_region("rw", MAX_SHARED_DELTA),
 167   _ro_region("ro", MAX_SHARED_DELTA),

 168   _ptrmap(mtClassShared),
 169   _rw_ptrmap(mtClassShared),
 170   _ro_ptrmap(mtClassShared),

 171   _rw_src_objs(),
 172   _ro_src_objs(),
 173   _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 174   _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 175   _total_heap_region_size(0),
 176   _estimated_metaspaceobj_bytes(0),
 177   _estimated_hashtable_bytes(0)
 178 {
 179   _klasses = new (mtClassShared) GrowableArray<Klass*>(4 * K, mtClassShared);
 180   _symbols = new (mtClassShared) GrowableArray<Symbol*>(256 * K, mtClassShared);
 181   _entropy_seed = 0x12345678;
 182   assert(_current == nullptr, "must be");
 183   _current = this;
 184 }
 185 
 186 ArchiveBuilder::~ArchiveBuilder() {
 187   assert(_current == this, "must be");
 188   _current = nullptr;
 189 
 190   for (int i = 0; i < _symbols->length(); i++) {

 302     return -1;
 303   } else {
 304     assert(a[0] > b[0], "Duplicated symbol %s unexpected", (*a)->as_C_string());
 305     return 1;
 306   }
 307 }
 308 
 309 int ArchiveBuilder::compare_klass_by_name(Klass** a, Klass** b) {
 310   return a[0]->name()->fast_compare(b[0]->name());
 311 }
 312 
 313 void ArchiveBuilder::sort_klasses() {
 314   log_info(cds)("Sorting classes ... ");
 315   _klasses->sort(compare_klass_by_name);
 316 }
 317 
 318 size_t ArchiveBuilder::estimate_archive_size() {
 319   // size of the symbol table and two dictionaries, plus the RunTimeClassInfo's
 320   size_t symbol_table_est = SymbolTable::estimate_size_for_archive();
 321   size_t dictionary_est = SystemDictionaryShared::estimate_size_for_archive();
 322   _estimated_hashtable_bytes = symbol_table_est + dictionary_est;










 323 
 324   if (CDSConfig::is_dumping_aot_linked_classes()) {
 325     // This is difficult to estimate when dumping the dynamic archive, as the
 326     // AOTLinkedClassTable may need to contain classes in the static archive as well.
 327     //
 328     // Just give a generous estimate for now. We will remove estimate_archive_size()
 329     // in JDK-8340416
 330     _estimated_hashtable_bytes += 20 * 1024 * 1024;
 331   }
 332 
 333   size_t total = 0;
 334 
 335   total += _estimated_metaspaceobj_bytes;
 336   total += _estimated_hashtable_bytes;
 337 
 338   // allow fragmentation at the end of each dump region
 339   total += _total_dump_regions * MetaspaceShared::core_region_alignment();
 340 
 341   log_info(cds)("_estimated_hashtable_bytes = " SIZE_FORMAT " + " SIZE_FORMAT " = " SIZE_FORMAT,
 342                 symbol_table_est, dictionary_est, _estimated_hashtable_bytes);

 533       _rw_src_objs.remember_embedded_pointer(src_info, ref);
 534     }
 535   }
 536 }
 537 
 538 void ArchiveBuilder::gather_source_objs() {
 539   ResourceMark rm;
 540   log_info(cds)("Gathering all archivable objects ... ");
 541   gather_klasses_and_symbols();
 542   GatherSortedSourceObjs doit(this);
 543   iterate_sorted_roots(&doit);
 544   doit.finish();
 545 }
 546 
 547 bool ArchiveBuilder::is_excluded(Klass* klass) {
 548   if (klass->is_instance_klass()) {
 549     InstanceKlass* ik = InstanceKlass::cast(klass);
 550     return SystemDictionaryShared::is_excluded_class(ik);
 551   } else if (klass->is_objArray_klass()) {
 552     Klass* bottom = ObjArrayKlass::cast(klass)->bottom_klass();
 553     if (MetaspaceShared::is_shared_static(bottom)) {
 554       // The bottom class is in the static archive so it's clearly not excluded.
 555       assert(CDSConfig::is_dumping_dynamic_archive(), "sanity");
 556       return false;
 557     } else if (bottom->is_instance_klass()) {
 558       return SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(bottom));
 559     }
 560   }
 561 
 562   return false;
 563 }
 564 
 565 ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref *ref) {
 566   address obj = ref->obj();
 567   if (MetaspaceShared::is_in_shared_metaspace(obj)) {
 568     // Don't dump existing shared metadata again.
 569     return point_to_it;
 570   } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
 571              ref->msotype() == MetaspaceObj::MethodCountersType) {
 572     return set_to_null;



 573   } else {
 574     if (ref->msotype() == MetaspaceObj::ClassType) {
 575       Klass* klass = (Klass*)ref->obj();
 576       assert(klass->is_klass(), "must be");
 577       if (is_excluded(klass)) {
 578         ResourceMark rm;
 579         log_debug(cds, dynamic)("Skipping class (excluded): %s", klass->external_name());
 580         return set_to_null;
 581       }
 582     }
 583 
 584     return make_a_copy;
 585   }
 586 }
 587 
 588 void ArchiveBuilder::start_dump_region(DumpRegion* next) {
 589   address bottom = _last_verified_top;
 590   address top = (address)(current_dump_region()->top());
 591   _other_region_used_bytes += size_t(top - bottom);
 592 

 764 }
 765 
 766 bool ArchiveBuilder::has_been_buffered(address src_addr) const {
 767   if (RegeneratedClasses::has_been_regenerated(src_addr) ||
 768       _src_obj_table.get(src_addr) == nullptr ||
 769       get_buffered_addr(src_addr) == nullptr) {
 770     return false;
 771   } else {
 772     return true;
 773   }
 774 }
 775 
 776 address ArchiveBuilder::get_buffered_addr(address src_addr) const {
 777   SourceObjInfo* p = _src_obj_table.get(src_addr);
 778   assert(p != nullptr, "src_addr " INTPTR_FORMAT " is used but has not been archived",
 779          p2i(src_addr));
 780 
 781   return p->buffered_addr();
 782 }
 783 





 784 address ArchiveBuilder::get_source_addr(address buffered_addr) const {
 785   assert(is_in_buffer_space(buffered_addr), "must be");
 786   address* src_p = _buffered_to_src_table.get(buffered_addr);
 787   assert(src_p != nullptr && *src_p != nullptr, "must be");
 788   return *src_p;
 789 }
 790 
 791 void ArchiveBuilder::relocate_embedded_pointers(ArchiveBuilder::SourceObjList* src_objs) {
 792   for (int i = 0; i < src_objs->objs()->length(); i++) {
 793     src_objs->relocate(i, this);
 794   }
 795 }
 796 
 797 void ArchiveBuilder::relocate_metaspaceobj_embedded_pointers() {
 798   log_info(cds)("Relocating embedded pointers in core regions ... ");
 799   relocate_embedded_pointers(&_rw_src_objs);
 800   relocate_embedded_pointers(&_ro_src_objs);
 801 }
 802 
 803 #define ADD_COUNT(x) \

 977   log_info(cds)("      boot             " STATS_FORMAT, STATS_PARAMS(boot_klasses));
 978   log_info(cds)("        vm             " STATS_FORMAT, STATS_PARAMS(vm_klasses));
 979   log_info(cds)("      platform         " STATS_FORMAT, STATS_PARAMS(platform_klasses));
 980   log_info(cds)("      app              " STATS_FORMAT, STATS_PARAMS(app_klasses));
 981   log_info(cds)("      unregistered     " STATS_FORMAT, STATS_PARAMS(unregistered_klasses));
 982   log_info(cds)("      (enum)           " STATS_FORMAT, STATS_PARAMS(enum_klasses));
 983   log_info(cds)("      (hidden)         " STATS_FORMAT, STATS_PARAMS(hidden_klasses));
 984   log_info(cds)("      (old)            " STATS_FORMAT, STATS_PARAMS(old_klasses));
 985   log_info(cds)("      (unlinked)       = %5d, boot = %d, plat = %d, app = %d, unreg = %d",
 986                 num_unlinked_klasses, boot_unlinked, platform_unlinked, app_unlinked, unreg_unlinked);
 987   log_info(cds)("    obj array classes  = %5d", num_obj_array_klasses);
 988   log_info(cds)("    type array classes = %5d", num_type_array_klasses);
 989   log_info(cds)("               symbols = %5d", _symbols->length());
 990 
 991 #undef STATS_FORMAT
 992 #undef STATS_PARAMS
 993 
 994   DynamicArchive::make_array_klasses_shareable();
 995 }
 996 






















 997 void ArchiveBuilder::serialize_dynamic_archivable_items(SerializeClosure* soc) {
 998   SymbolTable::serialize_shared_table_header(soc, false);
 999   SystemDictionaryShared::serialize_dictionary_headers(soc, false);
1000   DynamicArchive::serialize_array_klasses(soc);
1001   AOTLinkedClassBulkLoader::serialize(soc, false);


1002 }
1003 
1004 uintx ArchiveBuilder::buffer_to_offset(address p) const {
1005   address requested_p = to_requested(p);
1006   assert(requested_p >= _requested_static_archive_bottom, "must be");
1007   return requested_p - _requested_static_archive_bottom;
1008 }
1009 
1010 uintx ArchiveBuilder::any_to_offset(address p) const {
1011   if (is_in_mapped_static_archive(p)) {
1012     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
1013     return p - _mapped_static_archive_bottom;
1014   }
1015   if (!is_in_buffer_space(p)) {
1016     // p must be a "source" address
1017     p = get_buffered_addr(p);
1018   }
1019   return buffer_to_offset(p);
1020 }
1021 









1022 address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
1023   address requested_addr = _requested_static_archive_bottom + offset;
1024   address buffered_addr = requested_addr - _buffer_to_requested_delta;
1025   assert(is_in_buffer_space(buffered_addr), "bad offset");
1026   return buffered_addr;
1027 }
1028 
1029 #if INCLUDE_CDS_JAVA_HEAP
1030 narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
1031   assert(CDSConfig::is_dumping_heap(), "sanity");
1032   k = get_buffered_klass(k);
1033   Klass* requested_k = to_requested(k);
1034   const int narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
1035 #ifdef ASSERT
1036   const size_t klass_alignment = MAX2(SharedSpaceObjectAlignment, (size_t)nth_bit(narrow_klass_shift));
1037   assert(is_aligned(k, klass_alignment), "Klass " PTR_FORMAT " misaligned.", p2i(k));
1038 #endif
1039   address narrow_klass_base = _requested_static_archive_bottom; // runtime encoding base == runtime mapping start
1040   // Note: use the "raw" version of encode that takes explicit narrow klass base and shift. Don't use any
1041   // of the variants that do sanity checks, nor any of those that use the current - dump - JVM's encoding setting.

1118     ArchivePtrMarker::compact(_max_non_null_offset);
1119   }
1120 };
1121 
1122 #ifdef _LP64
1123 int ArchiveBuilder::precomputed_narrow_klass_shift() {
1124   // Legacy Mode:
1125   //    We use 32 bits for narrowKlass, which should cover the full 4G Klass range. Shift can be 0.
1126   // CompactObjectHeader Mode:
1127   //    narrowKlass is much smaller, and we use the highest possible shift value to later get the maximum
1128   //    Klass encoding range.
1129   //
1130   // Note that all of this may change in the future, if we decide to correct the pre-calculated
1131   // narrow Klass IDs at archive load time.
1132   assert(UseCompressedClassPointers, "Only needed for compressed class pointers");
1133   return UseCompactObjectHeaders ?  CompressedKlassPointers::max_shift() : 0;
1134 }
1135 #endif // _LP64
1136 
1137 void ArchiveBuilder::relocate_to_requested() {
1138   ro_region()->pack();


1139 
1140   size_t my_archive_size = buffer_top() - buffer_bottom();
1141 
1142   if (CDSConfig::is_dumping_static_archive()) {
1143     _requested_static_archive_top = _requested_static_archive_bottom + my_archive_size;
1144     RelocateBufferToRequested<true> patcher(this);
1145     patcher.doit();
1146   } else {
1147     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
1148     _requested_dynamic_archive_top = _requested_dynamic_archive_bottom + my_archive_size;
1149     RelocateBufferToRequested<false> patcher(this);
1150     patcher.doit();
1151   }
1152 }
1153 
1154 // Write detailed info to a mapfile to analyze contents of the archive.
1155 // static dump:
1156 //   java -Xshare:dump -Xlog:cds+map=trace:file=cds.map:none:filesize=0
1157 // dynamic dump:
1158 //   java -cp MyApp.jar -XX:ArchiveClassesAtExit=MyApp.jsa \

1440     assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1441     if (java_lang_Class::is_primitive(scratch_mirror)) {
1442       for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1443         BasicType bt = (BasicType)i;
1444         if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1445           oop orig_mirror = Universe::java_mirror(bt);
1446           java_lang_Class::print_signature(orig_mirror, st);
1447           return;
1448         }
1449       }
1450       ShouldNotReachHere();
1451     }
1452     java_lang_Class::print_signature(scratch_mirror, st);
1453   }
1454 
1455   static void log_heap_roots() {
1456     LogStreamHandle(Trace, cds, map, oops) st;
1457     if (st.is_enabled()) {
1458       for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
1459         st.print("roots[%4d]: ", i);
1460         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i));
1461       }
1462     }
1463   }
1464 
1465   // Example output:
1466   // - The first number is the requested address (if print_requested_addr == true)
1467   // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1468   //     0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
1469   //     0x00000007ffc000f8 (0xfff8001f) [B length: 11
1470   static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
1471     if (source_oop == nullptr) {
1472       st->print_cr("null");
1473     } else {
1474       ResourceMark rm;
1475       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1476       if (print_requested_addr) {
1477         st->print(PTR_FORMAT " ", p2i(requested_obj));
1478       }
1479       if (UseCompressedOops) {
1480         st->print("(0x%08x) ", CompressedOops::narrow_oop_value(requested_obj));
1481       }
1482       if (source_oop->is_array()) {
1483         int array_len = arrayOop(source_oop)->length();
1484         st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
1485       } else {
1486         st->print("%s", source_oop->klass()->external_name());
1487 
1488         if (java_lang_String::is_instance(source_oop)) {
1489           st->print(" ");
1490           java_lang_String::print(source_oop, st);



1491         } else if (java_lang_Class::is_instance(source_oop)) {
1492           oop scratch_mirror = source_oop;
1493 
1494           st->print(" ");
1495           print_class_signature_for_mirror(st, scratch_mirror);
1496 
1497           Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1498           if (src_klass != nullptr && src_klass->is_instance_klass()) {
1499             InstanceKlass* buffered_klass =
1500               ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1501             if (buffered_klass->has_aot_initialized_mirror()) {
1502               st->print(" (aot-inited)");
1503             }
1504           }
1505         }
1506         st->cr();
1507       }
1508     }
1509   }
1510 #endif // INCLUDE_CDS_JAVA_HEAP

1559     if (heap_info->is_used()) {
1560       log_heap_region(heap_info);
1561     }
1562 #endif
1563 
1564     log_info(cds, map)("[End of CDS archive map]");
1565   }
1566 }; // end ArchiveBuilder::CDSMapLogger
1567 
1568 void ArchiveBuilder::print_stats() {
1569   _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
1570 }
1571 
1572 void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) {
1573   // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
1574   // MetaspaceShared::n_regions (internal to hotspot).
1575   assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
1576 
1577   write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1578   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);

1579 
1580   // Split pointer map into read-write and read-only bitmaps
1581   ArchivePtrMarker::initialize_rw_ro_maps(&_rw_ptrmap, &_ro_ptrmap);
1582 
1583   size_t bitmap_size_in_bytes;
1584   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(), ArchivePtrMarker::ro_ptrmap(), heap_info,



1585                                               bitmap_size_in_bytes);
1586 
1587   if (heap_info->is_used()) {
1588     _total_heap_region_size = mapinfo->write_heap_region(heap_info);
1589   }
1590 
1591   print_region_stats(mapinfo, heap_info);
1592 
1593   mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address());
1594   mapinfo->set_header_crc(mapinfo->compute_header_crc());
1595   // After this point, we should not write any data into mapinfo->header() since this
1596   // would corrupt its checksum we have calculated before.
1597   mapinfo->write_header();
1598   mapinfo->close();
1599 
1600   if (log_is_enabled(Info, cds)) {
1601     print_stats();
1602   }
1603 
1604   if (log_is_enabled(Info, cds, map)) {

1610 }
1611 
1612 void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only,  bool allow_exec) {
1613   mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1614 }
1615 
1616 void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, ArchiveHeapInfo* heap_info) {
1617   // Print statistics of all the regions
1618   const size_t bitmap_used = mapinfo->region_at(MetaspaceShared::bm)->used();
1619   const size_t bitmap_reserved = mapinfo->region_at(MetaspaceShared::bm)->used_aligned();
1620   const size_t total_reserved = _ro_region.reserved()  + _rw_region.reserved() +
1621                                 bitmap_reserved +
1622                                 _total_heap_region_size;
1623   const size_t total_bytes = _ro_region.used()  + _rw_region.used() +
1624                              bitmap_used +
1625                              _total_heap_region_size;
1626   const double total_u_perc = percent_of(total_bytes, total_reserved);
1627 
1628   _rw_region.print(total_reserved);
1629   _ro_region.print(total_reserved);

1630 
1631   print_bitmap_region_stats(bitmap_used, total_reserved);
1632 
1633   if (heap_info->is_used()) {
1634     print_heap_region_stats(heap_info, total_reserved);
1635   }
1636 
1637   log_debug(cds)("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
1638                  total_bytes, total_reserved, total_u_perc);
1639 }
1640 
1641 void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) {
1642   log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]",
1643                  size, size/double(total_size)*100.0, size);
1644 }
1645 
1646 void ArchiveBuilder::print_heap_region_stats(ArchiveHeapInfo *info, size_t total_size) {
1647   char* start = info->buffer_start();
1648   size_t size = info->buffer_byte_size();
1649   char* top = start + size;

  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "cds/aotClassLinker.hpp"
  27 #include "cds/aotLinkedClassBulkLoader.hpp"
  28 #include "cds/archiveBuilder.hpp"
  29 #include "cds/archiveHeapWriter.hpp"
  30 #include "cds/archiveUtils.hpp"
  31 #include "cds/cdsConfig.hpp"
  32 #include "cds/cppVtables.hpp"
  33 #include "cds/dumpAllocStats.hpp"
  34 #include "cds/dynamicArchive.hpp"
  35 #include "cds/finalImageRecipes.hpp"
  36 #include "cds/heapShared.hpp"
  37 #include "cds/metaspaceShared.hpp"
  38 #include "cds/regeneratedClasses.hpp"
  39 #include "classfile/classLoader.hpp"
  40 #include "classfile/classLoaderDataShared.hpp"
  41 #include "classfile/classLoaderExt.hpp"
  42 #include "classfile/javaClasses.hpp"
  43 #include "classfile/symbolTable.hpp"
  44 #include "classfile/systemDictionaryShared.hpp"
  45 #include "classfile/vmClasses.hpp"
  46 #include "interpreter/abstractInterpreter.hpp"
  47 #include "jvm.h"
  48 #include "logging/log.hpp"
  49 #include "logging/logStream.hpp"
  50 #include "memory/allStatic.hpp"
  51 #include "memory/memoryReserver.hpp"
  52 #include "memory/memRegion.hpp"
  53 #include "memory/resourceArea.hpp"
  54 #include "oops/compressedKlass.inline.hpp"
  55 #include "oops/instanceKlass.hpp"
  56 #include "oops/methodCounters.hpp"
  57 #include "oops/methodData.hpp"
  58 #include "oops/objArrayKlass.hpp"
  59 #include "oops/objArrayOop.inline.hpp"
  60 #include "oops/oopHandle.inline.hpp"
  61 #include "oops/trainingData.hpp"
  62 #include "runtime/arguments.hpp"
  63 #include "runtime/fieldDescriptor.inline.hpp"
  64 #include "runtime/globals_extension.hpp"
  65 #include "runtime/javaThread.hpp"
  66 #include "runtime/sharedRuntime.hpp"
  67 #include "utilities/align.hpp"
  68 #include "utilities/bitMap.inline.hpp"
  69 #include "utilities/formatBuffer.hpp"
  70 
  71 ArchiveBuilder* ArchiveBuilder::_current = nullptr;
  72 
  73 ArchiveBuilder::OtherROAllocMark::~OtherROAllocMark() {
  74   char* newtop = ArchiveBuilder::current()->_ro_region.top();
  75   ArchiveBuilder::alloc_stats()->record_other_type(int(newtop - _oldtop), true);
  76 }
  77 
  78 ArchiveBuilder::SourceObjList::SourceObjList() : _ptrmap(16 * K, mtClassShared) {
  79   _total_bytes = 0;
  80   _objs = new (mtClassShared) GrowableArray<SourceObjInfo*>(128 * K, mtClassShared);
  81 }

 152 
 153   RelocateEmbeddedPointers relocator(builder, src_info->buffered_addr(), start);
 154   _ptrmap.iterate(&relocator, start, end);
 155 }
 156 
 157 ArchiveBuilder::ArchiveBuilder() :
 158   _current_dump_region(nullptr),
 159   _buffer_bottom(nullptr),
 160   _last_verified_top(nullptr),
 161   _num_dump_regions_used(0),
 162   _other_region_used_bytes(0),
 163   _requested_static_archive_bottom(nullptr),
 164   _requested_static_archive_top(nullptr),
 165   _requested_dynamic_archive_bottom(nullptr),
 166   _requested_dynamic_archive_top(nullptr),
 167   _mapped_static_archive_bottom(nullptr),
 168   _mapped_static_archive_top(nullptr),
 169   _buffer_to_requested_delta(0),
 170   _rw_region("rw", MAX_SHARED_DELTA),
 171   _ro_region("ro", MAX_SHARED_DELTA),
 172   _cc_region("cc", MAX_SHARED_DELTA),
 173   _ptrmap(mtClassShared),
 174   _rw_ptrmap(mtClassShared),
 175   _ro_ptrmap(mtClassShared),
 176   _cc_ptrmap(mtClassShared),
 177   _rw_src_objs(),
 178   _ro_src_objs(),
 179   _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 180   _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 181   _total_heap_region_size(0),
 182   _estimated_metaspaceobj_bytes(0),
 183   _estimated_hashtable_bytes(0)
 184 {
 185   _klasses = new (mtClassShared) GrowableArray<Klass*>(4 * K, mtClassShared);
 186   _symbols = new (mtClassShared) GrowableArray<Symbol*>(256 * K, mtClassShared);
 187   _entropy_seed = 0x12345678;
 188   assert(_current == nullptr, "must be");
 189   _current = this;
 190 }
 191 
 192 ArchiveBuilder::~ArchiveBuilder() {
 193   assert(_current == this, "must be");
 194   _current = nullptr;
 195 
 196   for (int i = 0; i < _symbols->length(); i++) {

 308     return -1;
 309   } else {
 310     assert(a[0] > b[0], "Duplicated symbol %s unexpected", (*a)->as_C_string());
 311     return 1;
 312   }
 313 }
 314 
 315 int ArchiveBuilder::compare_klass_by_name(Klass** a, Klass** b) {
 316   return a[0]->name()->fast_compare(b[0]->name());
 317 }
 318 
 319 void ArchiveBuilder::sort_klasses() {
 320   log_info(cds)("Sorting classes ... ");
 321   _klasses->sort(compare_klass_by_name);
 322 }
 323 
 324 size_t ArchiveBuilder::estimate_archive_size() {
 325   // size of the symbol table and two dictionaries, plus the RunTimeClassInfo's
 326   size_t symbol_table_est = SymbolTable::estimate_size_for_archive();
 327   size_t dictionary_est = SystemDictionaryShared::estimate_size_for_archive();
 328   size_t training_data_est = TrainingData::estimate_size_for_archive();
 329   _estimated_hashtable_bytes = symbol_table_est + dictionary_est + training_data_est;
 330 
 331   if (CDSConfig::is_dumping_final_static_archive()) {
 332     _estimated_hashtable_bytes += 200 * 1024 * 1024; // FIXME -- need to iterate archived symbols??
 333   }
 334 
 335   if (CDSConfig::is_dumping_dynamic_archive()) {
 336     // Some extra space for traning data. Be generous. Unused areas will be trimmed from the archive file.
 337     _estimated_hashtable_bytes += 200 * 1024 * 1024;
 338   }
 339 
 340   if (CDSConfig::is_dumping_aot_linked_classes()) {
 341     // This is difficult to estimate when dumping the dynamic archive, as the
 342     // AOTLinkedClassTable may need to contain classes in the static archive as well.
 343     //
 344     // Just give a generous estimate for now. We will remove estimate_archive_size()
 345     // in JDK-8340416
 346     _estimated_hashtable_bytes += 20 * 1024 * 1024;
 347   }
 348 
 349   size_t total = 0;
 350 
 351   total += _estimated_metaspaceobj_bytes;
 352   total += _estimated_hashtable_bytes;
 353 
 354   // allow fragmentation at the end of each dump region
 355   total += _total_dump_regions * MetaspaceShared::core_region_alignment();
 356 
 357   log_info(cds)("_estimated_hashtable_bytes = " SIZE_FORMAT " + " SIZE_FORMAT " = " SIZE_FORMAT,
 358                 symbol_table_est, dictionary_est, _estimated_hashtable_bytes);

 549       _rw_src_objs.remember_embedded_pointer(src_info, ref);
 550     }
 551   }
 552 }
 553 
 554 void ArchiveBuilder::gather_source_objs() {
 555   ResourceMark rm;
 556   log_info(cds)("Gathering all archivable objects ... ");
 557   gather_klasses_and_symbols();
 558   GatherSortedSourceObjs doit(this);
 559   iterate_sorted_roots(&doit);
 560   doit.finish();
 561 }
 562 
 563 bool ArchiveBuilder::is_excluded(Klass* klass) {
 564   if (klass->is_instance_klass()) {
 565     InstanceKlass* ik = InstanceKlass::cast(klass);
 566     return SystemDictionaryShared::is_excluded_class(ik);
 567   } else if (klass->is_objArray_klass()) {
 568     Klass* bottom = ObjArrayKlass::cast(klass)->bottom_klass();
 569     if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_shared_static(bottom)) {
 570       // The bottom class is in the static archive so it's clearly not excluded.
 571       assert(CDSConfig::is_dumping_dynamic_archive(), "sanity");
 572       return false;
 573     } else if (bottom->is_instance_klass()) {
 574       return SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(bottom));
 575     }
 576   }
 577 
 578   return false;
 579 }
 580 
 581 ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref *ref) {
 582   address obj = ref->obj();
 583   if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_in_shared_metaspace(obj)) {
 584     // Don't dump existing shared metadata again.
 585     return point_to_it;
 586   } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
 587              ref->msotype() == MetaspaceObj::MethodCountersType ||
 588              ref->msotype() == MetaspaceObj::KlassTrainingDataType ||
 589              ref->msotype() == MetaspaceObj::MethodTrainingDataType ||
 590              ref->msotype() == MetaspaceObj::CompileTrainingDataType) {
 591       return TrainingData::need_data() ? make_a_copy : set_to_null;
 592   } else {
 593     if (ref->msotype() == MetaspaceObj::ClassType) {
 594       Klass* klass = (Klass*)ref->obj();
 595       assert(klass->is_klass(), "must be");
 596       if (is_excluded(klass)) {
 597         ResourceMark rm;
 598         log_debug(cds, dynamic)("Skipping class (excluded): %s", klass->external_name());
 599         return set_to_null;
 600       }
 601     }
 602 
 603     return make_a_copy;
 604   }
 605 }
 606 
 607 void ArchiveBuilder::start_dump_region(DumpRegion* next) {
 608   address bottom = _last_verified_top;
 609   address top = (address)(current_dump_region()->top());
 610   _other_region_used_bytes += size_t(top - bottom);
 611 

 783 }
 784 
 785 bool ArchiveBuilder::has_been_buffered(address src_addr) const {
 786   if (RegeneratedClasses::has_been_regenerated(src_addr) ||
 787       _src_obj_table.get(src_addr) == nullptr ||
 788       get_buffered_addr(src_addr) == nullptr) {
 789     return false;
 790   } else {
 791     return true;
 792   }
 793 }
 794 
 795 address ArchiveBuilder::get_buffered_addr(address src_addr) const {
 796   SourceObjInfo* p = _src_obj_table.get(src_addr);
 797   assert(p != nullptr, "src_addr " INTPTR_FORMAT " is used but has not been archived",
 798          p2i(src_addr));
 799 
 800   return p->buffered_addr();
 801 }
 802 
 803 bool ArchiveBuilder::has_been_archived(address src_addr) const {
 804   SourceObjInfo* p = _src_obj_table.get(src_addr);
 805   return (p != nullptr);
 806 }
 807 
 808 address ArchiveBuilder::get_source_addr(address buffered_addr) const {
 809   assert(is_in_buffer_space(buffered_addr), "must be");
 810   address* src_p = _buffered_to_src_table.get(buffered_addr);
 811   assert(src_p != nullptr && *src_p != nullptr, "must be");
 812   return *src_p;
 813 }
 814 
 815 void ArchiveBuilder::relocate_embedded_pointers(ArchiveBuilder::SourceObjList* src_objs) {
 816   for (int i = 0; i < src_objs->objs()->length(); i++) {
 817     src_objs->relocate(i, this);
 818   }
 819 }
 820 
 821 void ArchiveBuilder::relocate_metaspaceobj_embedded_pointers() {
 822   log_info(cds)("Relocating embedded pointers in core regions ... ");
 823   relocate_embedded_pointers(&_rw_src_objs);
 824   relocate_embedded_pointers(&_ro_src_objs);
 825 }
 826 
 827 #define ADD_COUNT(x) \

1001   log_info(cds)("      boot             " STATS_FORMAT, STATS_PARAMS(boot_klasses));
1002   log_info(cds)("        vm             " STATS_FORMAT, STATS_PARAMS(vm_klasses));
1003   log_info(cds)("      platform         " STATS_FORMAT, STATS_PARAMS(platform_klasses));
1004   log_info(cds)("      app              " STATS_FORMAT, STATS_PARAMS(app_klasses));
1005   log_info(cds)("      unregistered     " STATS_FORMAT, STATS_PARAMS(unregistered_klasses));
1006   log_info(cds)("      (enum)           " STATS_FORMAT, STATS_PARAMS(enum_klasses));
1007   log_info(cds)("      (hidden)         " STATS_FORMAT, STATS_PARAMS(hidden_klasses));
1008   log_info(cds)("      (old)            " STATS_FORMAT, STATS_PARAMS(old_klasses));
1009   log_info(cds)("      (unlinked)       = %5d, boot = %d, plat = %d, app = %d, unreg = %d",
1010                 num_unlinked_klasses, boot_unlinked, platform_unlinked, app_unlinked, unreg_unlinked);
1011   log_info(cds)("    obj array classes  = %5d", num_obj_array_klasses);
1012   log_info(cds)("    type array classes = %5d", num_type_array_klasses);
1013   log_info(cds)("               symbols = %5d", _symbols->length());
1014 
1015 #undef STATS_FORMAT
1016 #undef STATS_PARAMS
1017 
1018   DynamicArchive::make_array_klasses_shareable();
1019 }
1020 
1021 void ArchiveBuilder::make_training_data_shareable() {
1022   auto clean_td = [&] (address& src_obj,  SourceObjInfo& info) {
1023     if (!is_in_buffer_space(info.buffered_addr())) {
1024       return;
1025     }
1026 
1027     if (info.msotype() == MetaspaceObj::KlassTrainingDataType ||
1028         info.msotype() == MetaspaceObj::MethodTrainingDataType ||
1029         info.msotype() == MetaspaceObj::CompileTrainingDataType) {
1030       TrainingData* buffered_td = (TrainingData*)info.buffered_addr();
1031       buffered_td->remove_unshareable_info();
1032     } else if (info.msotype() == MetaspaceObj::MethodDataType) {
1033       MethodData* buffered_mdo = (MethodData*)info.buffered_addr();
1034       buffered_mdo->remove_unshareable_info();
1035     } else if (info.msotype() == MetaspaceObj::MethodCountersType) {
1036       MethodCounters* buffered_mc = (MethodCounters*)info.buffered_addr();
1037       buffered_mc->remove_unshareable_info();
1038     }
1039   };
1040   _src_obj_table.iterate_all(clean_td);
1041 }
1042 
1043 void ArchiveBuilder::serialize_dynamic_archivable_items(SerializeClosure* soc) {
1044   SymbolTable::serialize_shared_table_header(soc, false);
1045   SystemDictionaryShared::serialize_dictionary_headers(soc, false);
1046   DynamicArchive::serialize_array_klasses(soc);
1047   AOTLinkedClassBulkLoader::serialize(soc, false);
1048   FinalImageRecipes::serialize(soc, false);
1049   TrainingData::serialize_training_data(soc);
1050 }
1051 
1052 uintx ArchiveBuilder::buffer_to_offset(address p) const {
1053   address requested_p = to_requested(p);
1054   assert(requested_p >= _requested_static_archive_bottom, "must be");
1055   return requested_p - _requested_static_archive_bottom;
1056 }
1057 
1058 uintx ArchiveBuilder::any_to_offset(address p) const {
1059   if (is_in_mapped_static_archive(p)) {
1060     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
1061     return p - _mapped_static_archive_bottom;
1062   }
1063   if (!is_in_buffer_space(p)) {
1064     // p must be a "source" address
1065     p = get_buffered_addr(p);
1066   }
1067   return buffer_to_offset(p);
1068 }
1069 
1070 void ArchiveBuilder::start_cc_region() {
1071   ro_region()->pack();
1072   start_dump_region(&_cc_region);
1073 }
1074 
1075 void ArchiveBuilder::end_cc_region() {
1076   _cc_region.pack();
1077 }
1078 
1079 address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
1080   address requested_addr = _requested_static_archive_bottom + offset;
1081   address buffered_addr = requested_addr - _buffer_to_requested_delta;
1082   assert(is_in_buffer_space(buffered_addr), "bad offset");
1083   return buffered_addr;
1084 }
1085 
1086 #if INCLUDE_CDS_JAVA_HEAP
1087 narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
1088   assert(CDSConfig::is_dumping_heap(), "sanity");
1089   k = get_buffered_klass(k);
1090   Klass* requested_k = to_requested(k);
1091   const int narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
1092 #ifdef ASSERT
1093   const size_t klass_alignment = MAX2(SharedSpaceObjectAlignment, (size_t)nth_bit(narrow_klass_shift));
1094   assert(is_aligned(k, klass_alignment), "Klass " PTR_FORMAT " misaligned.", p2i(k));
1095 #endif
1096   address narrow_klass_base = _requested_static_archive_bottom; // runtime encoding base == runtime mapping start
1097   // Note: use the "raw" version of encode that takes explicit narrow klass base and shift. Don't use any
1098   // of the variants that do sanity checks, nor any of those that use the current - dump - JVM's encoding setting.

1175     ArchivePtrMarker::compact(_max_non_null_offset);
1176   }
1177 };
1178 
1179 #ifdef _LP64
1180 int ArchiveBuilder::precomputed_narrow_klass_shift() {
1181   // Legacy Mode:
1182   //    We use 32 bits for narrowKlass, which should cover the full 4G Klass range. Shift can be 0.
1183   // CompactObjectHeader Mode:
1184   //    narrowKlass is much smaller, and we use the highest possible shift value to later get the maximum
1185   //    Klass encoding range.
1186   //
1187   // Note that all of this may change in the future, if we decide to correct the pre-calculated
1188   // narrow Klass IDs at archive load time.
1189   assert(UseCompressedClassPointers, "Only needed for compressed class pointers");
1190   return UseCompactObjectHeaders ?  CompressedKlassPointers::max_shift() : 0;
1191 }
1192 #endif // _LP64
1193 
1194 void ArchiveBuilder::relocate_to_requested() {
1195   if (!ro_region()->is_packed()) {
1196     ro_region()->pack();
1197   }
1198 
1199   size_t my_archive_size = buffer_top() - buffer_bottom();
1200 
1201   if (CDSConfig::is_dumping_static_archive()) {
1202     _requested_static_archive_top = _requested_static_archive_bottom + my_archive_size;
1203     RelocateBufferToRequested<true> patcher(this);
1204     patcher.doit();
1205   } else {
1206     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
1207     _requested_dynamic_archive_top = _requested_dynamic_archive_bottom + my_archive_size;
1208     RelocateBufferToRequested<false> patcher(this);
1209     patcher.doit();
1210   }
1211 }
1212 
1213 // Write detailed info to a mapfile to analyze contents of the archive.
1214 // static dump:
1215 //   java -Xshare:dump -Xlog:cds+map=trace:file=cds.map:none:filesize=0
1216 // dynamic dump:
1217 //   java -cp MyApp.jar -XX:ArchiveClassesAtExit=MyApp.jsa \

1499     assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1500     if (java_lang_Class::is_primitive(scratch_mirror)) {
1501       for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1502         BasicType bt = (BasicType)i;
1503         if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1504           oop orig_mirror = Universe::java_mirror(bt);
1505           java_lang_Class::print_signature(orig_mirror, st);
1506           return;
1507         }
1508       }
1509       ShouldNotReachHere();
1510     }
1511     java_lang_Class::print_signature(scratch_mirror, st);
1512   }
1513 
1514   static void log_heap_roots() {
1515     LogStreamHandle(Trace, cds, map, oops) st;
1516     if (st.is_enabled()) {
1517       for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
1518         st.print("roots[%4d]: ", i);
1519         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i).resolve());
1520       }
1521     }
1522   }
1523 
1524   // Example output:
1525   // - The first number is the requested address (if print_requested_addr == true)
1526   // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1527   //     0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
1528   //     0x00000007ffc000f8 (0xfff8001f) [B length: 11
1529   static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
1530     if (source_oop == nullptr) {
1531       st->print_cr("null");
1532     } else {
1533       ResourceMark rm;
1534       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1535       if (print_requested_addr) {
1536         st->print(PTR_FORMAT " ", p2i(requested_obj));
1537       }
1538       if (UseCompressedOops) {
1539         st->print("(0x%08x) ", CompressedOops::narrow_oop_value(requested_obj));
1540       }
1541       if (source_oop->is_array()) {
1542         int array_len = arrayOop(source_oop)->length();
1543         st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
1544       } else {
1545         st->print("%s", source_oop->klass()->external_name());
1546 
1547         if (java_lang_String::is_instance(source_oop)) {
1548           st->print(" ");
1549           java_lang_String::print(source_oop, st);
1550         } else if (java_lang_invoke_MethodType::is_instance(source_oop)) {
1551           st->print(" ");
1552           java_lang_invoke_MethodType::print_signature(source_oop, st);
1553         } else if (java_lang_Class::is_instance(source_oop)) {
1554           oop scratch_mirror = source_oop;
1555 
1556           st->print(" ");
1557           print_class_signature_for_mirror(st, scratch_mirror);
1558 
1559           Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1560           if (src_klass != nullptr && src_klass->is_instance_klass()) {
1561             InstanceKlass* buffered_klass =
1562               ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1563             if (buffered_klass->has_aot_initialized_mirror()) {
1564               st->print(" (aot-inited)");
1565             }
1566           }
1567         }
1568         st->cr();
1569       }
1570     }
1571   }
1572 #endif // INCLUDE_CDS_JAVA_HEAP

1621     if (heap_info->is_used()) {
1622       log_heap_region(heap_info);
1623     }
1624 #endif
1625 
1626     log_info(cds, map)("[End of CDS archive map]");
1627   }
1628 }; // end ArchiveBuilder::CDSMapLogger
1629 
1630 void ArchiveBuilder::print_stats() {
1631   _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
1632 }
1633 
1634 void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) {
1635   // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
1636   // MetaspaceShared::n_regions (internal to hotspot).
1637   assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
1638 
1639   write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1640   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
1641   write_region(mapinfo, MetaspaceShared::cc, &_cc_region, /*read_only=*/false,/*allow_exec=*/false);
1642 
1643   // Split pointer map into read-write and read-only bitmaps
1644   ArchivePtrMarker::initialize_rw_ro_cc_maps(&_rw_ptrmap, &_ro_ptrmap, &_cc_ptrmap);
1645 
1646   size_t bitmap_size_in_bytes;
1647   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(),
1648                                               ArchivePtrMarker::ro_ptrmap(),
1649                                               ArchivePtrMarker::cc_ptrmap(),
1650                                               heap_info,
1651                                               bitmap_size_in_bytes);
1652 
1653   if (heap_info->is_used()) {
1654     _total_heap_region_size = mapinfo->write_heap_region(heap_info);
1655   }
1656 
1657   print_region_stats(mapinfo, heap_info);
1658 
1659   mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address());
1660   mapinfo->set_header_crc(mapinfo->compute_header_crc());
1661   // After this point, we should not write any data into mapinfo->header() since this
1662   // would corrupt its checksum we have calculated before.
1663   mapinfo->write_header();
1664   mapinfo->close();
1665 
1666   if (log_is_enabled(Info, cds)) {
1667     print_stats();
1668   }
1669 
1670   if (log_is_enabled(Info, cds, map)) {

1676 }
1677 
1678 void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only,  bool allow_exec) {
1679   mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1680 }
1681 
1682 void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, ArchiveHeapInfo* heap_info) {
1683   // Print statistics of all the regions
1684   const size_t bitmap_used = mapinfo->region_at(MetaspaceShared::bm)->used();
1685   const size_t bitmap_reserved = mapinfo->region_at(MetaspaceShared::bm)->used_aligned();
1686   const size_t total_reserved = _ro_region.reserved()  + _rw_region.reserved() +
1687                                 bitmap_reserved +
1688                                 _total_heap_region_size;
1689   const size_t total_bytes = _ro_region.used()  + _rw_region.used() +
1690                              bitmap_used +
1691                              _total_heap_region_size;
1692   const double total_u_perc = percent_of(total_bytes, total_reserved);
1693 
1694   _rw_region.print(total_reserved);
1695   _ro_region.print(total_reserved);
1696   _cc_region.print(total_reserved);
1697 
1698   print_bitmap_region_stats(bitmap_used, total_reserved);
1699 
1700   if (heap_info->is_used()) {
1701     print_heap_region_stats(heap_info, total_reserved);
1702   }
1703 
1704   log_debug(cds)("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
1705                  total_bytes, total_reserved, total_u_perc);
1706 }
1707 
1708 void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) {
1709   log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]",
1710                  size, size/double(total_size)*100.0, size);
1711 }
1712 
1713 void ArchiveBuilder::print_heap_region_stats(ArchiveHeapInfo *info, size_t total_size) {
1714   char* start = info->buffer_start();
1715   size_t size = info->buffer_byte_size();
1716   char* top = start + size;
< prev index next >