Skip to content

Commit f51363e

Browse files
committedNov 28, 2024
8344913: Improve -Xlog:cds+map+oop logging for Java mirrors
Reviewed-by: dholmes, ccheung
1 parent cf5ee0b commit f51363e

File tree

2 files changed

+87
-15
lines changed

2 files changed

+87
-15
lines changed
 

‎src/hotspot/share/cds/archiveBuilder.cpp

+84-12
Original file line numberDiff line numberDiff line change
@@ -1294,10 +1294,15 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
12941294

12951295
if (source_oop != nullptr) {
12961296
// This is a regular oop that got archived.
1297-
print_oop_with_requested_addr_cr(&st, source_oop, false);
1297+
// Don't print the requested addr again as we have just printed it at the beginning of the line.
1298+
// Example:
1299+
// 0x00000007ffd27938: @@ Object (0xfffa4f27) java.util.HashMap
1300+
print_oop_info_cr(&st, source_oop, /*print_requested_addr=*/false);
12981301
byte_size = source_oop->size() * BytesPerWord;
12991302
} else if ((byte_size = ArchiveHeapWriter::get_filler_size_at(start)) > 0) {
13001303
// We have a filler oop, which also does not exist in BufferOffsetToSourceObjectTable.
1304+
// Example:
1305+
// 0x00000007ffc3ffd8: @@ Object filler 40 bytes
13011306
st.print_cr("filler " SIZE_FORMAT " bytes", byte_size);
13021307
} else {
13031308
ShouldNotReachHere();
@@ -1315,7 +1320,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
13151320

13161321
// ArchivedFieldPrinter is used to print the fields of archived objects. We can't
13171322
// use _source_obj->print_on(), because we want to print the oop fields
1318-
// in _source_obj with their requested addresses using print_oop_with_requested_addr_cr().
1323+
// in _source_obj with their requested addresses using print_oop_info_cr().
13191324
class ArchivedFieldPrinter : public FieldClosure {
13201325
ArchiveHeapInfo* _heap_info;
13211326
outputStream* _st;
@@ -1331,8 +1336,14 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
13311336
switch (ft) {
13321337
case T_ARRAY:
13331338
case T_OBJECT:
1334-
fd->print_on(_st); // print just the name and offset
1335-
print_oop_with_requested_addr_cr(_st, _source_obj->obj_field(fd->offset()));
1339+
{
1340+
fd->print_on(_st); // print just the name and offset
1341+
oop obj = _source_obj->obj_field(fd->offset());
1342+
if (java_lang_Class::is_instance(obj)) {
1343+
obj = HeapShared::scratch_java_mirror(obj);
1344+
}
1345+
print_oop_info_cr(_st, obj);
1346+
}
13361347
break;
13371348
default:
13381349
if (ArchiveHeapWriter::is_marked_as_native_pointer(_heap_info, _source_obj, fd->offset())) {
@@ -1388,37 +1399,78 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
13881399
objArrayOop source_obj_array = objArrayOop(source_oop);
13891400
for (int i = 0; i < source_obj_array->length(); i++) {
13901401
st.print(" -%4d: ", i);
1391-
print_oop_with_requested_addr_cr(&st, source_obj_array->obj_at(i));
1402+
oop obj = source_obj_array->obj_at(i);
1403+
if (java_lang_Class::is_instance(obj)) {
1404+
obj = HeapShared::scratch_java_mirror(obj);
1405+
}
1406+
print_oop_info_cr(&st, obj);
13921407
}
13931408
} else {
13941409
st.print_cr(" - fields (" SIZE_FORMAT " words):", source_oop->size());
13951410
ArchivedFieldPrinter print_field(heap_info, &st, source_oop, buffered_addr);
13961411
InstanceKlass::cast(source_klass)->print_nonstatic_fields(&print_field);
1412+
1413+
if (java_lang_Class::is_instance(source_oop)) {
1414+
oop scratch_mirror = source_oop;
1415+
st.print(" - signature: ");
1416+
print_class_signature_for_mirror(&st, scratch_mirror);
1417+
st.cr();
1418+
1419+
Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1420+
if (src_klass != nullptr && src_klass->is_instance_klass()) {
1421+
oop rr = HeapShared::scratch_resolved_references(InstanceKlass::cast(src_klass)->constants());
1422+
st.print(" - archived_resolved_references: ");
1423+
print_oop_info_cr(&st, rr);
1424+
1425+
// We need to print the fields in the scratch_mirror, not the original mirror.
1426+
// (if a class is not aot-initialized, static fields in its scratch mirror will be cleared).
1427+
assert(scratch_mirror == HeapShared::scratch_java_mirror(src_klass->java_mirror()), "sanity");
1428+
st.print_cr("- ---- static fields (%d):", java_lang_Class::static_oop_field_count(scratch_mirror));
1429+
InstanceKlass::cast(src_klass)->do_local_static_fields(&print_field);
1430+
}
1431+
}
1432+
}
1433+
}
1434+
}
1435+
1436+
static void print_class_signature_for_mirror(outputStream* st, oop scratch_mirror) {
1437+
assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
1438+
if (java_lang_Class::is_primitive(scratch_mirror)) {
1439+
for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
1440+
BasicType bt = (BasicType)i;
1441+
if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
1442+
oop orig_mirror = Universe::java_mirror(bt);
1443+
java_lang_Class::print_signature(orig_mirror, st);
1444+
return;
1445+
}
13971446
}
1447+
ShouldNotReachHere();
13981448
}
1449+
java_lang_Class::print_signature(scratch_mirror, st);
13991450
}
14001451

14011452
static void log_heap_roots() {
14021453
LogStreamHandle(Trace, cds, map, oops) st;
14031454
if (st.is_enabled()) {
14041455
for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
14051456
st.print("roots[%4d]: ", i);
1406-
print_oop_with_requested_addr_cr(&st, HeapShared::pending_roots()->at(i));
1457+
print_oop_info_cr(&st, HeapShared::pending_roots()->at(i));
14071458
}
14081459
}
14091460
}
14101461

1411-
// The output looks like this. The first number is the requested address. The second number is
1412-
// the narrowOop version of the requested address.
1413-
// 0x00000007ffc7e840 (0xfff8fd08) java.lang.Class
1462+
// Example output:
1463+
// - The first number is the requested address (if print_requested_addr == true)
1464+
// - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
1465+
// 0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
14141466
// 0x00000007ffc000f8 (0xfff8001f) [B length: 11
1415-
static void print_oop_with_requested_addr_cr(outputStream* st, oop source_oop, bool print_addr = true) {
1467+
static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
14161468
if (source_oop == nullptr) {
14171469
st->print_cr("null");
14181470
} else {
14191471
ResourceMark rm;
14201472
oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
1421-
if (print_addr) {
1473+
if (print_requested_addr) {
14221474
st->print(PTR_FORMAT " ", p2i(requested_obj));
14231475
}
14241476
if (UseCompressedOops) {
@@ -1428,7 +1480,27 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
14281480
int array_len = arrayOop(source_oop)->length();
14291481
st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
14301482
} else {
1431-
st->print_cr("%s", source_oop->klass()->external_name());
1483+
st->print("%s", source_oop->klass()->external_name());
1484+
1485+
if (java_lang_String::is_instance(source_oop)) {
1486+
st->print(" ");
1487+
java_lang_String::print(source_oop, st);
1488+
} else if (java_lang_Class::is_instance(source_oop)) {
1489+
oop scratch_mirror = source_oop;
1490+
1491+
st->print(" ");
1492+
print_class_signature_for_mirror(st, scratch_mirror);
1493+
1494+
Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
1495+
if (src_klass != nullptr && src_klass->is_instance_klass()) {
1496+
InstanceKlass* buffered_klass =
1497+
ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
1498+
if (buffered_klass->has_aot_initialized_mirror()) {
1499+
st->print(" (aot-inited)");
1500+
}
1501+
}
1502+
}
1503+
st->cr();
14321504
}
14331505
}
14341506
}

‎test/hotspot/jtreg/runtime/cds/CDSMapReader.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
The map file contains patterns like this for the heap objects:
3939
4040
======================================================================
41-
0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String
41+
0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String ""
4242
- klass: 'java/lang/String' 0x0000000800010220
4343
- fields (3 words):
4444
- private 'hash' 'I' @12 0 (0x00000000)
@@ -149,11 +149,11 @@ public static class Field {
149149

150150
// (one address)
151151
// 0x00000007ffc00000: @@ Object java.lang.String
152-
static Pattern objPattern1 = Pattern.compile("^0x([0-9a-f]+): @@ Object (.*)");
152+
static Pattern objPattern1 = Pattern.compile("^0x([0-9a-f]+): @@ Object ([^ ]*)");
153153

154154
// (two addresses)
155155
// 0x00000007ffc00000: @@ Object (0xfff80000) java.lang.String
156-
static Pattern objPattern2 = Pattern.compile("^0x([0-9a-f]+): @@ Object [(]0x([0-9a-f]+)[)] (.*)");
156+
static Pattern objPattern2 = Pattern.compile("^0x([0-9a-f]+): @@ Object [(]0x([0-9a-f]+)[)] ([^ ]*)");
157157

158158
// - klass: 'java/lang/String' 0x0000000800010290
159159
static Pattern instanceObjKlassPattern = Pattern.compile("^ - klass: '([^']+)' 0x([0-9a-f]+)");

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Nov 28, 2024

@openjdk-notifier[bot]
Please sign in to comment.