src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java

Print this page

        

*** 20,34 **** * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.compiler.hotspot.debug; ! import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; - import java.nio.file.Path; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; --- 20,33 ---- * or visit www.oracle.com if you need additional information or have any * questions. */ package org.graalvm.compiler.hotspot.debug; ! import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set;
*** 37,57 **** import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import org.graalvm.compiler.core.common.SuppressFBWarnings; import org.graalvm.compiler.debug.CSVUtil; - import org.graalvm.compiler.debug.GraalDebugConfig; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.replacements.HotspotSnippetsOptions; import org.graalvm.compiler.nodes.debug.DynamicCounterNode; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionValues; - import org.graalvm.compiler.options.UniquePathUtilities; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; //JaCoCo Exclude --- 36,54 ----
*** 103,115 **** " dacapo = 'err, starting =====, PASSED in'%n" + " specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'", type = OptionType.Debug) public static final OptionKey<String> BenchmarkDynamicCounters = new OptionKey<>(null); @Option(help = "Use grouping separators for number printing", type = OptionType.Debug) public static final OptionKey<Boolean> DynamicCountersPrintGroupSeparator = new OptionKey<>(true); ! @Option(help = "Print in human readable format", type = OptionType.Debug) ! public static final OptionKey<Boolean> DynamicCountersHumanReadable = new OptionKey<>(true); ! @Option(help = "Benchmark counters log file (default is stdout)", type = OptionType.Debug) public static final OptionKey<String> BenchmarkCountersFile = new OptionKey<>(null); @Option(help = "Dump dynamic counters", type = OptionType.Debug) public static final OptionKey<Boolean> BenchmarkCountersDumpDynamic = new OptionKey<>(true); @Option(help = "Dump static counters", type = OptionType.Debug) public static final OptionKey<Boolean> BenchmarkCountersDumpStatic = new OptionKey<>(false); --- 100,112 ---- " dacapo = 'err, starting =====, PASSED in'%n" + " specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'", type = OptionType.Debug) public static final OptionKey<String> BenchmarkDynamicCounters = new OptionKey<>(null); @Option(help = "Use grouping separators for number printing", type = OptionType.Debug) public static final OptionKey<Boolean> DynamicCountersPrintGroupSeparator = new OptionKey<>(true); ! @Option(help = "File to which benchmark counters are dumped. A CSV format is used if the file ends with .csv " + ! "otherwise a more human readable format is used. The fields in the CSV format are: " + ! "category, group, name, value", type = OptionType.Debug) public static final OptionKey<String> BenchmarkCountersFile = new OptionKey<>(null); @Option(help = "Dump dynamic counters", type = OptionType.Debug) public static final OptionKey<Boolean> BenchmarkCountersDumpDynamic = new OptionKey<>(true); @Option(help = "Dump static counters", type = OptionType.Debug) public static final OptionKey<Boolean> BenchmarkCountersDumpStatic = new OptionKey<>(false);
*** 168,233 **** return counter; } private static synchronized void dump(OptionValues options, PrintStream out, double seconds, long[] counters, int maxRows) { if (!counterMap.isEmpty()) { ! if (Options.DynamicCountersHumanReadable.getValue(options)) { ! out.println("====== dynamic counters (" + counterMap.size() + " in total) ======"); ! } TreeSet<String> set = new TreeSet<>(); counterMap.forEach((nameGroup, counter) -> set.add(counter.group)); for (String group : set) { if (group != null) { if (Options.BenchmarkCountersDumpStatic.getValue(options)) { ! dumpCounters(options, out, seconds, counters, true, group, maxRows); } if (Options.BenchmarkCountersDumpDynamic.getValue(options)) { ! dumpCounters(options, out, seconds, counters, false, group, maxRows); } } } - if (Options.DynamicCountersHumanReadable.getValue(options)) { - out.println("============================"); } clear(counters); } } ! private static synchronized void clear(long[] counters) { ! delta = counters; } ! private static synchronized void dumpCounters(OptionValues options, PrintStream out, double seconds, long[] counters, boolean staticCounter, String group, int maxRows) { ! ! // collect the numbers ! long[] array; ! if (staticCounter) { ! array = new long[counterMap.size()]; for (Counter counter : counterMap.values()) { array[counter.index] = counter.staticCounters.get(); } ! } else { ! array = counters.clone(); ! for (int i = 0; i < array.length; i++) { ! array[i] -= delta[i]; } } ! Set<Entry<String, Counter>> counterEntrySet = counterMap.entrySet(); ! if (Options.DynamicCountersHumanReadable.getValue(options)) { ! dumpHumanReadable(options, out, seconds, staticCounter, group, maxRows, array, counterEntrySet); ! } else { ! dumpComputerReadable(out, staticCounter, group, array, counterEntrySet); } } private static String getName(String nameGroup, String group) { return nameGroup.substring(0, nameGroup.length() - group.length() - 1); } ! private static void dumpHumanReadable(OptionValues options, PrintStream out, double seconds, boolean staticCounter, String group, int maxRows, long[] array, ! Set<Entry<String, Counter>> counterEntrySet) { // sort the counters by putting them into a sorted map TreeMap<Long, String> sorted = new TreeMap<>(); long sum = 0; for (Map.Entry<String, Counter> entry : counterEntrySet) { Counter counter = entry.getValue(); --- 165,270 ---- return counter; } private static synchronized void dump(OptionValues options, PrintStream out, double seconds, long[] counters, int maxRows) { if (!counterMap.isEmpty()) { ! try (Dumper dumper = Dumper.getDumper(options, out, counterMap.size(), seconds, maxRows)) { TreeSet<String> set = new TreeSet<>(); counterMap.forEach((nameGroup, counter) -> set.add(counter.group)); for (String group : set) { if (group != null) { if (Options.BenchmarkCountersDumpStatic.getValue(options)) { ! dumper.dumpCounters(true, group, collectStaticCounters(), counterMap.entrySet(), options); } if (Options.BenchmarkCountersDumpDynamic.getValue(options)) { ! dumper.dumpCounters(false, group, collectDynamicCounters(counters), counterMap.entrySet(), options); } } } } clear(counters); } } ! private static synchronized long[] collectDynamicCounters(long[] counters) { ! long[] array = counters.clone(); ! for (int i = 0; i < array.length; i++) { ! array[i] -= delta[i]; ! } ! return array; } ! private static synchronized long[] collectStaticCounters() { ! long[] array = new long[counterMap.size()]; for (Counter counter : counterMap.values()) { array[counter.index] = counter.staticCounters.get(); } ! return array; ! } ! ! private static synchronized void clear(long[] counters) { ! delta = counters; } + + private static boolean shouldDumpComputerReadable(OptionValues options) { + String dumpFile = Options.BenchmarkCountersFile.getValue(options); + return dumpFile != null && (dumpFile.endsWith(".csv") || dumpFile.endsWith(".CSV")); } ! ! private abstract static class Dumper implements AutoCloseable { ! public static Dumper getDumper(OptionValues options, PrintStream out, int counterSize, double second, int maxRows) { ! Dumper dumper = shouldDumpComputerReadable(options) ? new ComputerReadableDumper(out) : new HumanReadableDumper(out, second, maxRows); ! dumper.start(counterSize); ! return dumper; ! } ! ! protected final PrintStream out; ! ! private Dumper(PrintStream out) { ! this.out = out; } + + protected abstract void start(int size); + + public abstract void dumpCounters(boolean staticCounter, String group, long[] array, Set<Entry<String, Counter>> counterEntrySet, OptionValues options); + + @Override + public abstract void close(); + } private static String getName(String nameGroup, String group) { return nameGroup.substring(0, nameGroup.length() - group.length() - 1); } ! private static long percentage(long counter, long sum) { ! return (counter * 200 + 1) / sum / 2; ! } ! ! private static class HumanReadableDumper extends Dumper { ! private final double seconds; ! private final int maxRows; ! ! HumanReadableDumper(PrintStream out, double seconds, int maxRows) { ! super(out); ! this.seconds = seconds; ! this.maxRows = maxRows; ! } ! ! @Override ! public void start(int size) { ! out.println("====== dynamic counters (" + size + " in total) ======"); ! } ! ! @Override ! public void close() { ! out.println("============================"); ! } ! ! @Override ! public void dumpCounters(boolean staticCounter, String group, long[] array, Set<Entry<String, Counter>> counterEntrySet, OptionValues options) { // sort the counters by putting them into a sorted map TreeMap<Long, String> sorted = new TreeMap<>(); long sum = 0; for (Map.Entry<String, Counter> entry : counterEntrySet) { Counter counter = entry.getValue();
*** 278,291 **** out.format(Locale.US, numFmt + " total\n", sum); } } } } private static final String CSV_FMT = CSVUtil.buildFormatString("%s", "%s", "%s", "%d"); ! private static void dumpComputerReadable(PrintStream out, boolean staticCounter, String group, long[] array, Set<Entry<String, Counter>> counterEntrySet) { String category = staticCounter ? "static counters" : "dynamic counters"; for (Map.Entry<String, Counter> entry : counterEntrySet) { Counter counter = entry.getValue(); if (counter.group.equals(group)) { String name = getName(entry.getKey(), group); --- 315,346 ---- out.format(Locale.US, numFmt + " total\n", sum); } } } } + } private static final String CSV_FMT = CSVUtil.buildFormatString("%s", "%s", "%s", "%d"); ! private static class ComputerReadableDumper extends Dumper { ! ! ComputerReadableDumper(PrintStream out) { ! super(out); ! } ! ! @Override ! public void start(int size) { ! // do nothing ! } ! ! @Override ! public void close() { ! // do nothing ! } ! ! @Override ! public void dumpCounters(boolean staticCounter, String group, long[] array, Set<Entry<String, Counter>> counterEntrySet, OptionValues options) { String category = staticCounter ? "static counters" : "dynamic counters"; for (Map.Entry<String, Counter> entry : counterEntrySet) { Counter counter = entry.getValue(); if (counter.group.equals(group)) { String name = getName(entry.getKey(), group);
*** 293,305 **** long value = array[index]; CSVUtil.Escape.println(out, CSV_FMT, category, group, name, value); } } } - - private static long percentage(long counter, long sum) { - return (counter * 200 + 1) / sum / 2; } private abstract static class CallbackOutputStream extends OutputStream { protected final PrintStream delegate; --- 348,357 ----
*** 438,451 **** } private static PrintStream getPrintStream(OptionValues options) { if (Options.BenchmarkCountersFile.getValue(options) != null) { try { ! Path path = UniquePathUtilities.getPathGlobal(options, Options.BenchmarkCountersFile, GraalDebugConfig.Options.DumpPath, "csv"); ! TTY.println("Writing benchmark counters to '%s'", path); ! return new PrintStream(path.toFile()); ! } catch (FileNotFoundException e) { TTY.out().println(e.getMessage()); TTY.out().println("Fallback to default"); } } return TTY.out; --- 490,504 ---- } private static PrintStream getPrintStream(OptionValues options) { if (Options.BenchmarkCountersFile.getValue(options) != null) { try { ! ! File file = new File(Options.BenchmarkCountersFile.getValue(options)); ! TTY.println("Writing benchmark counters to '%s'", file.getAbsolutePath()); ! return new PrintStream(file); ! } catch (IOException e) { TTY.out().println(e.getMessage()); TTY.out().println("Fallback to default"); } } return TTY.out;
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File