diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java index 10f50095247..44aecf6413c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java @@ -27,6 +27,7 @@ package jdk.jfr.internal.tool; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.Array; import java.nio.file.Path; import java.time.Duration; import java.time.Instant; @@ -291,7 +292,7 @@ public final class PrettyWriter extends EventPrintWriter { RecordedFrame frame = frames.get(i); if (frame.isJavaFrame() && !frame.getMethod().isHidden()) { printIndent(); - printValue(frame, null, ""); + printJavaFrame(frame, ""); println(); depth++; } @@ -323,12 +324,12 @@ public final class PrettyWriter extends EventPrintWriter { printValue(getValue(struct, v), v, ""); } - private void printArray(Object[] array) { + private void printArray(Object[] array, ValueDescriptor field) { println("["); indent(); for (int i = 0; i < array.length; i++) { printIndent(); - printValue(array[i], null, i + 1 < array.length ? ", " : ""); + printValue(array[i], field, i + 1 < array.length ? ", " : ""); } retract(); printIndent(); @@ -336,81 +337,38 @@ public final class PrettyWriter extends EventPrintWriter { } private void printValue(Object value, ValueDescriptor field, String postFix) { - if (value == null) { - println("N/A" + postFix); - return; - } - if (value instanceof RecordedObject) { - if (value instanceof RecordedThread rt) { - printThread(rt, postFix); - return; - } - if (value instanceof RecordedClass rc) { - printClass(rc, postFix); - return; - } - if (value instanceof RecordedClassLoader rcl) { - printClassLoader(rcl, postFix); - return; - } - if (value instanceof RecordedFrame frame) { - if (frame.isJavaFrame()) { - printJavaFrame((RecordedFrame) value, postFix); - return; - } - } - if (value instanceof RecordedMethod rm) { - println(formatMethod(rm)); - return; - } - if (field.getTypeName().equals(TYPE_OLD_OBJECT)) { - printOldObject((RecordedObject) value); - return; - } - print((RecordedObject) value, postFix); - return; - } - if (value.getClass().isArray()) { - printArray((Object[]) value); - return; + switch (value) { + case null -> println("N/A" + postFix); + case RecordedObject object -> printRecordedObject(object, field, postFix); + case Number number -> printNumber(number, field); + case String text -> println("\"" + text + "\""); + case Duration duration -> printDuration(duration); + case OffsetDateTime dateTime -> printOffsetDateTime(dateTime); + case Object[] array -> printArray(array, field); + default -> println(value); } + } - if (value instanceof Double d) { - if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY) { - println("N/A"); - return; - } - } - if (value instanceof Float f) { - if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY) { - println("N/A"); - return; - } - } - if (value instanceof Long l) { - if (l == Long.MIN_VALUE) { - println("N/A"); - return; - } - } - if (value instanceof Integer i) { - if (i == Integer.MIN_VALUE) { - println("N/A"); - return; - } + private void printRecordedObject(RecordedObject struct, ValueDescriptor field, String postFix) { + switch (struct) { + case RecordedThread rt -> printThread(rt, postFix); + case RecordedClass rc -> printClass(rc, postFix); + case RecordedClassLoader rcl -> printClassLoader(rcl, postFix); + case RecordedFrame rf when rf.isJavaFrame() -> printJavaFrame(rf, postFix); + case RecordedMethod rm -> println(formatMethod(rm)); + case RecordedObject ro when field.getTypeName().equals(TYPE_OLD_OBJECT) -> printOldObject(ro); + default -> print(struct, postFix); } + } - if (field.getContentType() != null) { - if (printFormatted(field, value)) { - return; - } + private void printNumber(Number number, ValueDescriptor field) { + switch (number) { + case Double d when Double.isNaN(d) || d == Double.NEGATIVE_INFINITY -> println("N/A"); + case Float f when Float.isNaN(f) || f == Float.NEGATIVE_INFINITY -> println("N/A"); + case Long l when l == Long.MIN_VALUE -> println("N/A"); + case Integer i when i == Integer.MIN_VALUE -> println("N/A"); + default -> printFormatted(field, number); } - - String text = String.valueOf(value); - if (value instanceof String) { - text = "\"" + text + "\""; - } - println(text); } private void printOldObject(RecordedObject object) { @@ -546,78 +504,73 @@ public final class PrettyWriter extends EventPrintWriter { } } - private boolean printFormatted(ValueDescriptor field, Object value) { - if (value instanceof Duration d) { - if (d.getSeconds() == Long.MIN_VALUE && d.getNano() == 0) { - println("N/A"); - return true; - } - if (d.equals(ChronoUnit.FOREVER.getDuration())) { - println("Forever"); - return true; - } - if (showExact) { - println(String.format("%.9f s", (double) d.toNanos() / 1_000_000_000)); - } else { - println(ValueFormatter.formatDuration(d)); - } - return true; + private void printOffsetDateTime(OffsetDateTime dateTime) { + if (dateTime.equals(OffsetDateTime.MIN)) { + println("N/A"); + return; } - if (value instanceof OffsetDateTime odt) { - if (odt.equals(OffsetDateTime.MIN)) { - println("N/A"); - return true; - } - if (showExact) { - println(TIME_FORMAT_EXACT.format(odt)); - } else { - println(TIME_FORMAT.format(odt)); - } - return true; + if (showExact) { + println(TIME_FORMAT_EXACT.format(dateTime)); + } else { + println(TIME_FORMAT.format(dateTime)); } - Percentage percentage = field.getAnnotation(Percentage.class); - if (percentage != null) { - if (value instanceof Number n) { - double p = 100 * n.doubleValue(); + } + + private void printDuration(Duration duration) { + if (duration.getSeconds() == Long.MIN_VALUE && duration.getNano() == 0) { + println("N/A"); + return; + } + if (duration.equals(ChronoUnit.FOREVER.getDuration())) { + println("Forever"); + return; + } + if (showExact) { + println(String.format("%.9f s", (double) duration.toNanos() / 1_000_000_000)); + } else { + println(ValueFormatter.formatDuration(duration)); + } + } + + private void printFormatted(ValueDescriptor field, Number number) { + if (field.getContentType() != null) { + Percentage percentage = field.getAnnotation(Percentage.class); + if (percentage != null) { + double p = 100 * number.doubleValue(); if (showExact) { println(String.format("%.9f%%", p)); } else { println(String.format("%.2f%%", p)); } - return true; + return; } - } - DataAmount dataAmount = field.getAnnotation(DataAmount.class); - if (dataAmount != null && value instanceof Number number) { - boolean frequency = field.getAnnotation(Frequency.class) != null; - String unit = dataAmount.value(); - boolean bits = unit.equals(DataAmount.BITS); - boolean bytes = unit.equals(DataAmount.BYTES); - if (bits || bytes) { - formatMemory(number.longValue(), bytes, frequency); - return true; + DataAmount dataAmount = field.getAnnotation(DataAmount.class); + if (dataAmount != null) { + boolean frequency = field.getAnnotation(Frequency.class) != null; + String unit = dataAmount.value(); + boolean bits = unit.equals(DataAmount.BITS); + boolean bytes = unit.equals(DataAmount.BYTES); + if (bits || bytes) { + printMemory(number.longValue(), bytes, frequency); + return; + } } - } - MemoryAddress memoryAddress = field.getAnnotation(MemoryAddress.class); - if (memoryAddress != null) { - if (value instanceof Number n) { - long d = n.longValue(); + MemoryAddress memoryAddress = field.getAnnotation(MemoryAddress.class); + if (memoryAddress != null) { + long d = number.longValue(); println(String.format("0x%08X", d)); - return true; + return; + } + Frequency frequency = field.getAnnotation(Frequency.class); + if (frequency != null) { + println(number + " Hz"); + return; } } - Frequency frequency = field.getAnnotation(Frequency.class); - if (frequency != null) { - if (value instanceof Number) { - println(value + " Hz"); - return true; - } - } - - return false; + println(number); } - private void formatMemory(long value, boolean bytesUnit, boolean frequency) { + private void printMemory(long value, boolean bytesUnit, boolean frequency) { if (showExact) { StringBuilder sb = new StringBuilder(); sb.append(value); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/StructuredWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/StructuredWriter.java index 8e16e5fb0bf..1eabbb49d9b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/StructuredWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/StructuredWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,6 +113,10 @@ abstract class StructuredWriter { println(); } + public final void println(Object object) { + println(String.valueOf(object)); + } + private void updateIndent() { if (indent > indention.length()) { indention = " ".repeat(2 * indent);