mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-07 00:48:38 +00:00
8215771: The jfr tool should pretty print reference chains
Reviewed-by: mgronlun
This commit is contained in:
parent
691b2423e0
commit
bc2275c28e
@ -57,9 +57,11 @@ import jdk.jfr.internal.Utils;
|
||||
* This class is also used by {@link RecordedObject#toString()}
|
||||
*/
|
||||
public final class PrettyWriter extends EventPrintWriter {
|
||||
private static final String TYPE_OLD_OBJECT = Type.TYPES_PREFIX + "OldObject";
|
||||
private final static DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
|
||||
private final static Long ZERO = 0L;
|
||||
private boolean showIds;
|
||||
private RecordedEvent currentEvent;
|
||||
|
||||
public PrettyWriter(PrintWriter destination) {
|
||||
super(destination);
|
||||
@ -198,6 +200,7 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
}
|
||||
|
||||
public void print(RecordedEvent event) {
|
||||
currentEvent = event;
|
||||
print(event.getEventType().getName(), " ");
|
||||
println("{");
|
||||
indent();
|
||||
@ -308,7 +311,11 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
println(formatMethod((RecordedMethod) value));
|
||||
return;
|
||||
}
|
||||
print((RecordedObject) value, postFix);
|
||||
if (field.getTypeName().equals(TYPE_OLD_OBJECT)) {
|
||||
printOldObject((RecordedObject) value);
|
||||
return;
|
||||
}
|
||||
print((RecordedObject) value, postFix);
|
||||
return;
|
||||
}
|
||||
if (value.getClass().isArray()) {
|
||||
@ -358,6 +365,70 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
println(text);
|
||||
}
|
||||
|
||||
private void printOldObject(RecordedObject object) {
|
||||
println(" [");
|
||||
indent();
|
||||
printIndent();
|
||||
try {
|
||||
printReferenceChain(object);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// Could not find a field
|
||||
// Not possible to validate fields beforehand using RecordedObject#hasField
|
||||
// since nested objects, for example object.referrer.array.index, requires
|
||||
// an actual array object (which may be null).
|
||||
}
|
||||
retract();
|
||||
printIndent();
|
||||
println("]");
|
||||
}
|
||||
|
||||
private void printReferenceChain(RecordedObject object) {
|
||||
printObject(object, currentEvent.getLong("arrayElements"));
|
||||
for (RecordedObject ref = object.getValue("referrer"); ref != null; ref = object.getValue("referrer")) {
|
||||
long skip = ref.getLong("skip");
|
||||
if (skip > 0) {
|
||||
printIndent();
|
||||
println("...");
|
||||
}
|
||||
String objectHolder = "";
|
||||
long size = Long.MIN_VALUE;
|
||||
RecordedObject array = ref.getValue("array");
|
||||
if (array != null) {
|
||||
long index = array.getLong("index");
|
||||
size = array.getLong("size");
|
||||
objectHolder = "[" + index + "]";
|
||||
}
|
||||
RecordedObject field = ref.getValue("field");
|
||||
if (field != null) {
|
||||
objectHolder = field.getString("name");
|
||||
}
|
||||
printIndent();
|
||||
print(objectHolder);
|
||||
print(" : ");
|
||||
object = ref.getValue("object");
|
||||
if (object != null) {
|
||||
printObject(object, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printObject(RecordedObject object, long arraySize) {
|
||||
RecordedClass clazz = object.getClass("type");
|
||||
if (clazz != null) {
|
||||
String className = clazz.getName();
|
||||
if (className!= null && className.startsWith("[")) {
|
||||
className = decodeDescriptors(className, arraySize > 0 ? Long.toString(arraySize) : "").get(0);
|
||||
}
|
||||
print(className);
|
||||
String description = object.getString("description");
|
||||
if (description != null) {
|
||||
print(" ");
|
||||
print(description);
|
||||
}
|
||||
}
|
||||
println();
|
||||
}
|
||||
|
||||
private void printClassLoader(RecordedClassLoader cl, String postFix) {
|
||||
// Purposely not printing class loader name to avoid cluttered output
|
||||
RecordedClass clazz = cl.getType();
|
||||
@ -388,7 +459,7 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
StringJoiner sj = new StringJoiner(", ");
|
||||
String md = m.getDescriptor().replace("/", ".");
|
||||
String parameter = md.substring(1, md.lastIndexOf(")"));
|
||||
for (String qualifiedName : decodeDescriptors(parameter)) {
|
||||
for (String qualifiedName : decodeDescriptors(parameter, "")) {
|
||||
String typeName = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
|
||||
sj.add(typeName);
|
||||
}
|
||||
@ -409,17 +480,18 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
}
|
||||
String className = clazz.getName();
|
||||
if (className.startsWith("[")) {
|
||||
className = decodeDescriptors(className).get(0);
|
||||
className = decodeDescriptors(className, "").get(0);
|
||||
}
|
||||
println(className + " (classLoader = " + classLoaderName + ")" + postFix);
|
||||
}
|
||||
|
||||
List<String> decodeDescriptors(String descriptor) {
|
||||
List<String> decodeDescriptors(String descriptor, String arraySize) {
|
||||
List<String> descriptors = new ArrayList<>();
|
||||
for (int index = 0; index < descriptor.length(); index++) {
|
||||
String arrayBrackets = "";
|
||||
while (descriptor.charAt(index) == '[') {
|
||||
arrayBrackets += "[]";
|
||||
arrayBrackets = arrayBrackets + "[" + arraySize + "]" ;
|
||||
arraySize = "";
|
||||
index++;
|
||||
}
|
||||
char c = descriptor.charAt(index);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user