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