< 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 "cds/aotArtifactFinder.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 }

 146   BitMap::idx_t start = BitMap::idx_t(src_info->ptrmap_start()); // inclusive
 147   BitMap::idx_t end = BitMap::idx_t(src_info->ptrmap_end());     // exclusive
 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   _num_dump_regions_used(0),
 157   _requested_static_archive_bottom(nullptr),
 158   _requested_static_archive_top(nullptr),
 159   _requested_dynamic_archive_bottom(nullptr),
 160   _requested_dynamic_archive_top(nullptr),
 161   _mapped_static_archive_bottom(nullptr),
 162   _mapped_static_archive_top(nullptr),
 163   _buffer_to_requested_delta(0),
 164   _rw_region("rw", MAX_SHARED_DELTA),
 165   _ro_region("ro", MAX_SHARED_DELTA),

 166   _ptrmap(mtClassShared),
 167   _rw_ptrmap(mtClassShared),
 168   _ro_ptrmap(mtClassShared),

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

 289 
 290 int ArchiveBuilder::compare_symbols_by_address(Symbol** a, Symbol** b) {
 291   if (a[0] < b[0]) {
 292     return -1;
 293   } else {
 294     assert(a[0] > b[0], "Duplicated symbol %s unexpected", (*a)->as_C_string());
 295     return 1;
 296   }
 297 }
 298 
 299 int ArchiveBuilder::compare_klass_by_name(Klass** a, Klass** b) {
 300   return a[0]->name()->fast_compare(b[0]->name());
 301 }
 302 
 303 void ArchiveBuilder::sort_klasses() {
 304   log_info(cds)("Sorting classes ... ");
 305   _klasses->sort(compare_klass_by_name);
 306 }
 307 
 308 address ArchiveBuilder::reserve_buffer() {
 309   size_t buffer_size = LP64_ONLY(CompressedClassSpaceSize) NOT_LP64(256 * M);

 310   ReservedSpace rs = MemoryReserver::reserve(buffer_size,
 311                                              MetaspaceShared::core_region_alignment(),
 312                                              os::vm_page_size());
 313   if (!rs.is_reserved()) {
 314     log_error(cds)("Failed to reserve %zu bytes of output buffer.", buffer_size);
 315     MetaspaceShared::unrecoverable_writing_error();
 316   }
 317 
 318   // buffer_bottom is the lowest address of the 2 core regions (rw, ro) when
 319   // we are copying the class metadata into the buffer.
 320   address buffer_bottom = (address)rs.base();
 321   log_info(cds)("Reserved output buffer space at " PTR_FORMAT " [%zu bytes]",
 322                 p2i(buffer_bottom), buffer_size);
 323   _shared_rs = rs;
 324 
 325   _buffer_bottom = buffer_bottom;
 326   _current_dump_region = &_rw_region;
 327   _num_dump_regions_used = 1;
 328   _current_dump_region->init(&_shared_rs, &_shared_vs);
 329 

 507     return SystemDictionaryShared::is_excluded_class(ik);
 508   } else if (klass->is_objArray_klass()) {
 509     Klass* bottom = ObjArrayKlass::cast(klass)->bottom_klass();
 510     if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_shared_static(bottom)) {
 511       // The bottom class is in the static archive so it's clearly not excluded.
 512       return false;
 513     } else if (bottom->is_instance_klass()) {
 514       return SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(bottom));
 515     }
 516   }
 517 
 518   return false;
 519 }
 520 
 521 ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref *ref) {
 522   address obj = ref->obj();
 523   if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_in_shared_metaspace(obj)) {
 524     // Don't dump existing shared metadata again.
 525     return point_to_it;
 526   } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
 527              ref->msotype() == MetaspaceObj::MethodCountersType) {
 528     return set_to_null;










 529   } else {
 530     if (ref->msotype() == MetaspaceObj::ClassType) {
 531       Klass* klass = (Klass*)ref->obj();
 532       assert(klass->is_klass(), "must be");
 533       if (is_excluded(klass)) {
 534         ResourceMark rm;
 535         log_debug(cds, dynamic)("Skipping class (excluded): %s", klass->external_name());
 536         return set_to_null;
 537       }
 538     }
 539 
 540     return make_a_copy;
 541   }
 542 }
 543 
 544 void ArchiveBuilder::start_dump_region(DumpRegion* next) {
 545   current_dump_region()->pack(next);
 546   _current_dump_region = next;
 547   _num_dump_regions_used ++;
 548 }

 701 }
 702 
 703 bool ArchiveBuilder::has_been_buffered(address src_addr) const {
 704   if (RegeneratedClasses::has_been_regenerated(src_addr) ||
 705       _src_obj_table.get(src_addr) == nullptr ||
 706       get_buffered_addr(src_addr) == nullptr) {
 707     return false;
 708   } else {
 709     return true;
 710   }
 711 }
 712 
 713 address ArchiveBuilder::get_buffered_addr(address src_addr) const {
 714   SourceObjInfo* p = _src_obj_table.get(src_addr);
 715   assert(p != nullptr, "src_addr " INTPTR_FORMAT " is used but has not been archived",
 716          p2i(src_addr));
 717 
 718   return p->buffered_addr();
 719 }
 720 





 721 address ArchiveBuilder::get_source_addr(address buffered_addr) const {
 722   assert(is_in_buffer_space(buffered_addr), "must be");
 723   address* src_p = _buffered_to_src_table.get(buffered_addr);
 724   assert(src_p != nullptr && *src_p != nullptr, "must be");
 725   return *src_p;
 726 }
 727 
 728 void ArchiveBuilder::relocate_embedded_pointers(ArchiveBuilder::SourceObjList* src_objs) {
 729   for (int i = 0; i < src_objs->objs()->length(); i++) {
 730     src_objs->relocate(i, this);
 731   }
 732 }
 733 
 734 void ArchiveBuilder::relocate_metaspaceobj_embedded_pointers() {
 735   log_info(cds)("Relocating embedded pointers in core regions ... ");
 736   relocate_embedded_pointers(&_rw_src_objs);
 737   relocate_embedded_pointers(&_ro_src_objs);
 738 }
 739 
 740 #define ADD_COUNT(x) \

 914   log_info(cds)("      boot             " STATS_FORMAT, STATS_PARAMS(boot_klasses));
 915   log_info(cds)("        vm             " STATS_FORMAT, STATS_PARAMS(vm_klasses));
 916   log_info(cds)("      platform         " STATS_FORMAT, STATS_PARAMS(platform_klasses));
 917   log_info(cds)("      app              " STATS_FORMAT, STATS_PARAMS(app_klasses));
 918   log_info(cds)("      unregistered     " STATS_FORMAT, STATS_PARAMS(unregistered_klasses));
 919   log_info(cds)("      (enum)           " STATS_FORMAT, STATS_PARAMS(enum_klasses));
 920   log_info(cds)("      (hidden)         " STATS_FORMAT, STATS_PARAMS(hidden_klasses));
 921   log_info(cds)("      (old)            " STATS_FORMAT, STATS_PARAMS(old_klasses));
 922   log_info(cds)("      (unlinked)       = %5d, boot = %d, plat = %d, app = %d, unreg = %d",
 923                 num_unlinked_klasses, boot_unlinked, platform_unlinked, app_unlinked, unreg_unlinked);
 924   log_info(cds)("    obj array classes  = %5d", num_obj_array_klasses);
 925   log_info(cds)("    type array classes = %5d", num_type_array_klasses);
 926   log_info(cds)("               symbols = %5d", _symbols->length());
 927 
 928 #undef STATS_FORMAT
 929 #undef STATS_PARAMS
 930 
 931   DynamicArchive::make_array_klasses_shareable();
 932 }
 933 






















 934 void ArchiveBuilder::serialize_dynamic_archivable_items(SerializeClosure* soc) {
 935   SymbolTable::serialize_shared_table_header(soc, false);
 936   SystemDictionaryShared::serialize_dictionary_headers(soc, false);
 937   DynamicArchive::serialize_array_klasses(soc);
 938   AOTLinkedClassBulkLoader::serialize(soc, false);
 939 }
 940 
 941 uintx ArchiveBuilder::buffer_to_offset(address p) const {
 942   address requested_p = to_requested(p);
 943   assert(requested_p >= _requested_static_archive_bottom, "must be");
 944   return requested_p - _requested_static_archive_bottom;
 945 }
 946 
 947 uintx ArchiveBuilder::any_to_offset(address p) const {
 948   if (is_in_mapped_static_archive(p)) {
 949     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
 950     return p - _mapped_static_archive_bottom;
 951   }
 952   if (!is_in_buffer_space(p)) {
 953     // p must be a "source" address
 954     p = get_buffered_addr(p);
 955   }
 956   return buffer_to_offset(p);
 957 }
 958 









 959 address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
 960   address requested_addr = _requested_static_archive_bottom + offset;
 961   address buffered_addr = requested_addr - _buffer_to_requested_delta;
 962   assert(is_in_buffer_space(buffered_addr), "bad offset");
 963   return buffered_addr;
 964 }
 965 
 966 #if INCLUDE_CDS_JAVA_HEAP
 967 narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
 968   assert(CDSConfig::is_dumping_heap(), "sanity");
 969   k = get_buffered_klass(k);
 970   Klass* requested_k = to_requested(k);
 971   const int narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
 972 #ifdef ASSERT
 973   const size_t klass_alignment = MAX2(SharedSpaceObjectAlignment, (size_t)nth_bit(narrow_klass_shift));
 974   assert(is_aligned(k, klass_alignment), "Klass " PTR_FORMAT " misaligned.", p2i(k));
 975 #endif
 976   address narrow_klass_base = _requested_static_archive_bottom; // runtime encoding base == runtime mapping start
 977   // Note: use the "raw" version of encode that takes explicit narrow klass base and shift. Don't use any
 978   // of the variants that do sanity checks, nor any of those that use the current - dump - JVM's encoding setting.

1055     ArchivePtrMarker::compact(_max_non_null_offset);
1056   }
1057 };
1058 
1059 #ifdef _LP64
1060 int ArchiveBuilder::precomputed_narrow_klass_shift() {
1061   // Legacy Mode:
1062   //    We use 32 bits for narrowKlass, which should cover the full 4G Klass range. Shift can be 0.
1063   // CompactObjectHeader Mode:
1064   //    narrowKlass is much smaller, and we use the highest possible shift value to later get the maximum
1065   //    Klass encoding range.
1066   //
1067   // Note that all of this may change in the future, if we decide to correct the pre-calculated
1068   // narrow Klass IDs at archive load time.
1069   assert(UseCompressedClassPointers, "Only needed for compressed class pointers");
1070   return UseCompactObjectHeaders ?  CompressedKlassPointers::max_shift() : 0;
1071 }
1072 #endif // _LP64
1073 
1074 void ArchiveBuilder::relocate_to_requested() {
1075   ro_region()->pack();


1076 
1077   size_t my_archive_size = buffer_top() - buffer_bottom();
1078 
1079   if (CDSConfig::is_dumping_static_archive()) {
1080     _requested_static_archive_top = _requested_static_archive_bottom + my_archive_size;
1081     RelocateBufferToRequested<true> patcher(this);
1082     patcher.doit();
1083   } else {
1084     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
1085     _requested_dynamic_archive_top = _requested_dynamic_archive_bottom + my_archive_size;
1086     RelocateBufferToRequested<false> patcher(this);
1087     patcher.doit();
1088   }
1089 }
1090 
1091 // Write detailed info to a mapfile to analyze contents of the archive.
1092 // static dump:
1093 //   java -Xshare:dump -Xlog:cds+map=trace:file=cds.map:none:filesize=0
1094 // dynamic dump:
1095 //   java -cp MyApp.jar -XX:ArchiveClassesAtExit=MyApp.jsa \

1377     assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1378     if (java_lang_Class::is_primitive(scratch_mirror)) {
1379       for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1380         BasicType bt = (BasicType)i;
1381         if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1382           oop orig_mirror = Universe::java_mirror(bt);
1383           java_lang_Class::print_signature(orig_mirror, st);
1384           return;
1385         }
1386       }
1387       ShouldNotReachHere();
1388     }
1389     java_lang_Class::print_signature(scratch_mirror, st);
1390   }
1391 
1392   static void log_heap_roots() {
1393     LogStreamHandle(Trace, cds, map, oops) st;
1394     if (st.is_enabled()) {
1395       for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
1396         st.print("roots[%4d]: ", i);
1397         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i));
1398       }
1399     }
1400   }
1401 
1402   // Example output:
1403   // - The first number is the requested address (if print_requested_addr == true)
1404   // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1405   //     0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
1406   //     0x00000007ffc000f8 (0xfff8001f) [B length: 11
1407   static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
1408     if (source_oop == nullptr) {
1409       st->print_cr("null");
1410     } else {
1411       ResourceMark rm;
1412       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1413       if (print_requested_addr) {
1414         st->print(PTR_FORMAT " ", p2i(requested_obj));
1415       }
1416       if (UseCompressedOops) {
1417         st->print("(0x%08x) ", CompressedOops::narrow_oop_value(requested_obj));
1418       }
1419       if (source_oop->is_array()) {
1420         int array_len = arrayOop(source_oop)->length();
1421         st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
1422       } else {
1423         st->print("%s", source_oop->klass()->external_name());
1424 
1425         if (java_lang_String::is_instance(source_oop)) {
1426           st->print(" ");
1427           java_lang_String::print(source_oop, st);



1428         } else if (java_lang_Class::is_instance(source_oop)) {
1429           oop scratch_mirror = source_oop;
1430 
1431           st->print(" ");
1432           print_class_signature_for_mirror(st, scratch_mirror);
1433 
1434           Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1435           if (src_klass != nullptr && src_klass->is_instance_klass()) {
1436             InstanceKlass* buffered_klass =
1437               ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1438             if (buffered_klass->has_aot_initialized_mirror()) {
1439               st->print(" (aot-inited)");
1440             }
1441           }
1442         }
1443         st->cr();
1444       }
1445     }
1446   }
1447 #endif // INCLUDE_CDS_JAVA_HEAP

1496     if (heap_info->is_used()) {
1497       log_heap_region(heap_info);
1498     }
1499 #endif
1500 
1501     log_info(cds, map)("[End of CDS archive map]");
1502   }
1503 }; // end ArchiveBuilder::CDSMapLogger
1504 
1505 void ArchiveBuilder::print_stats() {
1506   _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
1507 }
1508 
1509 void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) {
1510   // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
1511   // MetaspaceShared::n_regions (internal to hotspot).
1512   assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
1513 
1514   write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1515   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);

1516 
1517   // Split pointer map into read-write and read-only bitmaps
1518   ArchivePtrMarker::initialize_rw_ro_maps(&_rw_ptrmap, &_ro_ptrmap);
1519 
1520   size_t bitmap_size_in_bytes;
1521   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(), ArchivePtrMarker::ro_ptrmap(), heap_info,



1522                                               bitmap_size_in_bytes);
1523 
1524   if (heap_info->is_used()) {
1525     _total_heap_region_size = mapinfo->write_heap_region(heap_info);
1526   }
1527 
1528   print_region_stats(mapinfo, heap_info);
1529 
1530   mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address());
1531   mapinfo->set_header_crc(mapinfo->compute_header_crc());
1532   // After this point, we should not write any data into mapinfo->header() since this
1533   // would corrupt its checksum we have calculated before.
1534   mapinfo->write_header();
1535   mapinfo->close();
1536 
1537   if (log_is_enabled(Info, cds)) {
1538     print_stats();
1539   }
1540 
1541   if (log_is_enabled(Info, cds, map)) {

1547 }
1548 
1549 void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only,  bool allow_exec) {
1550   mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1551 }
1552 
1553 void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, ArchiveHeapInfo* heap_info) {
1554   // Print statistics of all the regions
1555   const size_t bitmap_used = mapinfo->region_at(MetaspaceShared::bm)->used();
1556   const size_t bitmap_reserved = mapinfo->region_at(MetaspaceShared::bm)->used_aligned();
1557   const size_t total_reserved = _ro_region.reserved()  + _rw_region.reserved() +
1558                                 bitmap_reserved +
1559                                 _total_heap_region_size;
1560   const size_t total_bytes = _ro_region.used()  + _rw_region.used() +
1561                              bitmap_used +
1562                              _total_heap_region_size;
1563   const double total_u_perc = percent_of(total_bytes, total_reserved);
1564 
1565   _rw_region.print(total_reserved);
1566   _ro_region.print(total_reserved);

1567 
1568   print_bitmap_region_stats(bitmap_used, total_reserved);
1569 
1570   if (heap_info->is_used()) {
1571     print_heap_region_stats(heap_info, total_reserved);
1572   }
1573 
1574   log_debug(cds)("total   : %9zu [100.0%% of total] out of %9zu bytes [%5.1f%% used]",
1575                  total_bytes, total_reserved, total_u_perc);
1576 }
1577 
1578 void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) {
1579   log_debug(cds)("bm space: %9zu [ %4.1f%% of total] out of %9zu bytes [100.0%% used]",
1580                  size, size/double(total_size)*100.0, size);
1581 }
1582 
1583 void ArchiveBuilder::print_heap_region_stats(ArchiveHeapInfo *info, size_t total_size) {
1584   char* start = info->buffer_start();
1585   size_t size = info->buffer_byte_size();
1586   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 "cds/aotArtifactFinder.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 "code/SCCache.hpp"
  47 #include "interpreter/abstractInterpreter.hpp"
  48 #include "jvm.h"
  49 #include "logging/log.hpp"
  50 #include "logging/logStream.hpp"
  51 #include "memory/allStatic.hpp"
  52 #include "memory/memoryReserver.hpp"
  53 #include "memory/memRegion.hpp"
  54 #include "memory/resourceArea.hpp"
  55 #include "oops/compressedKlass.inline.hpp"
  56 #include "oops/instanceKlass.hpp"
  57 #include "oops/methodCounters.hpp"
  58 #include "oops/methodData.hpp"
  59 #include "oops/objArrayKlass.hpp"
  60 #include "oops/objArrayOop.inline.hpp"
  61 #include "oops/oopHandle.inline.hpp"
  62 #include "oops/trainingData.hpp"
  63 #include "runtime/arguments.hpp"
  64 #include "runtime/fieldDescriptor.inline.hpp"
  65 #include "runtime/globals_extension.hpp"
  66 #include "runtime/javaThread.hpp"
  67 #include "runtime/sharedRuntime.hpp"
  68 #include "utilities/align.hpp"
  69 #include "utilities/bitMap.inline.hpp"
  70 #include "utilities/formatBuffer.hpp"
  71 
  72 ArchiveBuilder* ArchiveBuilder::_current = nullptr;
  73 
  74 ArchiveBuilder::OtherROAllocMark::~OtherROAllocMark() {
  75   char* newtop = ArchiveBuilder::current()->_ro_region.top();
  76   ArchiveBuilder::alloc_stats()->record_other_type(int(newtop - _oldtop), true);
  77 }
  78 
  79 ArchiveBuilder::SourceObjList::SourceObjList() : _ptrmap(16 * K, mtClassShared) {
  80   _total_bytes = 0;
  81   _objs = new (mtClassShared) GrowableArray<SourceObjInfo*>(128 * K, mtClassShared);
  82 }

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

 296 
 297 int ArchiveBuilder::compare_symbols_by_address(Symbol** a, Symbol** b) {
 298   if (a[0] < b[0]) {
 299     return -1;
 300   } else {
 301     assert(a[0] > b[0], "Duplicated symbol %s unexpected", (*a)->as_C_string());
 302     return 1;
 303   }
 304 }
 305 
 306 int ArchiveBuilder::compare_klass_by_name(Klass** a, Klass** b) {
 307   return a[0]->name()->fast_compare(b[0]->name());
 308 }
 309 
 310 void ArchiveBuilder::sort_klasses() {
 311   log_info(cds)("Sorting classes ... ");
 312   _klasses->sort(compare_klass_by_name);
 313 }
 314 
 315 address ArchiveBuilder::reserve_buffer() {
 316   // SCCache::max_aot_code_size() accounts for cached code region.
 317   size_t buffer_size = LP64_ONLY(CompressedClassSpaceSize) NOT_LP64(256 * M) + SCCache::max_aot_code_size();
 318   ReservedSpace rs = MemoryReserver::reserve(buffer_size,
 319                                              MetaspaceShared::core_region_alignment(),
 320                                              os::vm_page_size());
 321   if (!rs.is_reserved()) {
 322     log_error(cds)("Failed to reserve %zu bytes of output buffer.", buffer_size);
 323     MetaspaceShared::unrecoverable_writing_error();
 324   }
 325 
 326   // buffer_bottom is the lowest address of the 2 core regions (rw, ro) when
 327   // we are copying the class metadata into the buffer.
 328   address buffer_bottom = (address)rs.base();
 329   log_info(cds)("Reserved output buffer space at " PTR_FORMAT " [%zu bytes]",
 330                 p2i(buffer_bottom), buffer_size);
 331   _shared_rs = rs;
 332 
 333   _buffer_bottom = buffer_bottom;
 334   _current_dump_region = &_rw_region;
 335   _num_dump_regions_used = 1;
 336   _current_dump_region->init(&_shared_rs, &_shared_vs);
 337 

 515     return SystemDictionaryShared::is_excluded_class(ik);
 516   } else if (klass->is_objArray_klass()) {
 517     Klass* bottom = ObjArrayKlass::cast(klass)->bottom_klass();
 518     if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_shared_static(bottom)) {
 519       // The bottom class is in the static archive so it's clearly not excluded.
 520       return false;
 521     } else if (bottom->is_instance_klass()) {
 522       return SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(bottom));
 523     }
 524   }
 525 
 526   return false;
 527 }
 528 
 529 ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref *ref) {
 530   address obj = ref->obj();
 531   if (CDSConfig::is_dumping_dynamic_archive() && MetaspaceShared::is_in_shared_metaspace(obj)) {
 532     // Don't dump existing shared metadata again.
 533     return point_to_it;
 534   } else if (ref->msotype() == MetaspaceObj::MethodDataType ||
 535              ref->msotype() == MetaspaceObj::MethodCountersType ||
 536              ref->msotype() == MetaspaceObj::KlassTrainingDataType ||
 537              ref->msotype() == MetaspaceObj::MethodTrainingDataType ||
 538              ref->msotype() == MetaspaceObj::CompileTrainingDataType) {
 539       return TrainingData::need_data() ? make_a_copy : set_to_null;
 540   } else if (ref->msotype() == MetaspaceObj::AdapterHandlerEntryType) {
 541     if (CDSConfig::is_dumping_adapters()) {
 542       AdapterHandlerEntry* entry = (AdapterHandlerEntry*)ref->obj();
 543       return AdapterHandlerLibrary::is_abstract_method_adapter(entry) ? set_to_null : make_a_copy;
 544     } else {
 545       return set_to_null;
 546     }
 547   } else {
 548     if (ref->msotype() == MetaspaceObj::ClassType) {
 549       Klass* klass = (Klass*)ref->obj();
 550       assert(klass->is_klass(), "must be");
 551       if (is_excluded(klass)) {
 552         ResourceMark rm;
 553         log_debug(cds, dynamic)("Skipping class (excluded): %s", klass->external_name());
 554         return set_to_null;
 555       }
 556     }
 557 
 558     return make_a_copy;
 559   }
 560 }
 561 
 562 void ArchiveBuilder::start_dump_region(DumpRegion* next) {
 563   current_dump_region()->pack(next);
 564   _current_dump_region = next;
 565   _num_dump_regions_used ++;
 566 }

 719 }
 720 
 721 bool ArchiveBuilder::has_been_buffered(address src_addr) const {
 722   if (RegeneratedClasses::has_been_regenerated(src_addr) ||
 723       _src_obj_table.get(src_addr) == nullptr ||
 724       get_buffered_addr(src_addr) == nullptr) {
 725     return false;
 726   } else {
 727     return true;
 728   }
 729 }
 730 
 731 address ArchiveBuilder::get_buffered_addr(address src_addr) const {
 732   SourceObjInfo* p = _src_obj_table.get(src_addr);
 733   assert(p != nullptr, "src_addr " INTPTR_FORMAT " is used but has not been archived",
 734          p2i(src_addr));
 735 
 736   return p->buffered_addr();
 737 }
 738 
 739 bool ArchiveBuilder::has_been_archived(address src_addr) const {
 740   SourceObjInfo* p = _src_obj_table.get(src_addr);
 741   return (p != nullptr);
 742 }
 743 
 744 address ArchiveBuilder::get_source_addr(address buffered_addr) const {
 745   assert(is_in_buffer_space(buffered_addr), "must be");
 746   address* src_p = _buffered_to_src_table.get(buffered_addr);
 747   assert(src_p != nullptr && *src_p != nullptr, "must be");
 748   return *src_p;
 749 }
 750 
 751 void ArchiveBuilder::relocate_embedded_pointers(ArchiveBuilder::SourceObjList* src_objs) {
 752   for (int i = 0; i < src_objs->objs()->length(); i++) {
 753     src_objs->relocate(i, this);
 754   }
 755 }
 756 
 757 void ArchiveBuilder::relocate_metaspaceobj_embedded_pointers() {
 758   log_info(cds)("Relocating embedded pointers in core regions ... ");
 759   relocate_embedded_pointers(&_rw_src_objs);
 760   relocate_embedded_pointers(&_ro_src_objs);
 761 }
 762 
 763 #define ADD_COUNT(x) \

 937   log_info(cds)("      boot             " STATS_FORMAT, STATS_PARAMS(boot_klasses));
 938   log_info(cds)("        vm             " STATS_FORMAT, STATS_PARAMS(vm_klasses));
 939   log_info(cds)("      platform         " STATS_FORMAT, STATS_PARAMS(platform_klasses));
 940   log_info(cds)("      app              " STATS_FORMAT, STATS_PARAMS(app_klasses));
 941   log_info(cds)("      unregistered     " STATS_FORMAT, STATS_PARAMS(unregistered_klasses));
 942   log_info(cds)("      (enum)           " STATS_FORMAT, STATS_PARAMS(enum_klasses));
 943   log_info(cds)("      (hidden)         " STATS_FORMAT, STATS_PARAMS(hidden_klasses));
 944   log_info(cds)("      (old)            " STATS_FORMAT, STATS_PARAMS(old_klasses));
 945   log_info(cds)("      (unlinked)       = %5d, boot = %d, plat = %d, app = %d, unreg = %d",
 946                 num_unlinked_klasses, boot_unlinked, platform_unlinked, app_unlinked, unreg_unlinked);
 947   log_info(cds)("    obj array classes  = %5d", num_obj_array_klasses);
 948   log_info(cds)("    type array classes = %5d", num_type_array_klasses);
 949   log_info(cds)("               symbols = %5d", _symbols->length());
 950 
 951 #undef STATS_FORMAT
 952 #undef STATS_PARAMS
 953 
 954   DynamicArchive::make_array_klasses_shareable();
 955 }
 956 
 957 void ArchiveBuilder::make_training_data_shareable() {
 958   auto clean_td = [&] (address& src_obj,  SourceObjInfo& info) {
 959     if (!is_in_buffer_space(info.buffered_addr())) {
 960       return;
 961     }
 962 
 963     if (info.msotype() == MetaspaceObj::KlassTrainingDataType ||
 964         info.msotype() == MetaspaceObj::MethodTrainingDataType ||
 965         info.msotype() == MetaspaceObj::CompileTrainingDataType) {
 966       TrainingData* buffered_td = (TrainingData*)info.buffered_addr();
 967       buffered_td->remove_unshareable_info();
 968     } else if (info.msotype() == MetaspaceObj::MethodDataType) {
 969       MethodData* buffered_mdo = (MethodData*)info.buffered_addr();
 970       buffered_mdo->remove_unshareable_info();
 971     } else if (info.msotype() == MetaspaceObj::MethodCountersType) {
 972       MethodCounters* buffered_mc = (MethodCounters*)info.buffered_addr();
 973       buffered_mc->remove_unshareable_info();
 974     }
 975   };
 976   _src_obj_table.iterate_all(clean_td);
 977 }
 978 
 979 void ArchiveBuilder::serialize_dynamic_archivable_items(SerializeClosure* soc) {
 980   SymbolTable::serialize_shared_table_header(soc, false);
 981   SystemDictionaryShared::serialize_dictionary_headers(soc, false);
 982   DynamicArchive::serialize_array_klasses(soc);
 983   AOTLinkedClassBulkLoader::serialize(soc, false);
 984 }
 985 
 986 uintx ArchiveBuilder::buffer_to_offset(address p) const {
 987   address requested_p = to_requested(p);
 988   assert(requested_p >= _requested_static_archive_bottom, "must be");
 989   return requested_p - _requested_static_archive_bottom;
 990 }
 991 
 992 uintx ArchiveBuilder::any_to_offset(address p) const {
 993   if (is_in_mapped_static_archive(p)) {
 994     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
 995     return p - _mapped_static_archive_bottom;
 996   }
 997   if (!is_in_buffer_space(p)) {
 998     // p must be a "source" address
 999     p = get_buffered_addr(p);
1000   }
1001   return buffer_to_offset(p);
1002 }
1003 
1004 void ArchiveBuilder::start_cc_region() {
1005   ro_region()->pack();
1006   start_dump_region(&_cc_region);
1007 }
1008 
1009 void ArchiveBuilder::end_cc_region() {
1010   _cc_region.pack();
1011 }
1012 
1013 address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
1014   address requested_addr = _requested_static_archive_bottom + offset;
1015   address buffered_addr = requested_addr - _buffer_to_requested_delta;
1016   assert(is_in_buffer_space(buffered_addr), "bad offset");
1017   return buffered_addr;
1018 }
1019 
1020 #if INCLUDE_CDS_JAVA_HEAP
1021 narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
1022   assert(CDSConfig::is_dumping_heap(), "sanity");
1023   k = get_buffered_klass(k);
1024   Klass* requested_k = to_requested(k);
1025   const int narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift();
1026 #ifdef ASSERT
1027   const size_t klass_alignment = MAX2(SharedSpaceObjectAlignment, (size_t)nth_bit(narrow_klass_shift));
1028   assert(is_aligned(k, klass_alignment), "Klass " PTR_FORMAT " misaligned.", p2i(k));
1029 #endif
1030   address narrow_klass_base = _requested_static_archive_bottom; // runtime encoding base == runtime mapping start
1031   // Note: use the "raw" version of encode that takes explicit narrow klass base and shift. Don't use any
1032   // of the variants that do sanity checks, nor any of those that use the current - dump - JVM's encoding setting.

1109     ArchivePtrMarker::compact(_max_non_null_offset);
1110   }
1111 };
1112 
1113 #ifdef _LP64
1114 int ArchiveBuilder::precomputed_narrow_klass_shift() {
1115   // Legacy Mode:
1116   //    We use 32 bits for narrowKlass, which should cover the full 4G Klass range. Shift can be 0.
1117   // CompactObjectHeader Mode:
1118   //    narrowKlass is much smaller, and we use the highest possible shift value to later get the maximum
1119   //    Klass encoding range.
1120   //
1121   // Note that all of this may change in the future, if we decide to correct the pre-calculated
1122   // narrow Klass IDs at archive load time.
1123   assert(UseCompressedClassPointers, "Only needed for compressed class pointers");
1124   return UseCompactObjectHeaders ?  CompressedKlassPointers::max_shift() : 0;
1125 }
1126 #endif // _LP64
1127 
1128 void ArchiveBuilder::relocate_to_requested() {
1129   if (!ro_region()->is_packed()) {
1130     ro_region()->pack();
1131   }
1132 
1133   size_t my_archive_size = buffer_top() - buffer_bottom();
1134 
1135   if (CDSConfig::is_dumping_static_archive()) {
1136     _requested_static_archive_top = _requested_static_archive_bottom + my_archive_size;
1137     RelocateBufferToRequested<true> patcher(this);
1138     patcher.doit();
1139   } else {
1140     assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
1141     _requested_dynamic_archive_top = _requested_dynamic_archive_bottom + my_archive_size;
1142     RelocateBufferToRequested<false> patcher(this);
1143     patcher.doit();
1144   }
1145 }
1146 
1147 // Write detailed info to a mapfile to analyze contents of the archive.
1148 // static dump:
1149 //   java -Xshare:dump -Xlog:cds+map=trace:file=cds.map:none:filesize=0
1150 // dynamic dump:
1151 //   java -cp MyApp.jar -XX:ArchiveClassesAtExit=MyApp.jsa \

1433     assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1434     if (java_lang_Class::is_primitive(scratch_mirror)) {
1435       for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1436         BasicType bt = (BasicType)i;
1437         if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1438           oop orig_mirror = Universe::java_mirror(bt);
1439           java_lang_Class::print_signature(orig_mirror, st);
1440           return;
1441         }
1442       }
1443       ShouldNotReachHere();
1444     }
1445     java_lang_Class::print_signature(scratch_mirror, st);
1446   }
1447 
1448   static void log_heap_roots() {
1449     LogStreamHandle(Trace, cds, map, oops) st;
1450     if (st.is_enabled()) {
1451       for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
1452         st.print("roots[%4d]: ", i);
1453         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i).resolve());
1454       }
1455     }
1456   }
1457 
1458   // Example output:
1459   // - The first number is the requested address (if print_requested_addr == true)
1460   // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1461   //     0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
1462   //     0x00000007ffc000f8 (0xfff8001f) [B length: 11
1463   static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
1464     if (source_oop == nullptr) {
1465       st->print_cr("null");
1466     } else {
1467       ResourceMark rm;
1468       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1469       if (print_requested_addr) {
1470         st->print(PTR_FORMAT " ", p2i(requested_obj));
1471       }
1472       if (UseCompressedOops) {
1473         st->print("(0x%08x) ", CompressedOops::narrow_oop_value(requested_obj));
1474       }
1475       if (source_oop->is_array()) {
1476         int array_len = arrayOop(source_oop)->length();
1477         st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
1478       } else {
1479         st->print("%s", source_oop->klass()->external_name());
1480 
1481         if (java_lang_String::is_instance(source_oop)) {
1482           st->print(" ");
1483           java_lang_String::print(source_oop, st);
1484         } else if (java_lang_invoke_MethodType::is_instance(source_oop)) {
1485           st->print(" ");
1486           java_lang_invoke_MethodType::print_signature(source_oop, st);
1487         } else if (java_lang_Class::is_instance(source_oop)) {
1488           oop scratch_mirror = source_oop;
1489 
1490           st->print(" ");
1491           print_class_signature_for_mirror(st, scratch_mirror);
1492 
1493           Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1494           if (src_klass != nullptr && src_klass->is_instance_klass()) {
1495             InstanceKlass* buffered_klass =
1496               ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1497             if (buffered_klass->has_aot_initialized_mirror()) {
1498               st->print(" (aot-inited)");
1499             }
1500           }
1501         }
1502         st->cr();
1503       }
1504     }
1505   }
1506 #endif // INCLUDE_CDS_JAVA_HEAP

1555     if (heap_info->is_used()) {
1556       log_heap_region(heap_info);
1557     }
1558 #endif
1559 
1560     log_info(cds, map)("[End of CDS archive map]");
1561   }
1562 }; // end ArchiveBuilder::CDSMapLogger
1563 
1564 void ArchiveBuilder::print_stats() {
1565   _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
1566 }
1567 
1568 void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) {
1569   // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
1570   // MetaspaceShared::n_regions (internal to hotspot).
1571   assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
1572 
1573   write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1574   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
1575   write_region(mapinfo, MetaspaceShared::cc, &_cc_region, /*read_only=*/false,/*allow_exec=*/false);
1576 
1577   // Split pointer map into read-write and read-only bitmaps
1578   ArchivePtrMarker::initialize_rw_ro_cc_maps(&_rw_ptrmap, &_ro_ptrmap, &_cc_ptrmap);
1579 
1580   size_t bitmap_size_in_bytes;
1581   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(),
1582                                               ArchivePtrMarker::ro_ptrmap(),
1583                                               ArchivePtrMarker::cc_ptrmap(),
1584                                               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   _cc_region.print(total_reserved);
1631 
1632   print_bitmap_region_stats(bitmap_used, total_reserved);
1633 
1634   if (heap_info->is_used()) {
1635     print_heap_region_stats(heap_info, total_reserved);
1636   }
1637 
1638   log_debug(cds)("total   : %9zu [100.0%% of total] out of %9zu bytes [%5.1f%% used]",
1639                  total_bytes, total_reserved, total_u_perc);
1640 }
1641 
1642 void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) {
1643   log_debug(cds)("bm space: %9zu [ %4.1f%% of total] out of %9zu bytes [100.0%% used]",
1644                  size, size/double(total_size)*100.0, size);
1645 }
1646 
1647 void ArchiveBuilder::print_heap_region_stats(ArchiveHeapInfo *info, size_t total_size) {
1648   char* start = info->buffer_start();
1649   size_t size = info->buffer_byte_size();
1650   char* top = start + size;
< prev index next >