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