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

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

mercurial