< prev index next >

src/hotspot/share/cds/archiveBuilder.cpp

Print this page

  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/aotLogging.hpp"
  29 #include "cds/archiveBuilder.hpp"
  30 #include "cds/archiveHeapWriter.hpp"
  31 #include "cds/archiveUtils.hpp"
  32 #include "cds/cdsConfig.hpp"
  33 #include "cds/cppVtables.hpp"
  34 #include "cds/dumpAllocStats.hpp"
  35 #include "cds/dynamicArchive.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/aotCodeCache.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 }
  83 
  84 ArchiveBuilder::SourceObjList::~SourceObjList() {
  85   delete _objs;
  86 }

 169   _ptrmap.iterate(&relocator, start, end);
 170 }
 171 
 172 ArchiveBuilder::ArchiveBuilder() :
 173   _current_dump_region(nullptr),
 174   _buffer_bottom(nullptr),
 175   _requested_static_archive_bottom(nullptr),
 176   _requested_static_archive_top(nullptr),
 177   _requested_dynamic_archive_bottom(nullptr),
 178   _requested_dynamic_archive_top(nullptr),
 179   _mapped_static_archive_bottom(nullptr),
 180   _mapped_static_archive_top(nullptr),
 181   _buffer_to_requested_delta(0),
 182   _pz_region("pz", MAX_SHARED_DELTA), // protection zone -- used only during dumping; does NOT exist in cds archive.
 183   _rw_region("rw", MAX_SHARED_DELTA),
 184   _ro_region("ro", MAX_SHARED_DELTA),
 185   _ac_region("ac", MAX_SHARED_DELTA),
 186   _ptrmap(mtClassShared),
 187   _rw_ptrmap(mtClassShared),
 188   _ro_ptrmap(mtClassShared),

 189   _rw_src_objs(),
 190   _ro_src_objs(),
 191   _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 192   _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 193   _total_heap_region_size(0)
 194 {
 195   _klasses = new (mtClassShared) GrowableArray<Klass*>(4 * K, mtClassShared);
 196   _symbols = new (mtClassShared) GrowableArray<Symbol*>(256 * K, mtClassShared);
 197   _entropy_seed = 0x12345678;
 198   _relocated_ptr_info._num_ptrs = 0;
 199   _relocated_ptr_info._num_tagged_ptrs = 0;
 200   _relocated_ptr_info._num_nulled_ptrs = 0;
 201   assert(_current == nullptr, "must be");
 202   _current = this;
 203 }
 204 
 205 ArchiveBuilder::~ArchiveBuilder() {
 206   assert(_current == this, "must be");
 207   _current = nullptr;
 208 

1310 
1311     for (size_t seg_idx = 0; seg_idx < segments.count(); seg_idx++) {
1312       address requested_start = ArchiveHeapWriter::buffered_addr_to_requested_addr(start);
1313       st.print_cr(PTR_FORMAT ": Heap roots segment [%d]",
1314                   p2i(requested_start), segments.size_in_elems(seg_idx));
1315       start += segments.size_in_bytes(seg_idx);
1316     }
1317     log_heap_roots();
1318 
1319     while (start < end) {
1320       size_t byte_size;
1321       oop source_oop = ArchiveHeapWriter::buffered_addr_to_source_obj(start);
1322       address requested_start = ArchiveHeapWriter::buffered_addr_to_requested_addr(start);
1323       st.print(PTR_FORMAT ": @@ Object ", p2i(requested_start));
1324 
1325       if (source_oop != nullptr) {
1326         // This is a regular oop that got archived.
1327         // Don't print the requested addr again as we have just printed it at the beginning of the line.
1328         // Example:
1329         // 0x00000007ffd27938: @@ Object (0xfffa4f27) java.util.HashMap

1330         print_oop_info_cr(&st, source_oop, /*print_requested_addr=*/false);
1331         byte_size = source_oop->size() * BytesPerWord;
1332       } else if ((byte_size = ArchiveHeapWriter::get_filler_size_at(start)) > 0) {
1333         // We have a filler oop, which also does not exist in BufferOffsetToSourceObjectTable.
1334         // Example:
1335         // 0x00000007ffc3ffd8: @@ Object filler 40 bytes
1336         st.print_cr("filler %zu bytes", byte_size);
1337       } else {
1338         ShouldNotReachHere();
1339       }
1340 
1341       address oop_end = start + byte_size;
1342       log_as_hex(start, oop_end, requested_start, /*is_heap=*/true);
1343 
1344       if (source_oop != nullptr) {
1345         log_oop_details(heap_info, source_oop, /*buffered_addr=*/start);
1346       }
1347       start = oop_end;
1348     }
1349   }

1359   public:
1360     ArchivedFieldPrinter(ArchiveHeapInfo* heap_info, outputStream* st, oop src_obj, address buffered_addr) :
1361       _heap_info(heap_info), _st(st), _source_obj(src_obj), _buffered_addr(buffered_addr) {}
1362 
1363     void do_field(fieldDescriptor* fd) {
1364       _st->print(" - ");
1365       BasicType ft = fd->field_type();
1366       switch (ft) {
1367       case T_ARRAY:
1368       case T_OBJECT:
1369         {
1370           fd->print_on(_st); // print just the name and offset
1371           oop obj = _source_obj->obj_field(fd->offset());
1372           if (java_lang_Class::is_instance(obj)) {
1373             obj = HeapShared::scratch_java_mirror(obj);
1374           }
1375           print_oop_info_cr(_st, obj);
1376         }
1377         break;
1378       default:
1379         if (ArchiveHeapWriter::is_marked_as_native_pointer(_heap_info, _source_obj, fd->offset())) {
1380           print_as_native_pointer(fd);
1381         } else {
1382           fd->print_on_for(_st, cast_to_oop(_buffered_addr)); // name, offset, value
1383           _st->cr();
1384         }
1385       }
1386     }
1387 
1388     void print_as_native_pointer(fieldDescriptor* fd) {
1389       LP64_ONLY(assert(fd->field_type() == T_LONG, "must be"));
1390       NOT_LP64 (assert(fd->field_type() == T_INT,  "must be"));
1391 
1392       // We have a field that looks like an integer, but it's actually a pointer to a MetaspaceObj.
1393       address source_native_ptr = (address)
1394           LP64_ONLY(_source_obj->long_field(fd->offset()))
1395           NOT_LP64( _source_obj->int_field (fd->offset()));
1396       ArchiveBuilder* builder = ArchiveBuilder::current();
1397 
1398       // The value of the native pointer at runtime.
1399       address requested_native_ptr = builder->to_requested(builder->get_buffered_addr(source_native_ptr));
1400 
1401       // The address of _source_obj at runtime
1402       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(_source_obj);
1403       // The address of this field in the requested space
1404       assert(requested_obj != nullptr, "Attempting to load field from null oop");
1405       address requested_field_addr = cast_from_oop<address>(requested_obj) + fd->offset();
1406 
1407       fd->print_on(_st);
1408       _st->print_cr(PTR_FORMAT " (marked metadata pointer @" PTR_FORMAT " )",
1409                     p2i(requested_native_ptr), p2i(requested_field_addr));
1410     }
1411   };
1412 
1413   // Print the fields of instanceOops, or the elements of arrayOops
1414   static void log_oop_details(ArchiveHeapInfo* heap_info, oop source_oop, address buffered_addr) {
1415     LogStreamHandle(Trace, aot, map, oops) st;
1416     if (st.is_enabled()) {
1417       Klass* source_klass = source_oop->klass();
1418       ArchiveBuilder* builder = ArchiveBuilder::current();
1419       Klass* requested_klass = builder->to_requested(builder->get_buffered_addr(source_klass));
1420 
1421       st.print(" - klass: ");
1422       source_klass->print_value_on(&st);

1467     assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1468     if (java_lang_Class::is_primitive(scratch_mirror)) {
1469       for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1470         BasicType bt = (BasicType)i;
1471         if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1472           oop orig_mirror = Universe::java_mirror(bt);
1473           java_lang_Class::print_signature(orig_mirror, st);
1474           return;
1475         }
1476       }
1477       ShouldNotReachHere();
1478     }
1479     java_lang_Class::print_signature(scratch_mirror, st);
1480   }
1481 
1482   static void log_heap_roots() {
1483     LogStreamHandle(Trace, aot, map, oops) st;
1484     if (st.is_enabled()) {
1485       for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
1486         st.print("roots[%4d]: ", i);
1487         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i));
1488       }
1489     }
1490   }
1491 
1492   // Example output:
1493   // - The first number is the requested address (if print_requested_addr == true)
1494   // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1495   //     0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
1496   //     0x00000007ffc000f8 (0xfff8001f) [B length: 11
1497   static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
1498     if (source_oop == nullptr) {
1499       st->print_cr("null");
1500     } else {
1501       ResourceMark rm;

1502       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1503       if (print_requested_addr) {
1504         st->print(PTR_FORMAT " ", p2i(requested_obj));
1505       }
1506       if (UseCompressedOops) {
1507         st->print("(0x%08x) ", CompressedOops::narrow_oop_value(requested_obj));
1508       }
1509       if (source_oop->is_array()) {
1510         int array_len = arrayOop(source_oop)->length();
1511         st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
1512       } else {
1513         st->print("%s", source_oop->klass()->external_name());
1514 
1515         if (java_lang_String::is_instance(source_oop)) {
1516           st->print(" ");
1517           java_lang_String::print(source_oop, st);



1518         } else if (java_lang_Class::is_instance(source_oop)) {
1519           oop scratch_mirror = source_oop;
1520 
1521           st->print(" ");
1522           print_class_signature_for_mirror(st, scratch_mirror);
1523 
1524           Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1525           if (src_klass != nullptr && src_klass->is_instance_klass()) {
1526             InstanceKlass* buffered_klass =
1527               ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1528             if (buffered_klass->has_aot_initialized_mirror()) {
1529               st->print(" (aot-inited)");
1530             }
1531           }
1532         }
1533         st->cr();
1534       }
1535     }
1536   }
1537 #endif // INCLUDE_CDS_JAVA_HEAP

1547       if (is_heap && UseCompressedOops) {
1548         // This makes the compressed oop pointers easier to read, but
1549         // longs and doubles will be split into two words.
1550         unitsize = sizeof(narrowOop);
1551       }
1552       os::print_hex_dump(&lsh, base, top, unitsize, /* print_ascii=*/true, /* bytes_per_line=*/32, requested_base);
1553     }
1554   }
1555 
1556   static void log_header(FileMapInfo* mapinfo) {
1557     LogStreamHandle(Info, aot, map) lsh;
1558     if (lsh.is_enabled()) {
1559       mapinfo->print(&lsh);
1560     }
1561   }
1562 
1563 public:
1564   static void log(ArchiveBuilder* builder, FileMapInfo* mapinfo,
1565                   ArchiveHeapInfo* heap_info,
1566                   char* bitmap, size_t bitmap_size_in_bytes) {





1567     log_info(aot, map)("%s CDS archive map for %s", CDSConfig::is_dumping_static_archive() ? "Static" : "Dynamic", mapinfo->full_path());
1568 
1569     address header = address(mapinfo->header());
1570     address header_end = header + mapinfo->header()->header_size();
1571     log_region("header", header, header_end, nullptr);
1572     log_header(mapinfo);
1573     log_as_hex(header, header_end, nullptr);
1574 
1575     DumpRegion* rw_region = &builder->_rw_region;
1576     DumpRegion* ro_region = &builder->_ro_region;
1577 
1578     log_metaspace_region("rw region", rw_region, &builder->_rw_src_objs);
1579     log_metaspace_region("ro region", ro_region, &builder->_ro_src_objs);
1580 
1581     address bitmap_end = address(bitmap + bitmap_size_in_bytes);
1582     log_region("bitmap", address(bitmap), bitmap_end, nullptr);
1583     log_as_hex((address)bitmap, bitmap_end, nullptr);
1584 
1585 #if INCLUDE_CDS_JAVA_HEAP
1586     if (heap_info->is_used()) {

1589 #endif
1590 
1591     log_info(aot, map)("[End of CDS archive map]");
1592   }
1593 }; // end ArchiveBuilder::CDSMapLogger
1594 
1595 void ArchiveBuilder::print_stats() {
1596   _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
1597 }
1598 
1599 void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) {
1600   // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
1601   // MetaspaceShared::n_regions (internal to hotspot).
1602   assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
1603 
1604   write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1605   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
1606   write_region(mapinfo, MetaspaceShared::ac, &_ac_region, /*read_only=*/false,/*allow_exec=*/false);
1607 
1608   // Split pointer map into read-write and read-only bitmaps
1609   ArchivePtrMarker::initialize_rw_ro_maps(&_rw_ptrmap, &_ro_ptrmap);
1610 
1611   size_t bitmap_size_in_bytes;
1612   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(), ArchivePtrMarker::ro_ptrmap(), heap_info,



1613                                               bitmap_size_in_bytes);
1614 
1615   if (heap_info->is_used()) {
1616     _total_heap_region_size = mapinfo->write_heap_region(heap_info);
1617   }
1618 
1619   print_region_stats(mapinfo, heap_info);
1620 
1621   mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address());
1622   mapinfo->set_header_crc(mapinfo->compute_header_crc());
1623   // After this point, we should not write any data into mapinfo->header() since this
1624   // would corrupt its checksum we have calculated before.
1625   mapinfo->write_header();
1626   mapinfo->close();
1627 

1628   if (log_is_enabled(Info, aot)) {
1629     log_info(aot)("Full module graph = %s", CDSConfig::is_dumping_full_module_graph() ? "enabled" : "disabled");
1630     print_stats();
1631   }
1632 
1633   if (log_is_enabled(Info, aot, map)) {
1634     CDSMapLogger::log(this, mapinfo, heap_info,
1635                       bitmap, bitmap_size_in_bytes);
1636   }
1637   CDS_JAVA_HEAP_ONLY(HeapShared::destroy_archived_object_cache());
1638   FREE_C_HEAP_ARRAY(char, bitmap);
1639 }
1640 
1641 void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only,  bool allow_exec) {
1642   mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1643 }
1644 
1645 void ArchiveBuilder::count_relocated_pointer(bool tagged, bool nulled) {
1646   _relocated_ptr_info._num_ptrs ++;
1647   _relocated_ptr_info._num_tagged_ptrs += tagged ? 1 : 0;
1648   _relocated_ptr_info._num_nulled_ptrs += nulled ? 1 : 0;
1649 }

  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/aotLogging.hpp"
  29 #include "cds/archiveBuilder.hpp"
  30 #include "cds/archiveHeapWriter.hpp"
  31 #include "cds/archiveUtils.hpp"
  32 #include "cds/cdsConfig.hpp"
  33 #include "cds/cppVtables.hpp"
  34 #include "cds/dumpAllocStats.hpp"
  35 #include "cds/dynamicArchive.hpp"
  36 #include "cds/finalImageRecipes.hpp"
  37 #include "cds/heapShared.hpp"
  38 #include "cds/metaspaceShared.hpp"
  39 #include "cds/regeneratedClasses.hpp"
  40 #include "classfile/classLoader.hpp"
  41 #include "classfile/classLoaderDataShared.hpp"
  42 #include "classfile/classLoaderExt.hpp"
  43 #include "classfile/javaClasses.hpp"
  44 #include "classfile/symbolTable.hpp"
  45 #include "classfile/systemDictionaryShared.hpp"
  46 #include "classfile/vmClasses.hpp"
  47 #include "code/aotCodeCache.hpp"
  48 #include "interpreter/abstractInterpreter.hpp"
  49 #include "jvm.h"
  50 #include "logging/log.hpp"
  51 #include "logging/logStream.hpp"
  52 #include "memory/allStatic.hpp"
  53 #include "memory/memoryReserver.hpp"
  54 #include "memory/memRegion.hpp"
  55 #include "memory/resourceArea.hpp"
  56 #include "oops/compressedKlass.inline.hpp"
  57 #include "oops/instanceKlass.hpp"
  58 #include "oops/methodCounters.hpp"
  59 #include "oops/methodData.hpp"
  60 #include "oops/objArrayKlass.hpp"
  61 #include "oops/objArrayOop.inline.hpp"
  62 #include "oops/oopHandle.inline.hpp"
  63 #include "oops/trainingData.hpp"
  64 #include "runtime/arguments.hpp"
  65 #include "runtime/fieldDescriptor.inline.hpp"
  66 #include "runtime/globals_extension.hpp"
  67 #include "runtime/javaThread.hpp"
  68 #include "runtime/safepointVerifiers.hpp"
  69 #include "runtime/sharedRuntime.hpp"
  70 #include "utilities/align.hpp"
  71 #include "utilities/bitMap.inline.hpp"
  72 #include "utilities/formatBuffer.hpp"
  73 
  74 ArchiveBuilder* ArchiveBuilder::_current = nullptr;
  75 
  76 ArchiveBuilder::OtherROAllocMark::~OtherROAllocMark() {
  77   char* newtop = ArchiveBuilder::current()->_ro_region.top();
  78   ArchiveBuilder::alloc_stats()->record_other_type(int(newtop - _oldtop), true);
  79 }
  80 
  81 ArchiveBuilder::SourceObjList::SourceObjList() : _ptrmap(16 * K, mtClassShared) {
  82   _total_bytes = 0;
  83   _objs = new (mtClassShared) GrowableArray<SourceObjInfo*>(128 * K, mtClassShared);
  84 }
  85 
  86 ArchiveBuilder::SourceObjList::~SourceObjList() {
  87   delete _objs;
  88 }

 171   _ptrmap.iterate(&relocator, start, end);
 172 }
 173 
 174 ArchiveBuilder::ArchiveBuilder() :
 175   _current_dump_region(nullptr),
 176   _buffer_bottom(nullptr),
 177   _requested_static_archive_bottom(nullptr),
 178   _requested_static_archive_top(nullptr),
 179   _requested_dynamic_archive_bottom(nullptr),
 180   _requested_dynamic_archive_top(nullptr),
 181   _mapped_static_archive_bottom(nullptr),
 182   _mapped_static_archive_top(nullptr),
 183   _buffer_to_requested_delta(0),
 184   _pz_region("pz", MAX_SHARED_DELTA), // protection zone -- used only during dumping; does NOT exist in cds archive.
 185   _rw_region("rw", MAX_SHARED_DELTA),
 186   _ro_region("ro", MAX_SHARED_DELTA),
 187   _ac_region("ac", MAX_SHARED_DELTA),
 188   _ptrmap(mtClassShared),
 189   _rw_ptrmap(mtClassShared),
 190   _ro_ptrmap(mtClassShared),
 191   _ac_ptrmap(mtClassShared),
 192   _rw_src_objs(),
 193   _ro_src_objs(),
 194   _src_obj_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 195   _buffered_to_src_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE),
 196   _total_heap_region_size(0)
 197 {
 198   _klasses = new (mtClassShared) GrowableArray<Klass*>(4 * K, mtClassShared);
 199   _symbols = new (mtClassShared) GrowableArray<Symbol*>(256 * K, mtClassShared);
 200   _entropy_seed = 0x12345678;
 201   _relocated_ptr_info._num_ptrs = 0;
 202   _relocated_ptr_info._num_tagged_ptrs = 0;
 203   _relocated_ptr_info._num_nulled_ptrs = 0;
 204   assert(_current == nullptr, "must be");
 205   _current = this;
 206 }
 207 
 208 ArchiveBuilder::~ArchiveBuilder() {
 209   assert(_current == this, "must be");
 210   _current = nullptr;
 211 

1313 
1314     for (size_t seg_idx = 0; seg_idx < segments.count(); seg_idx++) {
1315       address requested_start = ArchiveHeapWriter::buffered_addr_to_requested_addr(start);
1316       st.print_cr(PTR_FORMAT ": Heap roots segment [%d]",
1317                   p2i(requested_start), segments.size_in_elems(seg_idx));
1318       start += segments.size_in_bytes(seg_idx);
1319     }
1320     log_heap_roots();
1321 
1322     while (start < end) {
1323       size_t byte_size;
1324       oop source_oop = ArchiveHeapWriter::buffered_addr_to_source_obj(start);
1325       address requested_start = ArchiveHeapWriter::buffered_addr_to_requested_addr(start);
1326       st.print(PTR_FORMAT ": @@ Object ", p2i(requested_start));
1327 
1328       if (source_oop != nullptr) {
1329         // This is a regular oop that got archived.
1330         // Don't print the requested addr again as we have just printed it at the beginning of the line.
1331         // Example:
1332         // 0x00000007ffd27938: @@ Object (0xfffa4f27) java.util.HashMap
1333         assert(HeapShared::has_been_archived(source_oop), "did you call HeapShared::rehash_archived_object_cache()?");
1334         print_oop_info_cr(&st, source_oop, /*print_requested_addr=*/false);
1335         byte_size = source_oop->size() * BytesPerWord;
1336       } else if ((byte_size = ArchiveHeapWriter::get_filler_size_at(start)) > 0) {
1337         // We have a filler oop, which also does not exist in BufferOffsetToSourceObjectTable.
1338         // Example:
1339         // 0x00000007ffc3ffd8: @@ Object filler 40 bytes
1340         st.print_cr("filler %zu bytes", byte_size);
1341       } else {
1342         ShouldNotReachHere();
1343       }
1344 
1345       address oop_end = start + byte_size;
1346       log_as_hex(start, oop_end, requested_start, /*is_heap=*/true);
1347 
1348       if (source_oop != nullptr) {
1349         log_oop_details(heap_info, source_oop, /*buffered_addr=*/start);
1350       }
1351       start = oop_end;
1352     }
1353   }

1363   public:
1364     ArchivedFieldPrinter(ArchiveHeapInfo* heap_info, outputStream* st, oop src_obj, address buffered_addr) :
1365       _heap_info(heap_info), _st(st), _source_obj(src_obj), _buffered_addr(buffered_addr) {}
1366 
1367     void do_field(fieldDescriptor* fd) {
1368       _st->print(" - ");
1369       BasicType ft = fd->field_type();
1370       switch (ft) {
1371       case T_ARRAY:
1372       case T_OBJECT:
1373         {
1374           fd->print_on(_st); // print just the name and offset
1375           oop obj = _source_obj->obj_field(fd->offset());
1376           if (java_lang_Class::is_instance(obj)) {
1377             obj = HeapShared::scratch_java_mirror(obj);
1378           }
1379           print_oop_info_cr(_st, obj);
1380         }
1381         break;
1382       default:
1383         if (ArchiveHeapWriter::is_marked_as_native_pointer(_heap_info, _buffered_addr, fd->offset())) {
1384           print_as_native_pointer(fd);
1385         } else {
1386           fd->print_on_for(_st, cast_to_oop(_buffered_addr)); // name, offset, value
1387           _st->cr();
1388         }
1389       }
1390     }
1391 
1392     void print_as_native_pointer(fieldDescriptor* fd) {
1393       LP64_ONLY(assert(fd->field_type() == T_LONG, "must be"));
1394       NOT_LP64 (assert(fd->field_type() == T_INT,  "must be"));
1395 
1396       // We have a field that looks like an integer, but it's actually a pointer to a MetaspaceObj.
1397       address source_native_ptr = (address)
1398           LP64_ONLY(_source_obj->long_field(fd->offset()))
1399           NOT_LP64( _source_obj->int_field (fd->offset()));
1400       ArchiveBuilder* builder = ArchiveBuilder::current();
1401 
1402       // The value of the native pointer at runtime.
1403       address requested_native_ptr = builder->to_requested(builder->get_buffered_addr(source_native_ptr));
1404 
1405       // The address of _source_obj at runtime
1406       oop requested_obj = cast_to_oop(ArchiveHeapWriter::buffered_addr_to_requested_addr(_buffered_addr));
1407       // The address of this field in the requested space
1408       assert(requested_obj != nullptr, "Attempting to load field from null oop");
1409       address requested_field_addr = cast_from_oop<address>(requested_obj) + fd->offset();
1410 
1411       fd->print_on(_st);
1412       _st->print_cr(PTR_FORMAT " (marked metadata pointer @" PTR_FORMAT " )",
1413                     p2i(requested_native_ptr), p2i(requested_field_addr));
1414     }
1415   };
1416 
1417   // Print the fields of instanceOops, or the elements of arrayOops
1418   static void log_oop_details(ArchiveHeapInfo* heap_info, oop source_oop, address buffered_addr) {
1419     LogStreamHandle(Trace, aot, map, oops) st;
1420     if (st.is_enabled()) {
1421       Klass* source_klass = source_oop->klass();
1422       ArchiveBuilder* builder = ArchiveBuilder::current();
1423       Klass* requested_klass = builder->to_requested(builder->get_buffered_addr(source_klass));
1424 
1425       st.print(" - klass: ");
1426       source_klass->print_value_on(&st);

1471     assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1472     if (java_lang_Class::is_primitive(scratch_mirror)) {
1473       for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1474         BasicType bt = (BasicType)i;
1475         if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1476           oop orig_mirror = Universe::java_mirror(bt);
1477           java_lang_Class::print_signature(orig_mirror, st);
1478           return;
1479         }
1480       }
1481       ShouldNotReachHere();
1482     }
1483     java_lang_Class::print_signature(scratch_mirror, st);
1484   }
1485 
1486   static void log_heap_roots() {
1487     LogStreamHandle(Trace, aot, map, oops) st;
1488     if (st.is_enabled()) {
1489       for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
1490         st.print("roots[%4d]: ", i);
1491         print_oop_info_cr(&st, HeapShared::pending_roots()->at(i).resolve());
1492       }
1493     }
1494   }
1495 
1496   // Example output:
1497   // - The first number is the requested address (if print_requested_addr == true)
1498   // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1499   //     0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
1500   //     0x00000007ffc000f8 (0xfff8001f) [B length: 11
1501   static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
1502     if (source_oop == nullptr) {
1503       st->print_cr("null");
1504     } else {
1505       ResourceMark rm;
1506       assert(HeapShared::has_been_archived(source_oop), "did you call HeapShared::rehash_archived_object_cache()?");
1507       oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1508       if (print_requested_addr) {
1509         st->print(PTR_FORMAT " ", p2i(requested_obj));
1510       }
1511       if (UseCompressedOops) {
1512         st->print("(0x%08x) ", CompressedOops::narrow_oop_value(requested_obj));
1513       }
1514       if (source_oop->is_array()) {
1515         int array_len = arrayOop(source_oop)->length();
1516         st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
1517       } else {
1518         st->print("%s", source_oop->klass()->external_name());
1519 
1520         if (java_lang_String::is_instance(source_oop)) {
1521           st->print(" ");
1522           java_lang_String::print(source_oop, st);
1523         } else if (java_lang_invoke_MethodType::is_instance(source_oop)) {
1524           st->print(" ");
1525           java_lang_invoke_MethodType::print_signature(source_oop, st);
1526         } else if (java_lang_Class::is_instance(source_oop)) {
1527           oop scratch_mirror = source_oop;
1528 
1529           st->print(" ");
1530           print_class_signature_for_mirror(st, scratch_mirror);
1531 
1532           Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1533           if (src_klass != nullptr && src_klass->is_instance_klass()) {
1534             InstanceKlass* buffered_klass =
1535               ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1536             if (buffered_klass->has_aot_initialized_mirror()) {
1537               st->print(" (aot-inited)");
1538             }
1539           }
1540         }
1541         st->cr();
1542       }
1543     }
1544   }
1545 #endif // INCLUDE_CDS_JAVA_HEAP

1555       if (is_heap && UseCompressedOops) {
1556         // This makes the compressed oop pointers easier to read, but
1557         // longs and doubles will be split into two words.
1558         unitsize = sizeof(narrowOop);
1559       }
1560       os::print_hex_dump(&lsh, base, top, unitsize, /* print_ascii=*/true, /* bytes_per_line=*/32, requested_base);
1561     }
1562   }
1563 
1564   static void log_header(FileMapInfo* mapinfo) {
1565     LogStreamHandle(Info, aot, map) lsh;
1566     if (lsh.is_enabled()) {
1567       mapinfo->print(&lsh);
1568     }
1569   }
1570 
1571 public:
1572   static void log(ArchiveBuilder* builder, FileMapInfo* mapinfo,
1573                   ArchiveHeapInfo* heap_info,
1574                   char* bitmap, size_t bitmap_size_in_bytes) {
1575     // HeapShared::archived_object_cache() uses raw address of oop to compute the hash. At this point,
1576     // a GC might have happened and moved some of the oops, so the table needs to be rehashed.
1577     NoSafepointVerifier nsv;
1578     HeapShared::rehash_archived_object_cache();
1579 
1580     log_info(aot, map)("%s CDS archive map for %s", CDSConfig::is_dumping_static_archive() ? "Static" : "Dynamic", mapinfo->full_path());
1581 
1582     address header = address(mapinfo->header());
1583     address header_end = header + mapinfo->header()->header_size();
1584     log_region("header", header, header_end, nullptr);
1585     log_header(mapinfo);
1586     log_as_hex(header, header_end, nullptr);
1587 
1588     DumpRegion* rw_region = &builder->_rw_region;
1589     DumpRegion* ro_region = &builder->_ro_region;
1590 
1591     log_metaspace_region("rw region", rw_region, &builder->_rw_src_objs);
1592     log_metaspace_region("ro region", ro_region, &builder->_ro_src_objs);
1593 
1594     address bitmap_end = address(bitmap + bitmap_size_in_bytes);
1595     log_region("bitmap", address(bitmap), bitmap_end, nullptr);
1596     log_as_hex((address)bitmap, bitmap_end, nullptr);
1597 
1598 #if INCLUDE_CDS_JAVA_HEAP
1599     if (heap_info->is_used()) {

1602 #endif
1603 
1604     log_info(aot, map)("[End of CDS archive map]");
1605   }
1606 }; // end ArchiveBuilder::CDSMapLogger
1607 
1608 void ArchiveBuilder::print_stats() {
1609   _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
1610 }
1611 
1612 void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveHeapInfo* heap_info) {
1613   // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
1614   // MetaspaceShared::n_regions (internal to hotspot).
1615   assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
1616 
1617   write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1618   write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
1619   write_region(mapinfo, MetaspaceShared::ac, &_ac_region, /*read_only=*/false,/*allow_exec=*/false);
1620 
1621   // Split pointer map into read-write and read-only bitmaps
1622   ArchivePtrMarker::initialize_rw_ro_ac_maps(&_rw_ptrmap, &_ro_ptrmap, &_ac_ptrmap);
1623 
1624   size_t bitmap_size_in_bytes;
1625   char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::rw_ptrmap(),
1626                                               ArchivePtrMarker::ro_ptrmap(),
1627                                               ArchivePtrMarker::ac_ptrmap(),
1628                                               heap_info,
1629                                               bitmap_size_in_bytes);
1630 
1631   if (heap_info->is_used()) {
1632     _total_heap_region_size = mapinfo->write_heap_region(heap_info);
1633   }
1634 
1635   print_region_stats(mapinfo, heap_info);
1636 
1637   mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address());
1638   mapinfo->set_header_crc(mapinfo->compute_header_crc());
1639   // After this point, we should not write any data into mapinfo->header() since this
1640   // would corrupt its checksum we have calculated before.
1641   mapinfo->write_header();
1642   mapinfo->close();
1643 
1644   aot_log_info(aot)("Full module graph = %s", CDSConfig::is_dumping_full_module_graph() ? "enabled" : "disabled");
1645   if (log_is_enabled(Info, aot)) {

1646     print_stats();
1647   }
1648 
1649   if (log_is_enabled(Info, aot, map)) {
1650     CDSMapLogger::log(this, mapinfo, heap_info,
1651                       bitmap, bitmap_size_in_bytes);
1652   }
1653   CDS_JAVA_HEAP_ONLY(HeapShared::destroy_archived_object_cache());
1654   FREE_C_HEAP_ARRAY(char, bitmap);
1655 }
1656 
1657 void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only,  bool allow_exec) {
1658   mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1659 }
1660 
1661 void ArchiveBuilder::count_relocated_pointer(bool tagged, bool nulled) {
1662   _relocated_ptr_info._num_ptrs ++;
1663   _relocated_ptr_info._num_tagged_ptrs += tagged ? 1 : 0;
1664   _relocated_ptr_info._num_nulled_ptrs += nulled ? 1 : 0;
1665 }
< prev index next >