comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java @ 10082:665e95c28965

DynamicCounterNode: counter without lowering, output tweaks
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 18 Jun 2013 16:39:17 +0200
parents 19c5a07c7843
children b05e1ff3aac0
comparison
equal deleted inserted replaced
10081:20fd8760cb34 10082:665e95c28965
23 package com.oracle.graal.nodes.debug; 23 package com.oracle.graal.nodes.debug;
24 24
25 import java.io.*; 25 import java.io.*;
26 import java.util.*; 26 import java.util.*;
27 27
28 import sun.misc.*;
29
28 import com.oracle.graal.api.meta.*; 30 import com.oracle.graal.api.meta.*;
29 import com.oracle.graal.graph.*; 31 import com.oracle.graal.graph.*;
30 import com.oracle.graal.nodes.*; 32 import com.oracle.graal.nodes.*;
33 import com.oracle.graal.nodes.HeapAccess.WriteBarrierType;
31 import com.oracle.graal.nodes.calc.*; 34 import com.oracle.graal.nodes.calc.*;
35 import com.oracle.graal.nodes.extended.*;
32 import com.oracle.graal.nodes.java.*; 36 import com.oracle.graal.nodes.java.*;
33 import com.oracle.graal.nodes.spi.*; 37 import com.oracle.graal.nodes.spi.*;
34 import com.oracle.graal.nodes.type.*; 38 import com.oracle.graal.nodes.type.*;
35 39
36 /** 40 /**
42 * A unique counter will be created for each unique String passed to the constructor. 46 * A unique counter will be created for each unique String passed to the constructor.
43 */ 47 */
44 public class DynamicCounterNode extends FixedWithNextNode implements Lowerable { 48 public class DynamicCounterNode extends FixedWithNextNode implements Lowerable {
45 49
46 private static final int MAX_COUNTERS = 10 * 1024; 50 private static final int MAX_COUNTERS = 10 * 1024;
47 private static final long[] COUNTERS = new long[MAX_COUNTERS]; 51 public static final long[] COUNTERS = new long[MAX_COUNTERS];
48 private static final long[] STATIC_COUNTERS = new long[MAX_COUNTERS]; 52 private static final long[] STATIC_COUNTERS = new long[MAX_COUNTERS];
49 private static final String[] GROUPS = new String[MAX_COUNTERS]; 53 private static final String[] GROUPS = new String[MAX_COUNTERS];
50 private static final HashMap<String, Integer> INDEXES = new HashMap<>(); 54 private static final HashMap<String, Integer> INDEXES = new HashMap<>();
51 public static String excludedClassPrefix = null; 55 public static String excludedClassPrefix = null;
52 public static boolean enabled = false; 56 public static boolean enabled = false;
93 } 97 }
94 } 98 }
95 99
96 public static synchronized void dump(PrintStream out, double seconds) { 100 public static synchronized void dump(PrintStream out, double seconds) {
97 for (String group : new HashSet<>(Arrays.asList(GROUPS))) { 101 for (String group : new HashSet<>(Arrays.asList(GROUPS))) {
98 dumpCounters(out, seconds, true, group); 102 if (group != null) {
99 dumpCounters(out, seconds, false, group); 103 dumpCounters(out, seconds, true, group);
104 dumpCounters(out, seconds, false, group);
105 }
100 } 106 }
101 out.println("============================"); 107 out.println("============================");
102 108
103 clear(); 109 clear();
104 } 110 }
114 sum += array[index]; 120 sum += array[index];
115 sorted.put(array[index] * MAX_COUNTERS + index, entry.getKey()); 121 sorted.put(array[index] * MAX_COUNTERS + index, entry.getKey());
116 } 122 }
117 } 123 }
118 124
119 long cutoff = sum / 1000; 125 if (sum > 0) {
120 long sum2 = 0; 126 long cutoff = sum / 1000;
121 if (staticCounter) { 127 long sum2 = 0;
122 out.println("=========== " + group + " static counters: "); 128 if (staticCounter) {
123 for (Map.Entry<Long, String> entry : sorted.entrySet()) { 129 out.println("=========== " + group + " static counters: ");
124 long counter = entry.getKey() / MAX_COUNTERS; 130 for (Map.Entry<Long, String> entry : sorted.entrySet()) {
125 sum2 += counter; 131 long counter = entry.getKey() / MAX_COUNTERS;
126 if (sum2 >= cutoff) { 132 sum2 += counter;
127 out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); 133 if (sum2 >= cutoff) {
134 out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
135 }
128 } 136 }
129 } 137 out.println(sum + ": total");
130 out.println(sum + ": total"); 138 } else {
131 } else { 139 if (group.startsWith("~")) {
132 out.println("=========== " + group + " dynamic counters, time = " + seconds + " s"); 140 out.println("=========== " + group + " dynamic counters");
133 for (Map.Entry<Long, String> entry : sorted.entrySet()) { 141 for (Map.Entry<Long, String> entry : sorted.entrySet()) {
134 long counter = entry.getKey() / MAX_COUNTERS; 142 long counter = entry.getKey() / MAX_COUNTERS;
135 sum2 += counter; 143 sum2 += counter;
136 if (sum2 >= cutoff) { 144 if (sum2 >= cutoff) {
137 out.println((int) (counter / seconds) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); 145 out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
146 }
147 }
148 out.println(sum + "/s: total");
149 } else {
150 out.println("=========== " + group + " dynamic counters, time = " + seconds + " s");
151 for (Map.Entry<Long, String> entry : sorted.entrySet()) {
152 long counter = entry.getKey() / MAX_COUNTERS;
153 sum2 += counter;
154 if (sum2 >= cutoff) {
155 out.println((long) (counter / seconds) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
156 }
157 }
158 out.println((long) (sum / seconds) + "/s: total");
138 } 159 }
139 } 160 }
140 out.println((int) (sum / seconds) + "/s: total");
141 } 161 }
142 } 162 }
143 163
144 public static void clear() { 164 public static void clear() {
145 Arrays.fill(COUNTERS, 0); 165 Arrays.fill(COUNTERS, 0);
165 graph().addBeforeFixed(this, store); 185 graph().addBeforeFixed(this, store);
166 } 186 }
167 graph().removeFixed(this); 187 graph().removeFixed(this);
168 } 188 }
169 189
190 public static void addLowLevel(String group, String name, long increment, boolean addContext, FixedNode position, MetaAccessProvider runtime) {
191 if (!enabled) {
192 throw new GraalInternalError("counter nodes shouldn't exist when not enabled");
193 }
194 StructuredGraph graph = position.graph();
195 if (excludedClassPrefix == null || !graph.method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) {
196 int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", graph.method())) : getIndex(name);
197 STATIC_COUNTERS[index] += increment;
198 GROUPS[index] = group;
199
200 ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, runtime, graph);
201 ConstantLocationNode location = ConstantLocationNode.create(NamedLocationIdentity.getArrayLocation(Kind.Long), Kind.Long, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE *
202 index, graph);
203 ReadNode read = graph.add(new ReadNode(arrayConstant, location, StampFactory.forKind(Kind.Long), WriteBarrierType.NONE, false));
204 IntegerAddNode add = graph.add(new IntegerAddNode(Kind.Long, read, ConstantNode.forLong(increment, graph)));
205 WriteNode write = graph.add(new WriteNode(arrayConstant, add, location, WriteBarrierType.NONE, false));
206
207 graph.addBeforeFixed(position, read);
208 graph.addBeforeFixed(position, write);
209 }
210 }
211
170 public static void addCounterBefore(String group, String name, long increment, boolean addContext, FixedNode position) { 212 public static void addCounterBefore(String group, String name, long increment, boolean addContext, FixedNode position) {
171 if (enabled) { 213 if (enabled) {
172 StructuredGraph graph = position.graph(); 214 StructuredGraph graph = position.graph();
173 DynamicCounterNode counter = graph.add(new DynamicCounterNode(name, group, increment, addContext)); 215 DynamicCounterNode counter = graph.add(new DynamicCounterNode(name, group, increment, addContext));
174 graph.addBeforeFixed(position, counter); 216 graph.addBeforeFixed(position, counter);