Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8344913: Improve -Xlog:cds+map+oop logging for Java mirrors #22345

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 84 additions & 12 deletions src/hotspot/share/cds/archiveBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,10 +1294,15 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {

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

// ArchivedFieldPrinter is used to print the fields of archived objects. We can't
// use _source_obj->print_on(), because we want to print the oop fields
// in _source_obj with their requested addresses using print_oop_with_requested_addr_cr().
// in _source_obj with their requested addresses using print_oop_info_cr().
class ArchivedFieldPrinter : public FieldClosure {
ArchiveHeapInfo* _heap_info;
outputStream* _st;
Expand All @@ -1331,8 +1336,14 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
switch (ft) {
case T_ARRAY:
case T_OBJECT:
fd->print_on(_st); // print just the name and offset
print_oop_with_requested_addr_cr(_st, _source_obj->obj_field(fd->offset()));
{
fd->print_on(_st); // print just the name and offset
oop obj = _source_obj->obj_field(fd->offset());
if (java_lang_Class::is_instance(obj)) {
obj = HeapShared::scratch_java_mirror(obj);
}
print_oop_info_cr(_st, obj);
}
break;
default:
if (ArchiveHeapWriter::is_marked_as_native_pointer(_heap_info, _source_obj, fd->offset())) {
Expand Down Expand Up @@ -1388,37 +1399,78 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
objArrayOop source_obj_array = objArrayOop(source_oop);
for (int i = 0; i < source_obj_array->length(); i++) {
st.print(" -%4d: ", i);
print_oop_with_requested_addr_cr(&st, source_obj_array->obj_at(i));
oop obj = source_obj_array->obj_at(i);
if (java_lang_Class::is_instance(obj)) {
obj = HeapShared::scratch_java_mirror(obj);
}
print_oop_info_cr(&st, obj);
}
} else {
st.print_cr(" - fields (" SIZE_FORMAT " words):", source_oop->size());
ArchivedFieldPrinter print_field(heap_info, &st, source_oop, buffered_addr);
InstanceKlass::cast(source_klass)->print_nonstatic_fields(&print_field);

if (java_lang_Class::is_instance(source_oop)) {
oop scratch_mirror = source_oop;
st.print(" - signature: ");
print_class_signature_for_mirror(&st, scratch_mirror);
st.cr();

Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
if (src_klass != nullptr && src_klass->is_instance_klass()) {
oop rr = HeapShared::scratch_resolved_references(InstanceKlass::cast(src_klass)->constants());
st.print(" - archived_resolved_references: ");
print_oop_info_cr(&st, rr);

// We need to print the fields in the scratch_mirror, not the original mirror.
// (if a class is not aot-initialized, static fields in its scratch mirror will be cleared).
assert(scratch_mirror == HeapShared::scratch_java_mirror(src_klass->java_mirror()), "sanity");
st.print_cr("- ---- static fields (%d):", java_lang_Class::static_oop_field_count(scratch_mirror));
InstanceKlass::cast(src_klass)->do_local_static_fields(&print_field);
}
}
}
}
}

static void print_class_signature_for_mirror(outputStream* st, oop scratch_mirror) {
assert(java_lang_Class::is_instance(scratch_mirror), "sanity");
if (java_lang_Class::is_primitive(scratch_mirror)) {
for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
BasicType bt = (BasicType)i;
if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) {
oop orig_mirror = Universe::java_mirror(bt);
java_lang_Class::print_signature(orig_mirror, st);
return;
}
}
ShouldNotReachHere();
}
java_lang_Class::print_signature(scratch_mirror, st);
}

static void log_heap_roots() {
LogStreamHandle(Trace, cds, map, oops) st;
if (st.is_enabled()) {
for (int i = 0; i < HeapShared::pending_roots()->length(); i++) {
st.print("roots[%4d]: ", i);
print_oop_with_requested_addr_cr(&st, HeapShared::pending_roots()->at(i));
print_oop_info_cr(&st, HeapShared::pending_roots()->at(i));
}
}
}

// The output looks like this. The first number is the requested address. The second number is
// the narrowOop version of the requested address.
// 0x00000007ffc7e840 (0xfff8fd08) java.lang.Class
// Example output:
// - The first number is the requested address (if print_requested_addr == true)
// - The second number is the narrowOop version of the requested address (if UseCompressedOops == true)
// 0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array;
// 0x00000007ffc000f8 (0xfff8001f) [B length: 11
static void print_oop_with_requested_addr_cr(outputStream* st, oop source_oop, bool print_addr = true) {
static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) {
if (source_oop == nullptr) {
st->print_cr("null");
} else {
ResourceMark rm;
oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop);
if (print_addr) {
if (print_requested_addr) {
st->print(PTR_FORMAT " ", p2i(requested_obj));
}
if (UseCompressedOops) {
Expand All @@ -1428,7 +1480,27 @@ class ArchiveBuilder::CDSMapLogger : AllStatic {
int array_len = arrayOop(source_oop)->length();
st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len);
} else {
st->print_cr("%s", source_oop->klass()->external_name());
st->print("%s", source_oop->klass()->external_name());

if (java_lang_String::is_instance(source_oop)) {
st->print(" ");
java_lang_String::print(source_oop, st);
} else if (java_lang_Class::is_instance(source_oop)) {
oop scratch_mirror = source_oop;

st->print(" ");
print_class_signature_for_mirror(st, scratch_mirror);

Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror);
if (src_klass != nullptr && src_klass->is_instance_klass()) {
InstanceKlass* buffered_klass =
ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass));
if (buffered_klass->has_aot_initialized_mirror()) {
st->print(" (aot-inited)");
}
}
}
st->cr();
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions test/hotspot/jtreg/runtime/cds/CDSMapReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
The map file contains patterns like this for the heap objects:

======================================================================
0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String
0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String ""
- klass: 'java/lang/String' 0x0000000800010220
- fields (3 words):
- private 'hash' 'I' @12 0 (0x00000000)
Expand Down Expand Up @@ -149,11 +149,11 @@ public static class Field {

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

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

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