# HG changeset patch # User Lukas Stadler # Date 1395664299 -3600 # Node ID c3ec1e4494b8d41ce6dea907e256281bc9c324da # Parent 4c5ed5a670ed3c247855a8510442125c4d2edffd update BenchmarkCounters (add TimedDynamicCounters, fix -XX:+GraalCountersExcludeCompiler) diff -r 4c5ed5a670ed -r c3ec1e4494b8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java Mon Mar 24 13:31:39 2014 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, 2014, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler; + +import com.oracle.graal.compiler.CompilerThreadFactory.*; +import com.oracle.graal.debug.*; + +/** + * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the + * context of a thread-local {@linkplain GraalDebugConfig debug configuration}. + */ +public class CompilerThread extends Thread { + + private final DebugConfigAccess debugConfigAccess; + + public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { + super(r); + this.setName(namePrefix + "-" + this.getId()); + this.setPriority(Thread.MAX_PRIORITY); + this.setDaemon(true); + this.debugConfigAccess = debugConfigAccess; + } + + @Override + public void run() { + GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); + try { + super.run(); + } finally { + if (debugConfig != null) { + for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { + try { + dumpHandler.close(); + } catch (Throwable t) { + } + } + } + } + } +} diff -r 4c5ed5a670ed -r c3ec1e4494b8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java Mon Mar 24 14:41:28 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java Mon Mar 24 13:31:39 2014 +0100 @@ -53,38 +53,4 @@ public Thread newThread(Runnable r) { return new CompilerThread(r, threadNamePrefix, debugConfigAccess); } - - /** - * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in - * the context of a thread-local {@linkplain GraalDebugConfig debug configuration}. - */ - public static class CompilerThread extends Thread { - - private final DebugConfigAccess debugConfigAccess; - - public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { - super(r); - this.setName(namePrefix + "-" + this.getId()); - this.setPriority(Thread.MAX_PRIORITY); - this.setDaemon(true); - this.debugConfigAccess = debugConfigAccess; - } - - @Override - public void run() { - GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); - try { - super.run(); - } finally { - if (debugConfig != null) { - for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { - try { - dumpHandler.close(); - } catch (Throwable t) { - } - } - } - } - } - } } diff -r 4c5ed5a670ed -r c3ec1e4494b8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Mar 24 14:41:28 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Mar 24 13:31:39 2014 +0100 @@ -39,7 +39,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread; +import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; diff -r 4c5ed5a670ed -r c3ec1e4494b8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Mar 24 14:41:28 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Mar 24 13:31:39 2014 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread; import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; diff -r 4c5ed5a670ed -r c3ec1e4494b8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Mon Mar 24 14:41:28 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Mon Mar 24 13:31:39 2014 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.debug; import java.io.*; -import java.text.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -36,8 +35,8 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; @@ -83,6 +82,8 @@ //@formatter:off @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown") private static final OptionValue GenericDynamicCounters = new OptionValue<>(false); + @Option(help = "Turn on the benchmark counters, and displays the results every n milliseconds") + private static final OptionValue TimedDynamicCounters = new OptionValue<>(-1); @Option(help = "Turn on the benchmark counters, and listen for specific patterns on System.out/System.err:%n" + "Format: (err|out),start pattern,end pattern (~ matches multiple digits)%n" + @@ -109,7 +110,8 @@ } String name = counter.getName(); String group = counter.getGroup(); - name = counter.isWithContext() ? name + " @ " + counter.graph().graphId() + ":" + MetaUtil.format("%h.%n", counter.graph().method()) + "#" + group : name + "#" + group; + name = counter.isWithContext() && counter.graph().method() != null ? name + " @ " + counter.graph().graphId() + ":" + MetaUtil.format("%h.%n", counter.graph().method()) + "#" + group : name + + "#" + group; Integer index = indexes.get(name); if (index == null) { synchronized (BenchmarkCounters.class) { @@ -129,15 +131,15 @@ return index; } - public static synchronized void dump(PrintStream out, double seconds, long[] counters) { + public static synchronized void dump(PrintStream out, double seconds, long[] counters, int maxRows) { if (!groups.isEmpty()) { out.println("====== dynamic counters (" + staticCounters.size() + " in total) ======"); for (String group : new TreeSet<>(groups)) { if (group != null) { if (DUMP_STATIC) { - dumpCounters(out, seconds, counters, true, group); + dumpCounters(out, seconds, counters, true, group, maxRows); } - dumpCounters(out, seconds, counters, false, group); + dumpCounters(out, seconds, counters, false, group, maxRows); } } out.println("============================"); @@ -150,9 +152,10 @@ delta = counters; } - private static synchronized void dumpCounters(PrintStream out, double seconds, long[] counters, boolean staticCounter, String group) { + private static synchronized void dumpCounters(PrintStream out, double seconds, long[] counters, boolean staticCounter, String group, int maxRows) { TreeMap sorted = new TreeMap<>(); + // collect the numbers long[] array; if (staticCounter) { array = new long[indexes.size()]; @@ -165,6 +168,7 @@ array[i] -= delta[i]; } } + // sort the counters by putting them into a sorted map long sum = 0; for (Map.Entry entry : indexes.entrySet()) { int index = entry.getValue(); @@ -175,41 +179,51 @@ } if (sum > 0) { - NumberFormat format = NumberFormat.getInstance(Locale.US); long cutoff = sorted.size() < 10 ? 1 : Math.max(1, sum / 100); + int cnt = sorted.size(); + + // remove everything below cutoff and keep at most maxRows + Iterator> iter = sorted.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + long counter = entry.getKey() / array.length; + if (counter < cutoff || cnt > maxRows) { + iter.remove(); + } + cnt--; + } + if (staticCounter) { out.println("=========== " + group + " (static counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } + out.format(Locale.US, "%,19d %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); } - out.println(sum + ": total"); + out.format(Locale.US, "%,19d total\n", sum); } else { if (group.startsWith("~")) { out.println("=========== " + group + " (dynamic counters), time = " + seconds + " s:"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format((long) (counter / seconds)) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } + out.format(Locale.US, "%,19d/s %3d%% %s\n", (long) (counter / seconds), percentage(counter, sum), entry.getValue()); } - out.println(format.format((long) (sum / seconds)) + "/s: total"); + out.format(Locale.US, "%,19d/s total\n", (long) (sum / seconds)); } else { out.println("=========== " + group + " (dynamic counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } + out.format(Locale.US, "%,19d %3d%% %s\n", counter, percentage(counter, sum), entry.getValue()); } - out.println(format.format(sum) + ": total"); + out.format(Locale.US, "%,19d total\n", sum); } } } } + private static long percentage(long counter, long sum) { + return (counter * 200 + 1) / sum / 2; + } + public abstract static class CallbackOutputStream extends OutputStream { protected final PrintStream delegate; @@ -282,7 +296,7 @@ case 2: if (waitingForEnd) { waitingForEnd = false; - BenchmarkCounters.dump(delegate, (System.nanoTime() - startTime) / 1000000000d, compilerToVM.collectCounters()); + BenchmarkCounters.dump(delegate, (System.nanoTime() - startTime) / 1000000000d, compilerToVM.collectCounters(), 100); } break; } @@ -309,20 +323,43 @@ if (Options.GenericDynamicCounters.getValue()) { enabled = true; } - if (Options.GenericDynamicCounters.getValue() || Options.BenchmarkDynamicCounters.getValue() != null) { + if (Options.TimedDynamicCounters.getValue() > 0) { + Thread thread = new Thread() { + long lastTime = System.nanoTime(); + PrintStream out = System.out; + + @Override + public void run() { + while (true) { + try { + Thread.sleep(Options.TimedDynamicCounters.getValue()); + } catch (InterruptedException e) { + } + long time = System.nanoTime(); + dump(out, (time - lastTime) / 1000000000d, compilerToVM.collectCounters(), 10); + lastTime = time; + } + } + }; + thread.setDaemon(true); + thread.setPriority(Thread.MAX_PRIORITY); + thread.start(); + enabled = true; + } + if (enabled) { clear(compilerToVM.collectCounters()); } } public static void shutdown(CompilerToVM compilerToVM, long compilerStartTime) { if (Options.GenericDynamicCounters.getValue()) { - dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters()); + dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters(), 100); } } public static void lower(DynamicCounterNode counter, HotSpotRegistersProvider registers, HotSpotVMConfig config, Kind wordKind) { StructuredGraph graph = counter.graph(); - if (excludedClassPrefix == null || !counter.graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) { + if (excludedClassPrefix == null || (counter.graph().method() != null && !counter.graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix))) { ReadRegisterNode thread = graph.add(new ReadRegisterNode(registers.getThreadRegister(), wordKind, true, false)); diff -r 4c5ed5a670ed -r c3ec1e4494b8 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Mar 24 14:41:28 2014 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Mar 24 13:31:39 2014 +0100 @@ -184,6 +184,7 @@ do_klass(Long_klass, java_lang_Long, Pre ) \ \ /* Support for Graal */ \ + do_klass(CompilerThread_klass, com_oracle_graal_compiler_CompilerThread, Opt) \ do_klass(BitSet_klass, java_util_BitSet, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ @@ -203,7 +204,6 @@ do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Opt) \ do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Opt) \ do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Opt) \ - do_klass(CompilerThread_klass, com_oracle_graal_hotspot_CompilerThread, Opt) \ /* graal.api.code */ \ do_klass(Assumptions_klass, com_oracle_graal_api_code_Assumptions, Opt) \ do_klass(Assumptions_ConcreteMethod_klass, com_oracle_graal_api_code_Assumptions_ConcreteMethod, Opt) \ diff -r 4c5ed5a670ed -r c3ec1e4494b8 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Mar 24 14:41:28 2014 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Mar 24 13:31:39 2014 +0100 @@ -288,10 +288,11 @@ NOT_LP64( do_alias(intptr_signature, int_signature) ) \ LP64_ONLY( do_alias(intptr_signature, long_signature) ) \ template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \ - \ - /* Support for Graal */ \ - template(java_util_BitSet, "java/util/BitSet") \ - /* graal.hotspot */ \ + \ + /* Support for Graal */ \ + template(com_oracle_graal_compiler_CompilerThread, "com/oracle/graal/compiler/CompilerThread") \ + template(java_util_BitSet, "java/util/BitSet") \ + /* graal.hotspot */ \ template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime") \ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ @@ -314,7 +315,6 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ - template(com_oracle_graal_hotspot_CompilerThread, "com/oracle/graal/hotspot/CompilerThread") \ /* graal.api.meta */ \ template(com_oracle_graal_api_meta_Constant, "com/oracle/graal/api/meta/Constant") \ template(com_oracle_graal_api_meta_ConstantPool, "com/oracle/graal/api/meta/ConstantPool") \