8344913: Improve -Xlog:cds+map+oop logging for Java mirrors
Reviewed-by: dholmes, ccheung
This commit is contained in:
parent
cf5ee0bda2
commit
f51363e027
@ -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();
|
||||
@ -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;
|
||||
@ -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())) {
|
||||
@ -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) {
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ This is a simple parser for parsing the output of
|
||||
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)
|
||||
@ -149,11 +149,11 @@ public class CDSMapReader {
|
||||
|
||||
// (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]+)");
|
||||
|
Loading…
x
Reference in New Issue
Block a user