1 package build.tools.jfr; 2 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; 17 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; 23 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; 28 29 public class GenerateJfrFiles { 30 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]); 42 43 Metadata metadata = new Metadata(metadataXml, metadataSchema); 44 metadata.verify(); 45 metadata.wireUpTypes(); 46 47 printJfrPeriodicHpp(metadata, outputDirectory); 48 printJfrEventIdsHpp(metadata, outputDirectory); 49 printJfrEventControlHpp(metadata, outputDirectory); 50 printJfrTypesHpp(metadata, outputDirectory); 51 printJfrEventClassesHpp(metadata, outputDirectory); 52 53 } catch (Exception e) { 54 e.printStackTrace(); 55 System.exit(1); 56 } 57 } 58 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 } 67 68 static class TypeElement { 69 List<FieldElement> fields = new ArrayList<>(); 70 String name; 71 String fieldType; 72 String parameterType; 73 boolean supportStruct; 74 } 75 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 } 86 87 List<EventElement> getEvents() { 88 return getList(t -> t.getClass() == EventElement.class); 89 } 90 91 List<TypeElement> getEventsAndStructs() { 92 return getList(t -> t.getClass() == EventElement.class || t.supportStruct); 93 } 94 95 List<TypeElement> getTypesAndStructs() { 96 return getList(t -> t.getClass() == TypeElement.class || t.supportStruct); 97 } 98 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 } 109 110 List<EventElement> getPeriodicEvents() { 111 return getList(t -> t.getClass() == EventElement.class && ((EventElement) t).periodic); 112 } 113 114 List<TypeElement> getNonEventsAndNonStructs() { 115 return getList(t -> t.getClass() != EventElement.class && !t.supportStruct); 116 } 117 118 List<TypeElement> getTypes() { 119 return getList(t -> t.getClass() == TypeElement.class && !t.supportStruct); 120 } 121 122 List<TypeElement> getStructs() { 123 return getList(t -> t.getClass() == TypeElement.class && t.supportStruct); 124 } 125 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 } 137 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 } 150 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 } 159 160 static class FieldElement { 161 final Metadata metadata; 162 TypeElement type; 163 String name; 164 String typeName; 165 boolean struct; 166 167 FieldElement(Metadata metadata) { 168 this.metadata = metadata; 169 } 170 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 } 181 182 String getParameterName() { 183 return struct ? "value" : "new_value"; 184 } 185 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 } 197 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 } 240 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 } 245 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 } 261 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 } 269 270 void write(String text) { 271 out.print(text); 272 out.print("\n"); // Don't use Windows line endings 273 } 274 275 @Override 276 public void close() throws Exception { 277 out.close(); 278 } 279 } 280 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 } 319 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 } 359 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 } 404 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 } 450 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 } 498 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 } 518 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 } 537 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 } 547 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 } 565 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 } 600 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 } 613 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 } 617 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 } 629 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 } 670 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 } 692 693 private static void printField(Printer out, FieldElement field) { 694 out.write(" " + field.getFieldType() + " _" + field.name + ";"); 695 } 696 }