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.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(""); 455 out.write("#include \"oops/klass.hpp\""); 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(" using JfrEvent::commit; // else commit() is hidden by overloaded versions in this class"); 535 printCommitMethod(out, event, true); 536 out.write("};"); 537 } 538 539 private static void printEmptyType(Printer out, TypeElement t) { 540 out.write("struct JfrStruct" + t.name); 541 out.write("{"); 542 out.write(" public:"); 543 for (FieldElement f : t.fields) { 544 out.write(" void set_" + f.name + "(" + f.getParameterType() + ") { }"); 545 } 546 out.write("};"); 547 } 548 549 private static void printType(Printer out, TypeElement t) { 550 out.write("struct JfrStruct" + t.name); 551 out.write("{"); 552 out.write(" private:"); 553 for (FieldElement f : t.fields) { 554 printField(out, f); 555 } 556 out.write(""); 557 out.write(" public:"); 558 for (FieldElement f : t.fields) { 559 printTypeSetter(out, f); 560 } 561 out.write(""); 562 printWriteData(out, t.fields); 563 out.write("};"); 564 out.write(""); 565 } 566 567 private static void printEvent(Printer out, EventElement event) { 568 out.write("class Event" + event.name + " : public JfrEvent<Event" + event.name + ">"); 569 out.write("{"); 570 out.write(" private:"); 571 for (FieldElement f : event.fields) { 572 printField(out, f); 573 } 574 out.write(""); 575 out.write(" public:"); 576 out.write(" static const bool hasThread = " + event.thread + ";"); 577 out.write(" static const bool hasStackTrace = " + event.stackTrace + ";"); 578 out.write(" static const bool isInstant = " + !event.startTime + ";"); 579 out.write(" static const bool hasCutoff = " + event.cutoff + ";"); 580 out.write(" static const bool isRequestable = " + event.periodic + ";"); 581 out.write(" static const JfrEventId eventId = Jfr" + event.name + "Event;"); 582 out.write(""); 583 out.write(" Event" + event.name + "(EventStartTime timing=TIMED) : JfrEvent<Event" + event.name + ">(timing) {}"); 584 out.write(""); 585 int index = 0; 586 for (FieldElement f : event.fields) { 587 out.write(" void set_" + f.name + "(" + f.getParameterType() + " " + f.getParameterName() + ") {"); 588 out.write(" this->_" + f.name + " = " + f.getParameterName() + ";"); 589 out.write(" DEBUG_ONLY(set_field_bit(" + index++ + "));"); 590 out.write(" }"); 591 } 592 out.write(""); 593 printWriteData(out, event.fields); 594 out.write(""); 595 out.write(" using JfrEvent<Event" + event.name + ">::commit; // else commit() is hidden by overloaded versions in this class"); 596 printConstructor2(out, event); 597 printCommitMethod(out, event, false); 598 printVerify(out, event.fields); 599 out.write("};"); 600 } 601 602 private static void printWriteData(Printer out, List<FieldElement> fields) { 603 out.write(" template <typename Writer>"); 604 out.write(" void writeData(Writer& w) {"); 605 for (FieldElement field : fields) { 606 if (field.struct) { 607 out.write(" _" + field.name + ".writeData(w);"); 608 } else { 609 out.write(" w.write(_" + field.name + ");"); 610 } 611 } 612 out.write(" }"); 613 } 614 615 private static void printTypeSetter(Printer out, FieldElement field) { 616 out.write(" void set_" + field.name + "(" + field.getParameterType() + " new_value) { this->_" + field.name + " = new_value; }"); 617 } 618 619 private static void printVerify(Printer out, List<FieldElement> fields) { 620 out.write(""); 621 out.write("#ifdef ASSERT"); 622 out.write(" void verify() const {"); 623 int index = 0; 624 for (FieldElement f : fields) { 625 out.write(" assert(verify_field_bit(" + index++ + "), \"Attempting to write an uninitialized event field: %s\", \"_" + f.name + "\");"); 626 } 627 out.write(" }"); 628 out.write("#endif"); 629 } 630 631 private static void printCommitMethod(Printer out, EventElement event, boolean emptyBody) { 632 if (event.startTime) { 633 StringJoiner sj = new StringJoiner(",\n "); 634 for (FieldElement f : event.fields) { 635 sj.add(f.getParameterType() + " " + f.name); 636 } 637 out.write(""); 638 out.write(" void commit(" + sj.toString() + ") {"); 639 if (!emptyBody) { 640 out.write(" if (should_commit()) {"); 641 for (FieldElement f : event.fields) { 642 out.write(" set_" + f.name + "(" + f.name + ");"); 643 } 644 out.write(" commit();"); 645 out.write(" }"); 646 } 647 out.write(" }"); 648 } 649 out.write(""); 650 StringJoiner sj = new StringJoiner(",\n "); 651 if (event.startTime) { 652 sj.add("const Ticks& startTicks"); 653 sj.add("const Ticks& endTicks"); 654 } 655 for (FieldElement f : event.fields) { 656 sj.add(f.getParameterType() + " " + f.name); 657 } 658 out.write(" static void commit(" + sj.toString() + ") {"); 659 if (!emptyBody) { 660 out.write(" Event" + event.name + " me(UNTIMED);"); 661 out.write(""); 662 out.write(" if (me.should_commit()) {"); 663 if (event.startTime) { 664 out.write(" me.set_starttime(startTicks);"); 665 out.write(" me.set_endtime(endTicks);"); 666 } 667 for (FieldElement f : event.fields) { 668 out.write(" me.set_" + f.name + "(" + f.name + ");"); 669 } 670 out.write(" me.commit();"); 671 out.write(" }"); 672 } 673 out.write(" }"); 674 } 675 676 private static void printConstructor2(Printer out, EventElement event) { 677 if (!event.startTime) { 678 out.write(""); 679 out.write(""); 680 } 681 if (event.startTime) { 682 out.write(""); 683 out.write(" Event" + event.name + "("); 684 StringJoiner sj = new StringJoiner(",\n "); 685 for (FieldElement f : event.fields) { 686 sj.add(f.getParameterType() + " " + f.name); 687 } 688 out.write(" " + sj.toString() + ") : JfrEvent<Event" + event.name + ">(TIMED) {"); 689 out.write(" if (should_commit()) {"); 690 for (FieldElement f : event.fields) { 691 out.write(" set_" + f.name + "(" + f.name + ");"); 692 } 693 out.write(" }"); 694 out.write(" }"); 695 } 696 } 697 698 private static void printField(Printer out, FieldElement field) { 699 out.write(" " + field.getFieldType() + " _" + field.name + ";"); 700 } 701 }