src/share/vm/jfr/GenerateJfrFiles.java

Mon, 12 Aug 2019 18:30:40 +0300

author
apetushkov
date
Mon, 12 Aug 2019 18:30:40 +0300
changeset 9858
b985cbb00e68
child 9869
a5e7fde5ba80
permissions
-rw-r--r--

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 }

mercurial