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