author | ihse |
Fri, 25 May 2018 10:14:27 +0200 | |
changeset 50266 | 8090a68b6af5 |
parent 50124 | src/hotspot/share/jfr/metadata/GenerateJfrFiles.java@781f36c0831e |
child 51968 | 5bdf60cd0ed0 |
permissions | -rw-r--r-- |
50266 | 1 |
package build.tools.jfr; |
2 |
||
50113 | 3 |
import java.io.BufferedOutputStream; |
4 |
import java.io.File; |
|
5 |
import java.io.FileNotFoundException; |
|
6 |
import java.io.FileOutputStream; |
|
7 |
import java.io.IOException; |
|
8 |
import java.io.PrintStream; |
|
9 |
import java.util.ArrayList; |
|
10 |
import java.util.HashMap; |
|
11 |
import java.util.LinkedHashMap; |
|
12 |
import java.util.List; |
|
13 |
import java.util.Map; |
|
14 |
import java.util.StringJoiner; |
|
15 |
import java.util.function.Predicate; |
|
16 |
||
17 |
import javax.xml.XMLConstants; |
|
18 |
import javax.xml.parsers.ParserConfigurationException; |
|
19 |
import javax.xml.parsers.SAXParser; |
|
20 |
import javax.xml.parsers.SAXParserFactory; |
|
21 |
import javax.xml.validation.SchemaFactory; |
|
22 |
||
23 |
import org.xml.sax.Attributes; |
|
24 |
import org.xml.sax.SAXException; |
|
25 |
import org.xml.sax.SAXParseException; |
|
26 |
import org.xml.sax.helpers.DefaultHandler; |
|
27 |
||
28 |
public class GenerateJfrFiles { |
|
29 |
||
30 |
public static void main(String... args) throws Exception { |
|
31 |
if (args.length != 3) { |
|
32 |
System.err.println("Incorrect number of command line arguments."); |
|
33 |
System.err.println("Usage:"); |
|
34 |
System.err.println("java GenerateJfrFiles[.java] <path-to-metadata.xml> <path-to-metadata.xsd> <output-directory>"); |
|
35 |
System.exit(1); |
|
36 |
} |
|
37 |
try { |
|
38 |
File metadataXml = new File(args[0]); |
|
39 |
File metadataSchema = new File(args[1]); |
|
40 |
File outputDirectory = new File(args[2]); |
|
41 |
||
42 |
Metadata metadata = new Metadata(metadataXml, metadataSchema); |
|
43 |
metadata.verify(); |
|
44 |
metadata.wireUpTypes(); |
|
45 |
||
46 |
printJfrPeriodicHpp(metadata, outputDirectory); |
|
47 |
printJfrEventIdsHpp(metadata, outputDirectory); |
|
48 |
printJfrEventControlHpp(metadata, outputDirectory); |
|
49 |
printJfrTypesHpp(metadata, outputDirectory); |
|
50 |
printJfrEventClassesHpp(metadata, outputDirectory); |
|
51 |
||
52 |
} catch (Exception e) { |
|
53 |
e.printStackTrace(); |
|
54 |
System.exit(1); |
|
55 |
} |
|
56 |
} |
|
57 |
||
58 |
static class XmlType { |
|
59 |
final String fieldType; |
|
60 |
final String parameterType; |
|
61 |
XmlType(String fieldType, String parameterType) { |
|
62 |
this.fieldType = fieldType; |
|
63 |
this.parameterType = parameterType; |
|
64 |
} |
|
65 |
} |
|
66 |
||
67 |
static class TypeElement { |
|
68 |
List<FieldElement> fields = new ArrayList<>(); |
|
69 |
String name; |
|
70 |
String fieldType; |
|
71 |
String parameterType; |
|
72 |
boolean supportStruct; |
|
73 |
} |
|
74 |
||
75 |
static class Metadata { |
|
76 |
final Map<String, TypeElement> types = new LinkedHashMap<>(); |
|
77 |
final Map<String, XmlType> xmlTypes = new HashMap<>(); |
|
78 |
Metadata(File metadataXml, File metadataSchema) throws ParserConfigurationException, SAXException, FileNotFoundException, IOException { |
|
79 |
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); |
|
80 |
SAXParserFactory factory = SAXParserFactory.newInstance(); |
|
81 |
factory.setSchema(schemaFactory.newSchema(metadataSchema)); |
|
82 |
SAXParser sp = factory.newSAXParser(); |
|
83 |
sp.parse(metadataXml, new MetadataHandler(this)); |
|
84 |
} |
|
85 |
||
86 |
List<EventElement> getEvents() { |
|
87 |
return getList(t -> t.getClass() == EventElement.class); |
|
88 |
} |
|
89 |
||
90 |
List<TypeElement> getEventsAndStructs() { |
|
91 |
return getList(t -> t.getClass() == EventElement.class || t.supportStruct); |
|
92 |
} |
|
93 |
||
94 |
List<TypeElement> getTypesAndStructs() { |
|
95 |
return getList(t -> t.getClass() == TypeElement.class || t.supportStruct); |
|
96 |
} |
|
97 |
||
98 |
@SuppressWarnings("unchecked") |
|
99 |
<T> List<T> getList(Predicate<? super TypeElement> pred) { |
|
100 |
List<T> result = new ArrayList<>(types.size()); |
|
101 |
for (TypeElement t : types.values()) { |
|
102 |
if (pred.test(t)) { |
|
103 |
result.add((T) t); |
|
104 |
} |
|
105 |
} |
|
106 |
return result; |
|
107 |
} |
|
108 |
||
109 |
List<EventElement> getPeriodicEvents() { |
|
110 |
return getList(t -> t.getClass() == EventElement.class && ((EventElement) t).periodic); |
|
111 |
} |
|
112 |
||
113 |
List<TypeElement> getNonEventsAndNonStructs() { |
|
114 |
return getList(t -> t.getClass() != EventElement.class && !t.supportStruct); |
|
115 |
} |
|
116 |
||
117 |
List<TypeElement> getTypes() { |
|
118 |
return getList(t -> t.getClass() == TypeElement.class && !t.supportStruct); |
|
119 |
} |
|
120 |
||
121 |
List<TypeElement> getStructs() { |
|
122 |
return getList(t -> t.getClass() == TypeElement.class && t.supportStruct); |
|
123 |
} |
|
124 |
||
125 |
void verify() { |
|
126 |
for (TypeElement t : types.values()) { |
|
127 |
for (FieldElement f : t.fields) { |
|
128 |
if (!xmlTypes.containsKey(f.typeName)) { // ignore primitives |
|
129 |
if (!types.containsKey(f.typeName)) { |
|
130 |
throw new IllegalStateException("Could not find definition of type '" + f.typeName + "' used by " + t.name + "#" + f.name); |
|
131 |
} |
|
132 |
} |
|
133 |
} |
|
134 |
} |
|
135 |
} |
|
136 |
||
137 |
void wireUpTypes() { |
|
138 |
for (TypeElement t : types.values()) { |
|
139 |
for (FieldElement f : t.fields) { |
|
140 |
TypeElement type = types.get(f.typeName); |
|
141 |
if (f.struct) { |
|
142 |
type.supportStruct = true; |
|
143 |
} |
|
144 |
f.type = type; |
|
145 |
} |
|
146 |
} |
|
147 |
} |
|
148 |
} |
|
149 |
||
150 |
static class EventElement extends TypeElement { |
|
151 |
String representation; |
|
152 |
boolean thread; |
|
153 |
boolean stackTrace; |
|
154 |
boolean startTime; |
|
155 |
boolean periodic; |
|
156 |
boolean cutoff; |
|
157 |
} |
|
158 |
||
159 |
static class FieldElement { |
|
160 |
final Metadata metadata; |
|
161 |
TypeElement type; |
|
162 |
String name; |
|
163 |
String typeName; |
|
164 |
boolean struct; |
|
165 |
||
166 |
FieldElement(Metadata metadata) { |
|
167 |
this.metadata = metadata; |
|
168 |
} |
|
169 |
||
170 |
String getParameterType() { |
|
171 |
if (struct) { |
|
172 |
return "const JfrStruct" + typeName + "&"; |
|
173 |
} |
|
174 |
XmlType xmlType = metadata.xmlTypes.get(typeName); |
|
175 |
if (xmlType != null) { |
|
176 |
return xmlType.parameterType; |
|
177 |
} |
|
178 |
return type != null ? "u8" : typeName; |
|
179 |
} |
|
180 |
||
181 |
String getParameterName() { |
|
182 |
return struct ? "value" : "new_value"; |
|
183 |
} |
|
184 |
||
185 |
String getFieldType() { |
|
186 |
if (struct) { |
|
187 |
return "JfrStruct" + typeName; |
|
188 |
} |
|
189 |
XmlType xmlType = metadata.xmlTypes.get(typeName); |
|
190 |
if (xmlType != null) { |
|
191 |
return xmlType.fieldType; |
|
192 |
} |
|
193 |
return type != null ? "u8" : typeName; |
|
194 |
} |
|
195 |
} |
|
196 |
||
197 |
static class MetadataHandler extends DefaultHandler { |
|
198 |
final Metadata metadata; |
|
199 |
FieldElement currentField; |
|
200 |
TypeElement currentType; |
|
201 |
MetadataHandler(Metadata metadata) { |
|
202 |
this.metadata = metadata; |
|
203 |
} |
|
204 |
@Override |
|
205 |
public void error(SAXParseException e) throws SAXException { |
|
206 |
throw e; |
|
207 |
} |
|
208 |
@Override |
|
209 |
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { |
|
210 |
switch (qName) { |
|
211 |
case "XmlType": |
|
212 |
String name = attributes.getValue("name"); |
|
213 |
String parameterType = attributes.getValue("parameterType"); |
|
214 |
String fieldType = attributes.getValue("fieldType"); |
|
215 |
metadata.xmlTypes.put(name, new XmlType(fieldType, parameterType)); |
|
216 |
break; |
|
217 |
case "Type": |
|
218 |
currentType = new TypeElement(); |
|
219 |
currentType.name = attributes.getValue("name"); |
|
220 |
break; |
|
221 |
case "Event": |
|
222 |
EventElement eventtType = new EventElement(); |
|
223 |
eventtType.name = attributes.getValue("name"); |
|
224 |
eventtType.thread = getBoolean(attributes, "thread", false); |
|
225 |
eventtType.stackTrace = getBoolean(attributes, "stackTrace", false); |
|
226 |
eventtType.startTime = getBoolean(attributes, "startTime", true); |
|
227 |
eventtType.periodic = attributes.getValue("period") != null; |
|
228 |
eventtType.cutoff = getBoolean(attributes, "cutoff", false); |
|
229 |
currentType = eventtType; |
|
230 |
break; |
|
231 |
case "Field": |
|
232 |
currentField = new FieldElement(metadata); |
|
233 |
currentField.struct = getBoolean(attributes, "struct", false); |
|
234 |
currentField.name = attributes.getValue("name"); |
|
235 |
currentField.typeName = attributes.getValue("type"); |
|
236 |
break; |
|
237 |
} |
|
238 |
} |
|
239 |
||
240 |
private boolean getBoolean(Attributes attributes, String name, boolean defaultValue) { |
|
241 |
String value = attributes.getValue(name); |
|
242 |
return value == null ? defaultValue : Boolean.valueOf(value); |
|
243 |
} |
|
244 |
||
245 |
@Override |
|
246 |
public void endElement(String uri, String localName, String qName) { |
|
247 |
switch (qName) { |
|
248 |
case "Type": |
|
249 |
case "Event": |
|
250 |
metadata.types.put(currentType.name, currentType); |
|
251 |
currentType = null; |
|
252 |
break; |
|
253 |
case "Field": |
|
254 |
currentType.fields.add(currentField); |
|
255 |
currentField = null; |
|
256 |
break; |
|
257 |
} |
|
258 |
} |
|
259 |
} |
|
260 |
||
261 |
static class Printer implements AutoCloseable { |
|
262 |
final PrintStream out; |
|
263 |
Printer(File outputDirectory, String filename) throws FileNotFoundException { |
|
264 |
out = new PrintStream(new BufferedOutputStream(new FileOutputStream(new File(outputDirectory, filename)))); |
|
265 |
write("/* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */"); |
|
266 |
write(""); |
|
267 |
} |
|
268 |
||
269 |
void write(String text) { |
|
270 |
out.print(text); |
|
271 |
out.print("\n"); // Don't use Windows line endings |
|
272 |
} |
|
273 |
||
274 |
@Override |
|
275 |
public void close() throws Exception { |
|
276 |
out.close(); |
|
277 |
} |
|
278 |
} |
|
279 |
||
280 |
private static void printJfrPeriodicHpp(Metadata metadata, File outputDirectory) throws Exception { |
|
281 |
try (Printer out = new Printer(outputDirectory, "jfrPeriodic.hpp")) { |
|
282 |
out.write("#ifndef JFRFILES_JFRPERIODICEVENTSET_HPP"); |
|
283 |
out.write("#define JFRFILES_JFRPERIODICEVENTSET_HPP"); |
|
284 |
out.write(""); |
|
285 |
out.write("#include \"utilities/macros.hpp\""); |
|
286 |
out.write("#if INCLUDE_JFR"); |
|
287 |
out.write("#include \"jfrfiles/jfrEventIds.hpp\""); |
|
288 |
out.write("#include \"memory/allocation.hpp\""); |
|
289 |
out.write(""); |
|
290 |
out.write("class JfrPeriodicEventSet : public AllStatic {"); |
|
291 |
out.write(" public:"); |
|
292 |
out.write(" static void requestEvent(JfrEventId id) {"); |
|
293 |
out.write(" switch(id) {"); |
|
294 |
out.write(" "); |
|
295 |
for (EventElement e : metadata.getPeriodicEvents()) { |
|
296 |
out.write(" case Jfr" + e.name + "Event:"); |
|
297 |
out.write(" request" + e.name + "();"); |
|
298 |
out.write(" break;"); |
|
299 |
out.write(" "); |
|
300 |
} |
|
301 |
out.write(" default:"); |
|
302 |
out.write(" break;"); |
|
303 |
out.write(" }"); |
|
304 |
out.write(" }"); |
|
305 |
out.write(""); |
|
306 |
out.write(" private:"); |
|
307 |
out.write(""); |
|
308 |
for (EventElement e : metadata.getPeriodicEvents()) { |
|
309 |
out.write(" static void request" + e.name + "(void);"); |
|
310 |
out.write(""); |
|
311 |
} |
|
312 |
out.write("};"); |
|
313 |
out.write(""); |
|
314 |
out.write("#endif // INCLUDE_JFR"); |
|
315 |
out.write("#endif // JFRFILES_JFRPERIODICEVENTSET_HPP"); |
|
316 |
} |
|
317 |
} |
|
318 |
||
319 |
private static void printJfrEventControlHpp(Metadata metadata, File outputDirectory) throws Exception { |
|
320 |
try (Printer out = new Printer(outputDirectory, "jfrEventControl.hpp")) { |
|
321 |
out.write("#ifndef JFRFILES_JFR_NATIVE_EVENTSETTING_HPP"); |
|
322 |
out.write("#define JFRFILES_JFR_NATIVE_EVENTSETTING_HPP"); |
|
323 |
out.write(""); |
|
324 |
out.write("#include \"utilities/macros.hpp\""); |
|
325 |
out.write("#if INCLUDE_JFR"); |
|
326 |
out.write("#include \"jfrfiles/jfrEventIds.hpp\""); |
|
327 |
out.write(""); |
|
328 |
out.write("/**"); |
|
329 |
out.write(" * Event setting. We add some padding so we can use our"); |
|
330 |
out.write(" * event IDs as indexes into this."); |
|
331 |
out.write(" */"); |
|
332 |
out.write(""); |
|
333 |
out.write("struct jfrNativeEventSetting {"); |
|
334 |
out.write(" jlong threshold_ticks;"); |
|
335 |
out.write(" jlong cutoff_ticks;"); |
|
336 |
out.write(" u1 stacktrace;"); |
|
337 |
out.write(" u1 enabled;"); |
|
338 |
out.write(" u1 pad[6]; // Because GCC on linux ia32 at least tries to pack this."); |
|
339 |
out.write("};"); |
|
340 |
out.write(""); |
|
341 |
out.write("union JfrNativeSettings {"); |
|
342 |
out.write(" // Array version."); |
|
343 |
out.write(" jfrNativeEventSetting bits[MaxJfrEventId];"); |
|
344 |
out.write(" // Then, to make it easy to debug,"); |
|
345 |
out.write(" // add named struct members also."); |
|
346 |
out.write(" struct {"); |
|
347 |
out.write(" jfrNativeEventSetting pad[NUM_RESERVED_EVENTS];"); |
|
348 |
for (TypeElement t : metadata.getEventsAndStructs()) { |
|
349 |
out.write(" jfrNativeEventSetting " + t.name + ";"); |
|
350 |
} |
|
351 |
out.write(" } ev;"); |
|
352 |
out.write("};"); |
|
353 |
out.write(""); |
|
354 |
out.write("#endif // INCLUDE_JFR"); |
|
355 |
out.write("#endif // JFRFILES_JFR_NATIVE_EVENTSETTING_HPP"); |
|
356 |
} |
|
357 |
} |
|
358 |
||
359 |
private static void printJfrEventIdsHpp(Metadata metadata, File outputDirectory) throws Exception { |
|
360 |
try (Printer out = new Printer(outputDirectory, "jfrEventIds.hpp")) { |
|
361 |
out.write("#ifndef JFRFILES_JFREVENTIDS_HPP"); |
|
362 |
out.write("#define JFRFILES_JFREVENTIDS_HPP"); |
|
363 |
out.write(""); |
|
364 |
out.write("#include \"utilities/macros.hpp\""); |
|
365 |
out.write("#if INCLUDE_JFR"); |
|
366 |
out.write("#include \"jfrfiles/jfrTypes.hpp\""); |
|
367 |
out.write(""); |
|
368 |
out.write("/**"); |
|
369 |
out.write(" * Enum of the event types in the JVM"); |
|
370 |
out.write(" */"); |
|
371 |
out.write("enum JfrEventId {"); |
|
372 |
out.write(" _jfreventbase = (NUM_RESERVED_EVENTS-1), // Make sure we start at right index."); |
|
373 |
out.write(" "); |
|
374 |
out.write(" // Events -> enum entry"); |
|
375 |
for (TypeElement t : metadata.getEventsAndStructs()) { |
|
376 |
out.write(" Jfr" + t.name + "Event,"); |
|
377 |
} |
|
378 |
out.write(""); |
|
379 |
out.write(" MaxJfrEventId"); |
|
380 |
out.write("};"); |
|
381 |
out.write(""); |
|
382 |
out.write("/**"); |
|
383 |
out.write(" * Struct types in the JVM"); |
|
384 |
out.write(" */"); |
|
385 |
out.write("enum JfrStructId {"); |
|
386 |
for (TypeElement t : metadata.getNonEventsAndNonStructs()) { |
|
387 |
out.write(" Jfr" + t.name + "Struct,"); |
|
388 |
} |
|
389 |
for (TypeElement t : metadata.getEventsAndStructs()) { |
|
390 |
out.write(" Jfr" + t.name + "Struct,"); |
|
391 |
} |
|
392 |
out.write(""); |
|
393 |
out.write(" MaxJfrStructId"); |
|
394 |
out.write("};"); |
|
395 |
out.write(""); |
|
396 |
out.write("typedef enum JfrEventId JfrEventId;"); |
|
397 |
out.write("typedef enum JfrStructId JfrStructId;"); |
|
398 |
out.write(""); |
|
399 |
out.write("#endif // INCLUDE_JFR"); |
|
400 |
out.write("#endif // JFRFILES_JFREVENTIDS_HPP"); |
|
401 |
} |
|
402 |
} |
|
403 |
||
404 |
private static void printJfrTypesHpp(Metadata metadata, File outputDirectory) throws Exception { |
|
405 |
List<String> knownTypes = List.of("Thread", "StackTrace", "Class", "StackFrame"); |
|
406 |
try (Printer out = new Printer(outputDirectory, "jfrTypes.hpp")) { |
|
407 |
out.write("#ifndef JFRFILES_JFRTYPES_HPP"); |
|
408 |
out.write("#define JFRFILES_JFRTYPES_HPP"); |
|
409 |
out.write(""); |
|
410 |
out.write("#include \"utilities/macros.hpp\""); |
|
411 |
out.write("#if INCLUDE_JFR"); |
|
412 |
out.write(""); |
|
413 |
out.write("enum JfrTypeId {"); |
|
414 |
out.write(" TYPE_NONE = 0,"); |
|
415 |
out.write(" TYPE_CLASS = 20,"); |
|
416 |
out.write(" TYPE_STRING = 21,"); |
|
417 |
out.write(" TYPE_THREAD = 22,"); |
|
418 |
out.write(" TYPE_STACKTRACE = 23,"); |
|
419 |
out.write(" TYPE_BYTES = 24,"); |
|
420 |
out.write(" TYPE_EPOCHMILLIS = 25,"); |
|
421 |
out.write(" TYPE_MILLIS = 26,"); |
|
422 |
out.write(" TYPE_NANOS = 27,"); |
|
423 |
out.write(" TYPE_TICKS = 28,"); |
|
424 |
out.write(" TYPE_ADDRESS = 29,"); |
|
425 |
out.write(" TYPE_PERCENTAGE = 30,"); |
|
426 |
out.write(" TYPE_DUMMY,"); |
|
427 |
out.write(" TYPE_DUMMY_1,"); |
|
428 |
for (TypeElement type : metadata.getTypes()) { |
|
429 |
if (!knownTypes.contains(type.name)) { |
|
430 |
out.write(" TYPE_" + type.name.toUpperCase() + ","); |
|
431 |
} |
|
432 |
} |
|
433 |
out.write(""); |
|
434 |
out.write(" NUM_JFR_TYPES,"); |
|
435 |
out.write(" TYPES_END = 255"); |
|
436 |
out.write("};"); |
|
437 |
out.write(""); |
|
438 |
out.write("enum ReservedEvent {"); |
|
439 |
out.write(" EVENT_METADATA,"); |
|
440 |
out.write(" EVENT_CHECKPOINT,"); |
|
441 |
out.write(" EVENT_BUFFERLOST,"); |
|
442 |
out.write(" NUM_RESERVED_EVENTS = TYPES_END"); |
|
443 |
out.write("};"); |
|
444 |
out.write(""); |
|
445 |
out.write("#endif // INCLUDE_JFR"); |
|
446 |
out.write("#endif // JFRFILES_JFRTYPES_HPP"); |
|
447 |
}; |
|
448 |
} |
|
449 |
||
450 |
private static void printJfrEventClassesHpp(Metadata metadata, File outputDirectory) throws Exception { |
|
451 |
try (Printer out = new Printer(outputDirectory, "jfrEventClasses.hpp")) { |
|
452 |
out.write("#ifndef JFRFILES_JFREVENTCLASSES_HPP"); |
|
453 |
out.write("#define JFRFILES_JFREVENTCLASSES_HPP"); |
|
454 |
out.write(""); |
|
50124
781f36c0831e
8203285: Minimal VM fails to build after JDK-8199712 (Flight Recorder)
shade
parents:
50113
diff
changeset
|
455 |
out.write("#include \"oops/klass.hpp\""); |
50113 | 456 |
out.write("#include \"jfrfiles/jfrTypes.hpp\""); |
457 |
out.write("#include \"jfr/utilities/jfrTypes.hpp\""); |
|
458 |
out.write("#include \"utilities/macros.hpp\""); |
|
459 |
out.write("#include \"utilities/ticks.hpp\""); |
|
460 |
out.write("#if INCLUDE_JFR"); |
|
461 |
out.write("#include \"jfr/recorder/service/jfrEvent.hpp\""); |
|
462 |
out.write("/*"); |
|
463 |
out.write(" * Each event class has an assert member function verify() which is invoked"); |
|
464 |
out.write(" * just before the engine writes the event and its fields to the data stream."); |
|
465 |
out.write(" * The purpose of verify() is to ensure that all fields in the event are initialized"); |
|
466 |
out.write(" * and set before attempting to commit."); |
|
467 |
out.write(" *"); |
|
468 |
out.write(" * We enforce this requirement because events are generally stack allocated and therefore"); |
|
469 |
out.write(" * *not* initialized to default values. This prevents us from inadvertently committing"); |
|
470 |
out.write(" * uninitialized values to the data stream."); |
|
471 |
out.write(" *"); |
|
472 |
out.write(" * The assert message contains both the index (zero based) as well as the name of the field."); |
|
473 |
out.write(" */"); |
|
474 |
out.write(""); |
|
475 |
printTypes(out, metadata, false); |
|
476 |
out.write(""); |
|
477 |
out.write(""); |
|
478 |
out.write("#else // !INCLUDE_JFR"); |
|
479 |
out.write(""); |
|
480 |
out.write("class JfrEvent {"); |
|
481 |
out.write(" public:"); |
|
482 |
out.write(" JfrEvent() {}"); |
|
483 |
out.write(" void set_starttime(const Ticks&) const {}"); |
|
484 |
out.write(" void set_endtime(const Ticks&) const {}"); |
|
485 |
out.write(" bool should_commit() const { return false; }"); |
|
486 |
out.write(" static bool is_enabled() { return false; }"); |
|
487 |
out.write(" void commit() {}"); |
|
488 |
out.write("};"); |
|
489 |
out.write(""); |
|
490 |
printTypes(out, metadata, true); |
|
491 |
out.write(""); |
|
492 |
out.write(""); |
|
493 |
out.write("#endif // INCLUDE_JFR"); |
|
494 |
out.write("#endif // JFRFILES_JFREVENTCLASSES_HPP"); |
|
495 |
} |
|
496 |
} |
|
497 |
||
498 |
private static void printTypes(Printer out, Metadata metadata, boolean empty) { |
|
499 |
for (TypeElement t : metadata.getStructs()) { |
|
500 |
if (empty) { |
|
501 |
out.write(""); |
|
502 |
printEmptyType(out, t); |
|
503 |
} else { |
|
504 |
printType(out, t); |
|
505 |
} |
|
506 |
out.write(""); |
|
507 |
} |
|
508 |
for (EventElement e : metadata.getEvents()) { |
|
509 |
if (empty) { |
|
510 |
printEmptyEvent(out, e); |
|
511 |
} else { |
|
512 |
printEvent(out, e); |
|
513 |
} |
|
514 |
out.write(""); |
|
515 |
} |
|
516 |
} |
|
517 |
||
518 |
private static void printEmptyEvent(Printer out, EventElement event) { |
|
519 |
out.write("class Event" + event.name + " : public JfrEvent"); |
|
520 |
out.write("{"); |
|
521 |
out.write(" public:"); |
|
522 |
out.write(" Event" + event.name + "(EventStartTime ignore=TIMED) {}"); |
|
523 |
if (event.startTime) { |
|
524 |
StringJoiner sj = new StringJoiner(",\n "); |
|
525 |
for (FieldElement f : event.fields) { |
|
526 |
sj.add(f.getParameterType()); |
|
527 |
} |
|
528 |
out.write(" Event" + event.name + "("); |
|
529 |
out.write(" " + sj.toString() + ") { }"); |
|
530 |
} |
|
531 |
for (FieldElement f : event.fields) { |
|
532 |
out.write(" void set_" + f.name + "(" + f.getParameterType() + ") { }"); |
|
533 |
} |
|
534 |
out.write("};"); |
|
535 |
} |
|
536 |
||
537 |
private static void printEmptyType(Printer out, TypeElement t) { |
|
538 |
out.write("struct JfrStruct" + t.name); |
|
539 |
out.write("{"); |
|
540 |
out.write(" public:"); |
|
541 |
for (FieldElement f : t.fields) { |
|
542 |
out.write(" void set_" + f.name + "(" + f.getParameterType() + ") { }"); |
|
543 |
} |
|
544 |
out.write("};"); |
|
545 |
} |
|
546 |
||
547 |
private static void printType(Printer out, TypeElement t) { |
|
548 |
out.write("struct JfrStruct" + t.name); |
|
549 |
out.write("{"); |
|
550 |
out.write(" private:"); |
|
551 |
for (FieldElement f : t.fields) { |
|
552 |
printField(out, f); |
|
553 |
} |
|
554 |
out.write(""); |
|
555 |
out.write(" public:"); |
|
556 |
for (FieldElement f : t.fields) { |
|
557 |
printTypeSetter(out, f); |
|
558 |
} |
|
559 |
out.write(""); |
|
560 |
printWriteData(out, t.fields); |
|
561 |
out.write("};"); |
|
562 |
out.write(""); |
|
563 |
} |
|
564 |
||
565 |
private static void printEvent(Printer out, EventElement event) { |
|
566 |
out.write("class Event" + event.name + " : public JfrEvent<Event" + event.name + ">"); |
|
567 |
out.write("{"); |
|
568 |
out.write(" private:"); |
|
569 |
for (FieldElement f : event.fields) { |
|
570 |
printField(out, f); |
|
571 |
} |
|
572 |
out.write(""); |
|
573 |
out.write(" public:"); |
|
574 |
out.write(" static const bool hasThread = " + event.thread + ";"); |
|
575 |
out.write(" static const bool hasStackTrace = " + event.stackTrace + ";"); |
|
576 |
out.write(" static const bool isInstant = " + !event.startTime + ";"); |
|
577 |
out.write(" static const bool hasCutoff = " + event.cutoff + ";"); |
|
578 |
out.write(" static const bool isRequestable = " + event.periodic + ";"); |
|
579 |
out.write(" static const JfrEventId eventId = Jfr" + event.name + "Event;"); |
|
580 |
out.write(""); |
|
581 |
out.write(" Event" + event.name + "(EventStartTime timing=TIMED) : JfrEvent<Event" + event.name + ">(timing) {}"); |
|
582 |
out.write(""); |
|
583 |
int index = 0; |
|
584 |
for (FieldElement f : event.fields) { |
|
585 |
out.write(" void set_" + f.name + "(" + f.getParameterType() + " " + f.getParameterName() + ") {"); |
|
586 |
out.write(" this->_" + f.name + " = " + f.getParameterName() + ";"); |
|
587 |
out.write(" DEBUG_ONLY(set_field_bit(" + index++ + "));"); |
|
588 |
out.write(" }"); |
|
589 |
} |
|
590 |
out.write(""); |
|
591 |
printWriteData(out, event.fields); |
|
592 |
out.write(""); |
|
593 |
out.write(" using JfrEvent<Event" + event.name + ">::commit; // else commit() is hidden by overloaded versions in this class"); |
|
594 |
printConstructor2(out, event); |
|
595 |
printCommitMethod(out, event); |
|
596 |
printVerify(out, event.fields); |
|
597 |
out.write("};"); |
|
598 |
} |
|
599 |
||
600 |
private static void printWriteData(Printer out, List<FieldElement> fields) { |
|
601 |
out.write(" template <typename Writer>"); |
|
602 |
out.write(" void writeData(Writer& w) {"); |
|
603 |
for (FieldElement field : fields) { |
|
604 |
if (field.struct) { |
|
605 |
out.write(" _" + field.name + ".writeData(w);"); |
|
606 |
} else { |
|
607 |
out.write(" w.write(_" + field.name + ");"); |
|
608 |
} |
|
609 |
} |
|
610 |
out.write(" }"); |
|
611 |
} |
|
612 |
||
613 |
private static void printTypeSetter(Printer out, FieldElement field) { |
|
614 |
out.write(" void set_" + field.name + "(" + field.getParameterType() + " new_value) { this->_" + field.name + " = new_value; }"); |
|
615 |
} |
|
616 |
||
617 |
private static void printVerify(Printer out, List<FieldElement> fields) { |
|
618 |
out.write(""); |
|
619 |
out.write("#ifdef ASSERT"); |
|
620 |
out.write(" void verify() const {"); |
|
621 |
int index = 0; |
|
622 |
for (FieldElement f : fields) { |
|
623 |
out.write(" assert(verify_field_bit(" + index++ + "), \"Attempting to write an uninitialized event field: %s\", \"_" + f.name + "\");"); |
|
624 |
} |
|
625 |
out.write(" }"); |
|
626 |
out.write("#endif"); |
|
627 |
} |
|
628 |
||
629 |
private static void printCommitMethod(Printer out, EventElement event) { |
|
630 |
if (event.startTime) { |
|
631 |
StringJoiner sj = new StringJoiner(",\n "); |
|
632 |
for (FieldElement f : event.fields) { |
|
633 |
sj.add(f.getParameterType() + " " + f.name); |
|
634 |
} |
|
635 |
out.write(""); |
|
636 |
out.write(" void commit(" + sj.toString() + ") {"); |
|
637 |
out.write(" if (should_commit()) {"); |
|
638 |
for (FieldElement f : event.fields) { |
|
639 |
out.write(" set_" + f.name + "(" + f.name + ");"); |
|
640 |
} |
|
641 |
out.write(" commit();"); |
|
642 |
out.write(" }"); |
|
643 |
out.write(" }"); |
|
644 |
} |
|
645 |
out.write(""); |
|
646 |
StringJoiner sj = new StringJoiner(",\n "); |
|
647 |
if (event.startTime) { |
|
648 |
sj.add("const Ticks& startTicks"); |
|
649 |
sj.add("const Ticks& endTicks"); |
|
650 |
} |
|
651 |
for (FieldElement f : event.fields) { |
|
652 |
sj.add(f.getParameterType() + " " + f.name); |
|
653 |
} |
|
654 |
out.write(" static void commit(" + sj.toString() + ") {"); |
|
655 |
out.write(" Event" + event.name + " me(UNTIMED);"); |
|
656 |
out.write(""); |
|
657 |
out.write(" if (me.should_commit()) {"); |
|
658 |
if (event.startTime) { |
|
659 |
out.write(" me.set_starttime(startTicks);"); |
|
660 |
out.write(" me.set_endtime(endTicks);"); |
|
661 |
} |
|
662 |
for (FieldElement f : event.fields) { |
|
663 |
out.write(" me.set_" + f.name + "(" + f.name + ");"); |
|
664 |
} |
|
665 |
out.write(" me.commit();"); |
|
666 |
out.write(" }"); |
|
667 |
out.write(" }"); |
|
668 |
} |
|
669 |
||
670 |
private static void printConstructor2(Printer out, EventElement event) { |
|
671 |
if (!event.startTime) { |
|
672 |
out.write(""); |
|
673 |
out.write(""); |
|
674 |
} |
|
675 |
if (event.startTime) { |
|
676 |
out.write(""); |
|
677 |
out.write(" Event" + event.name + "("); |
|
678 |
StringJoiner sj = new StringJoiner(",\n "); |
|
679 |
for (FieldElement f : event.fields) { |
|
680 |
sj.add(f.getParameterType() + " " + f.name); |
|
681 |
} |
|
682 |
out.write(" " + sj.toString() + ") : JfrEvent<Event" + event.name + ">(TIMED) {"); |
|
683 |
out.write(" if (should_commit()) {"); |
|
684 |
for (FieldElement f : event.fields) { |
|
685 |
out.write(" set_" + f.name + "(" + f.name + ");"); |
|
686 |
} |
|
687 |
out.write(" }"); |
|
688 |
out.write(" }"); |
|
689 |
} |
|
690 |
} |
|
691 |
||
692 |
private static void printField(Printer out, FieldElement field) { |
|
693 |
out.write(" " + field.getFieldType() + " _" + field.name + ";"); |
|
694 |
} |
|
50124
781f36c0831e
8203285: Minimal VM fails to build after JDK-8199712 (Flight Recorder)
shade
parents:
50113
diff
changeset
|
695 |
} |