8216303: JFR: Simplify generated files

Reviewed-by: erikj, mgronlun
This commit is contained in:
Erik Gahlin 2020-05-29 15:19:01 +02:00
parent 02fbf44cc7
commit 6fd44901ec
16 changed files with 246 additions and 154 deletions

View File

@ -7,10 +7,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringJoiner;
import java.util.function.Predicate;
@ -43,10 +43,11 @@ public class GenerateJfrFiles {
metadata.verify();
metadata.wireUpTypes();
TypeCounter typeCounter = new TypeCounter();
printJfrEventIdsHpp(metadata, typeCounter, outputDirectory);
printJfrTypesHpp(metadata, typeCounter, outputDirectory);
printJfrPeriodicHpp(metadata, outputDirectory);
printJfrEventIdsHpp(metadata, outputDirectory);
printJfrEventControlHpp(metadata, outputDirectory);
printJfrTypesHpp(metadata, outputDirectory);
printJfrEventControlHpp(metadata, typeCounter, outputDirectory);
printJfrEventClassesHpp(metadata, outputDirectory);
} catch (Exception e) {
@ -55,12 +56,78 @@ public class GenerateJfrFiles {
}
}
static class TypeCounter {
final static long RESERVED_EVENT_COUNT = 2;
long typeId = -1;
long eventId = -1;
long eventCount = 0;
String firstTypeName;
String lastTypeName;
String firstEventName;
String lastEventname;
public long nextEventId(String name) {
eventCount++;
if (eventId == -1) {
eventId = firstEventId();
firstEventName = lastEventname = name;
return eventId;
}
lastEventname = name;
return ++eventId;
}
public long nextTypeId(String typeName) {
if (typeId == -1) {
lastTypeName = firstTypeName = typeName;
typeId = lastEventId();
}
lastTypeName = typeName;
return ++typeId;
}
public long firstEventId() {
return RESERVED_EVENT_COUNT;
}
public long lastEventId() {
return eventId == -1 ? firstEventId() : eventId;
}
public long eventCount() {
return eventCount;
}
public String firstTypeName() {
return firstTypeName;
}
public String lastTypeName() {
return lastTypeName;
}
public String firstEventName() {
return firstEventName;
}
public String lastEventName() {
return lastEventname;
}
}
static class XmlType {
final String name;
final String fieldType;
final String parameterType;
XmlType(String fieldType, String parameterType) {
final String javaType;
final boolean unsigned;
XmlType(String name, String fieldType, String parameterType, String javaType, boolean unsigned) {
this.name = name;
this.fieldType = fieldType;
this.parameterType = parameterType;
this.javaType = javaType;
this.unsigned = unsigned;
}
}
@ -74,7 +141,7 @@ public class GenerateJfrFiles {
static class Metadata {
final Map<String, TypeElement> types = new LinkedHashMap<>();
final Map<String, XmlType> xmlTypes = new HashMap<>();
final Map<String, XmlType> xmlTypes = new LinkedHashMap<>();
Metadata(File metadataXml, File metadataSchema) throws ParserConfigurationException, SAXException, FileNotFoundException, IOException {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
SAXParserFactory factory = SAXParserFactory.newInstance();
@ -110,12 +177,8 @@ public class GenerateJfrFiles {
return getList(t -> t.getClass() == EventElement.class && ((EventElement) t).periodic);
}
List<TypeElement> getNonEventsAndNonStructs() {
return getList(t -> t.getClass() != EventElement.class && !t.supportStruct);
}
List<TypeElement> getTypes() {
return getList(t -> t.getClass() == TypeElement.class && !t.supportStruct);
return getList(t -> t.getClass() == TypeElement.class);
}
List<TypeElement> getStructs() {
@ -213,8 +276,11 @@ public class GenerateJfrFiles {
String name = attributes.getValue("name");
String parameterType = attributes.getValue("parameterType");
String fieldType = attributes.getValue("fieldType");
metadata.xmlTypes.put(name, new XmlType(fieldType, parameterType));
String javaType = attributes.getValue("javaType");
boolean unsigned = getBoolean(attributes, "unsigned", false);
metadata.xmlTypes.put(name, new XmlType(name, fieldType, parameterType, javaType, unsigned));
break;
case "Relation":
case "Type":
currentType = new TypeElement();
currentType.name = attributes.getValue("name");
@ -247,6 +313,7 @@ public class GenerateJfrFiles {
@Override
public void endElement(String uri, String localName, String qName) {
switch (qName) {
case "Relation":
case "Type":
case "Event":
metadata.types.put(currentType.name, currentType);
@ -318,7 +385,7 @@ public class GenerateJfrFiles {
}
}
private static void printJfrEventControlHpp(Metadata metadata, File outputDirectory) throws Exception {
private static void printJfrEventControlHpp(Metadata metadata, TypeCounter typeCounter, File outputDirectory) throws Exception {
try (Printer out = new Printer(outputDirectory, "jfrEventControl.hpp")) {
out.write("#ifndef JFRFILES_JFR_NATIVE_EVENTSETTING_HPP");
out.write("#define JFRFILES_JFR_NATIVE_EVENTSETTING_HPP");
@ -342,11 +409,11 @@ public class GenerateJfrFiles {
out.write("");
out.write("union JfrNativeSettings {");
out.write(" // Array version.");
out.write(" jfrNativeEventSetting bits[MaxJfrEventId];");
out.write(" jfrNativeEventSetting bits[NUMBER_OF_EVENTS];");
out.write(" // Then, to make it easy to debug,");
out.write(" // add named struct members also.");
out.write(" struct {");
out.write(" jfrNativeEventSetting pad[NUM_RESERVED_EVENTS];");
out.write(" jfrNativeEventSetting pad[NUMBER_OF_RESERVED_EVENTS];");
for (TypeElement t : metadata.getEventsAndStructs()) {
out.write(" jfrNativeEventSetting " + t.name + ";");
}
@ -358,53 +425,34 @@ public class GenerateJfrFiles {
}
}
private static void printJfrEventIdsHpp(Metadata metadata, File outputDirectory) throws Exception {
private static void printJfrEventIdsHpp(Metadata metadata, TypeCounter typeCounter, File outputDirectory) throws Exception {
try (Printer out = new Printer(outputDirectory, "jfrEventIds.hpp")) {
out.write("#ifndef JFRFILES_JFREVENTIDS_HPP");
out.write("#define JFRFILES_JFREVENTIDS_HPP");
out.write("");
out.write("#include \"utilities/macros.hpp\"");
out.write("#if INCLUDE_JFR");
out.write("#include \"jfrfiles/jfrTypes.hpp\"");
out.write("");
out.write("/**");
out.write(" * Enum of the event types in the JVM");
out.write(" */");
out.write("enum JfrEventId {");
out.write(" _jfreventbase = (NUM_RESERVED_EVENTS-1), // Make sure we start at right index.");
out.write(" ");
out.write(" // Events -> enum entry");
for (TypeElement t : metadata.getEventsAndStructs()) {
out.write(" Jfr" + t.name + "Event,");
out.write(" JfrMetadataEvent = 0,");
out.write(" JfrCheckpointEvent = 1,");
for (TypeElement t : metadata.getEvents()) {
String name = "Jfr" + t.name +"Event";
out.write(" " + name + " = " + typeCounter.nextEventId(name) + ",");
}
out.write("");
out.write(" MaxJfrEventId");
out.write("};");
out.write("");
out.write("/**");
out.write(" * Struct types in the JVM");
out.write(" */");
out.write("enum JfrStructId {");
for (TypeElement t : metadata.getNonEventsAndNonStructs()) {
out.write(" Jfr" + t.name + "Struct,");
}
for (TypeElement t : metadata.getEventsAndStructs()) {
out.write(" Jfr" + t.name + "Struct,");
}
out.write("");
out.write(" MaxJfrStructId");
out.write("};");
out.write("");
out.write("typedef enum JfrEventId JfrEventId;");
out.write("typedef enum JfrStructId JfrStructId;");
out.write("");
out.write("static const JfrEventId FIRST_EVENT_ID = " + typeCounter.firstEventName() + ";");
out.write("static const JfrEventId LAST_EVENT_ID = " + typeCounter.lastEventName() + ";");
out.write("static const int NUMBER_OF_EVENTS = " + typeCounter.eventCount() + ";");
out.write("static const int NUMBER_OF_RESERVED_EVENTS = " + TypeCounter.RESERVED_EVENT_COUNT + ";");
out.write("#endif // INCLUDE_JFR");
out.write("#endif // JFRFILES_JFREVENTIDS_HPP");
}
}
private static void printJfrTypesHpp(Metadata metadata, File outputDirectory) throws Exception {
List<String> knownTypes = List.of("Thread", "StackTrace", "Class", "StackFrame");
private static void printJfrTypesHpp(Metadata metadata, TypeCounter typeCounter, File outputDirectory) throws Exception {
try (Printer out = new Printer(outputDirectory, "jfrTypes.hpp")) {
out.write("#ifndef JFRFILES_JFRTYPES_HPP");
out.write("#define JFRFILES_JFRTYPES_HPP");
@ -412,41 +460,54 @@ public class GenerateJfrFiles {
out.write("#include \"utilities/macros.hpp\"");
out.write("#if INCLUDE_JFR");
out.write("");
out.write("#include <string.h>");
out.write("#include \"memory/allocation.hpp\"");
out.write("");
out.write("enum JfrTypeId {");
out.write(" TYPE_NONE = 0,");
out.write(" TYPE_CLASS = 20,");
out.write(" TYPE_STRING = 21,");
out.write(" TYPE_THREAD = 22,");
out.write(" TYPE_STACKTRACE = 23,");
out.write(" TYPE_BYTES = 24,");
out.write(" TYPE_EPOCHMILLIS = 25,");
out.write(" TYPE_MILLIS = 26,");
out.write(" TYPE_NANOS = 27,");
out.write(" TYPE_TICKS = 28,");
out.write(" TYPE_ADDRESS = 29,");
out.write(" TYPE_PERCENTAGE = 30,");
out.write(" TYPE_DUMMY,");
out.write(" TYPE_DUMMY_1,");
for (TypeElement type : metadata.getTypes()) {
if (!knownTypes.contains(type.name)) {
out.write(" TYPE_" + type.name.toUpperCase() + ",");
Map<String, XmlType> javaTypes = new LinkedHashMap<>();
for (var t : metadata.xmlTypes.entrySet()) {
String name = t.getKey();
XmlType xmlType = t.getValue();
if (xmlType.javaType != null && !xmlType.unsigned) {
String typeName = "TYPE_" + name.toUpperCase();
long typeId = typeCounter.nextTypeId(typeName);
out.write(" " + typeName + " = " + typeId + ",");
javaTypes.put(name, xmlType);
}
}
for (TypeElement type : metadata.getTypes()) {
String name = type.name;
if (!javaTypes.containsKey(name)) {
String typeName = "TYPE_" + name.toUpperCase();
long typeId = typeCounter.nextTypeId(typeName);
out.write(" " + typeName + " = " + typeId + ",");
}
}
out.write("");
out.write(" NUM_JFR_TYPES,");
out.write(" TYPES_END = 255");
out.write("};");
out.write("");
out.write("enum ReservedEvent {");
out.write(" EVENT_METADATA,");
out.write(" EVENT_CHECKPOINT,");
out.write(" EVENT_BUFFERLOST,");
out.write(" NUM_RESERVED_EVENTS = TYPES_END");
out.write("static const JfrTypeId FIRST_TYPE_ID = " + typeCounter.firstTypeName() + ";");
out.write("static const JfrTypeId LAST_TYPE_ID = " + typeCounter.lastTypeName() + ";");
out.write("");
out.write("class JfrType : public AllStatic {");
out.write(" public:");
out.write(" static jlong name_to_id(const char* type_name) {");
for (Entry<String, XmlType> m : javaTypes.entrySet()) {
XmlType xmlType = m.getValue();
String javaName = xmlType.javaType;
String typeName = xmlType.name.toUpperCase();
out.write(" if (strcmp(type_name, \"" + javaName + "\") == 0) {");
out.write(" return TYPE_" + typeName + ";");
out.write(" }");
}
out.write(" return -1;");
out.write(" }");
out.write("};");
out.write("");
out.write("#endif // INCLUDE_JFR");
out.write("#endif // JFRFILES_JFRTYPES_HPP");
};
}
;
}
private static void printJfrEventClassesHpp(Metadata metadata, File outputDirectory) throws Exception {

View File

@ -49,6 +49,7 @@
#include "jfr/utilities/jfrTime.hpp"
#include "jfr/writers/jfrJavaEventWriter.hpp"
#include "jfrfiles/jfrPeriodic.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/interfaceSupport.inline.hpp"
@ -349,4 +350,10 @@ JVM_ENTRY_NO_ENV(jboolean, jfr_set_handler(JNIEnv * env, jobject jvm, jobject cl
return JfrJavaSupport::set_handler(clazz, handler, thread);
JVM_END
NO_TRANSITION(jlong, jfr_get_type_id_from_string(JNIEnv * env, jobject jvm, jstring type))
const char* type_name= env->GetStringUTFChars(type, NULL);
jlong id = JfrType::name_to_id(type_name);
env->ReleaseStringUTFChars(type, type_name);
return id;
NO_TRANSITION_END

View File

@ -148,6 +148,7 @@ jobject JNICALL jfr_get_handler(JNIEnv* env, jobject jvm, jobject clazz);
jboolean JNICALL jfr_set_handler(JNIEnv* env, jobject jvm, jobject clazz, jobject handler);
jlong JNICALL jfr_get_type_id_from_string(JNIEnv* env, jobject jvm, jstring type);
#ifdef __cplusplus
}

View File

@ -88,7 +88,8 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) {
(char*)"isExcluded", (char*)"(Ljava/lang/Thread;)Z", (void*)jfr_is_thread_excluded,
(char*)"getChunkStartNanos", (char*)"()J", (void*)jfr_chunk_start_nanos,
(char*)"getHandler", (char*)"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)jfr_get_handler,
(char*)"setHandler", (char*)"(Ljava/lang/Class;Ljdk/jfr/internal/handlers/EventHandler;)Z", (void*)jfr_set_handler
(char*)"setHandler", (char*)"(Ljava/lang/Class;Ljdk/jfr/internal/handlers/EventHandler;)Z", (void*)jfr_set_handler,
(char*)"getTypeId", (char*)"(Ljava/lang/String;)J", (void*)jfr_get_type_id_from_string
};
const size_t method_array_length = sizeof(method) / sizeof(JNINativeMethod);

View File

@ -1304,8 +1304,8 @@
<XmlType name="ClassLoader" parameterType="const ClassLoaderData*" fieldType="const ClassLoaderData*"/>
<XmlType name="Method" parameterType="const Method*" fieldType="const Method*"/>
<XmlType name="Thread" javaType="java.lang.Thread" parameterType="u8" fieldType="u8"/>
<XmlType name="Tickspan" contentType="tickspan" javaType="long" parameterType="const Tickspan&amp;" fieldType="Tickspan"/>
<XmlType name="Ticks" contentType="tickstamp" javaType="long" parameterType="const Ticks&amp;" fieldType="Ticks"/>
<XmlType name="Tickspan" contentType="tickspan" unsigned="true" javaType="long" parameterType="const Tickspan&amp;" fieldType="Tickspan"/>
<XmlType name="Ticks" contentType="tickstamp" unsigned="true" javaType="long" parameterType="const Ticks&amp;" fieldType="Ticks"/>
<XmlType name="ulong" javaType="long" unsigned="true" parameterType="u8" fieldType="u8"/>
<XmlType name="uint" javaType="int" unsigned="true" parameterType="unsigned" fieldType="unsigned"/>
<XmlType name="ushort" javaType="short" unsigned="true" parameterType="u2" fieldType="u2"/>
@ -1319,6 +1319,7 @@
<XmlType name="boolean" javaType="boolean" parameterType="bool" fieldType="bool"/>
<XmlType name="char" javaType="char" parameterType="char" fieldType="char"/>
<XmlType name="string" javaType="java.lang.String" parameterType="const char*" fieldType="const char*"/>
<XmlType name="StackTrace" javaType="jdk.types.StackTrace" parameterType="u8" fieldType="u8"/>
<XmlContentType name="bytes" annotation="jdk.jfr.DataAmount(BYTES)" />
<XmlContentType name="tickstamp" annotation="jdk.jfr.Timestamp(TICKS)" />

View File

@ -126,7 +126,8 @@ void JfrCheckpointWriter::release() {
}
void JfrCheckpointWriter::write_type(JfrTypeId type_id) {
assert(type_id < TYPES_END, "invariant");
assert(type_id <= LAST_TYPE_ID, "type id overflow invariant");
assert(type_id >= FIRST_TYPE_ID, "type id underflow invariant");
write<u8>(type_id);
increment();
}

View File

@ -27,6 +27,7 @@
#include "classfile/javaClasses.inline.hpp"
#include "classfile/symbolTable.hpp"
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "oops/arrayKlass.inline.hpp"
#include "oops/klass.inline.hpp"
@ -52,7 +53,7 @@ static traceid atomic_inc(traceid volatile* const dest) {
}
static traceid next_class_id() {
static volatile traceid class_id_counter = MaxJfrEventId + 100;
static volatile traceid class_id_counter = LAST_TYPE_ID + 1;
return atomic_inc(&class_id_counter) << TRACE_ID_SHIFT;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -55,7 +55,10 @@ void JfrEventSetting::set_enabled(jlong id, bool enabled) {
#ifdef ASSERT
bool JfrEventSetting::bounds_check_event(jlong id) {
if ((unsigned)id < NUM_RESERVED_EVENTS || (unsigned)id >= MaxJfrEventId) {
if ((unsigned)id < FIRST_EVENT_ID) {
return false;
}
if ((unsigned)id > LAST_EVENT_ID) {
return false;
}
return true;

View File

@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "jfr/recorder/repository/jfrChunk.hpp"
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
#include "jfr/utilities/jfrTime.hpp"

View File

@ -192,8 +192,8 @@ class JfrEvent {
JfrEventVerifier _verifier;
void assert_precondition() {
assert(T::eventId >= (JfrEventId)NUM_RESERVED_EVENTS, "event id underflow invariant");
assert(T::eventId < MaxJfrEventId, "event id overflow invariant");
assert(T::eventId >= FIRST_EVENT_ID, "event id underflow invariant");
assert(T::eventId <= LAST_EVENT_ID, "event id overflow invariant");
DEBUG_ONLY(static_cast<T*>(this)->verify());
}

View File

@ -26,6 +26,7 @@
#define SHARE_JFR_UTILITIES_JFRTYPES_HPP
#include "jfrfiles/jfrEventIds.hpp"
#include "jfrfiles/jfrTypes.hpp"
#include "utilities/globalDefinitions.hpp"
typedef u8 traceid;
@ -46,6 +47,11 @@ inline int sort_traceid(traceid* lhs, traceid* rhs) {
return compare_traceid(*lhs, *rhs);
}
enum ReservedEvent {
EVENT_METADATA = 0,
EVENT_CHECKPOINT = 1
};
enum EventStartTime {
UNTIMED,
TIMED

View File

@ -577,4 +577,13 @@ public final class JVM {
* @return the handler, may be {@code null}
*/
public native Object getHandler(Class<? extends jdk.internal.event.Event> eventClass);
/**
* Returns the id for the Java types defined in metadata.xml.
*
* @param name the name of the type
*
* @return the id, or a negative value if it does not exists.
*/
public native long getTypeId(String name);
}

View File

@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -59,6 +60,9 @@ import jdk.jfr.Unsigned;
final class MetadataHandler extends DefaultHandler implements EntityResolver {
// Metadata and Checkpoint event
private final long RESERVED_EVENT_COUNT = 2;
static class TypeElement {
List<FieldElement> fields = new ArrayList<>();
String name;
@ -72,6 +76,7 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
boolean stackTrace;
boolean cutoff;
boolean isEvent;
boolean isRelation;
boolean experimental;
boolean valueType;
}
@ -99,13 +104,11 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
}
final Map<String, TypeElement> types = new LinkedHashMap<>(200);
final Map<String, XmlType> xmlTypes = new HashMap<>(20);
final Map<String, List<AnnotationElement>> xmlContentTypes = new HashMap<>(20);
final List<String> relations = new ArrayList<>();
long eventTypeId = 255;
long structTypeId = 33;
final Map<String, XmlType> xmlTypes = new LinkedHashMap<>(20);
final Map<String, List<AnnotationElement>> xmlContentTypes = new LinkedHashMap<>(20);
FieldElement currentField;
TypeElement currentType;
long eventCount;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
@ -118,6 +121,7 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
xmlType.unsigned = Boolean.valueOf(attributes.getValue("unsigned"));
xmlTypes.put(xmlType.name, xmlType);
break;
case "Relation":
case "Type":
case "Event":
currentType = new TypeElement();
@ -132,6 +136,7 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
currentType.cutoff = getBoolean(attributes, "cutoff", false);
currentType.experimental = getBoolean(attributes, "experimental", false);
currentType.isEvent = qName.equals("Event");
currentType.isRelation = qName.equals("Relation");
break;
case "Field":
currentField = new FieldElement();
@ -151,10 +156,6 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
String annotation = attributes.getValue("annotation");
xmlContentTypes.put(name, createAnnotationElements(annotation));
break;
case "Relation":
String n = attributes.getValue("name");
relations.add(n);
break;
}
}
@ -202,7 +203,11 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
switch (qName) {
case "Type":
case "Event":
case "Relation":
types.put(currentType.name, currentType);
if (currentType.isEvent) {
eventCount++;
}
currentType = null;
break;
case "Field":
@ -221,7 +226,6 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
parser.parse(is, t);
return t.buildTypes();
} catch (Exception e) {
e.printStackTrace();
throw new IOException(e);
}
}
@ -237,12 +241,12 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
private Map<String, AnnotationElement> buildRelationMap(Map<String, Type> typeMap) {
Map<String, AnnotationElement> relationMap = new HashMap<>();
for (String relation : relations) {
Type relationType = new Type(Type.TYPES_PREFIX + relation, Type.SUPER_TYPE_ANNOTATION, eventTypeId++);
relationType.setAnnotations(Collections.singletonList(new AnnotationElement(Relational.class)));
AnnotationElement ae = PrivateAccess.getInstance().newAnnotation(relationType, Collections.emptyList(), true);
relationMap.put(relation, ae);
typeMap.put(relationType.getName(), relationType);
for (TypeElement t : types.values()) {
if (t.isRelation) {
Type relationType = typeMap.get(t.name);
AnnotationElement ae = PrivateAccess.getInstance().newAnnotation(relationType, Collections.emptyList(), true);
relationMap.put(t.name, ae);
}
}
return relationMap;
}
@ -276,7 +280,9 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
aes.addAll(Objects.requireNonNull(xmlContentTypes.get(f.contentType)));
}
if (f.relation != null) {
aes.add(Objects.requireNonNull(relationMap.get(f.relation)));
String relationTypeName = Type.TYPES_PREFIX + f.relation;
AnnotationElement t = relationMap.get(relationTypeName);
aes.add(Objects.requireNonNull(t));
}
if (f.label != null) {
aes.add(new AnnotationElement(Label.class, f.label));
@ -301,10 +307,13 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
private Map<String, Type> buildTypeMap() {
Map<String, Type> typeMap = new HashMap<>();
for (Type type : Type.getKnownTypes()) {
typeMap.put(type.getName(), type);
Map<String, Type> knownTypeMap = new HashMap<>();
for (Type kt :Type.getKnownTypes()) {
typeMap.put(kt.getName(), kt);
knownTypeMap.put(kt.getName(), kt);
}
long eventTypeId = RESERVED_EVENT_COUNT;
long typeId = RESERVED_EVENT_COUNT + eventCount + knownTypeMap.size();
for (TypeElement t : types.values()) {
List<AnnotationElement> aes = new ArrayList<>();
if (t.category != null) {
@ -339,10 +348,16 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
aes.add(new AnnotationElement(Enabled.class, false));
type = new PlatformEventType(t.name, eventTypeId++, false, true);
} else {
// Struct types had their own XML-element in the past. To have id assigned in the
// same order as generated .hpp file do some tweaks here.
boolean valueType = t.name.endsWith("StackFrame") || t.valueType;
type = new Type(t.name, null, valueType ? eventTypeId++ : nextTypeId(t.name), false);
if (knownTypeMap.containsKey(t.name)) {
type = knownTypeMap.get(t.name);
} else {
if (t.isRelation) {
type = new Type(t.name, Type.SUPER_TYPE_ANNOTATION, typeId++);
aes.add(new AnnotationElement(Relational.class));
} else {
type = new Type(t.name, null, typeId++);
}
}
}
type.setAnnotations(aes);
typeMap.put(t.name, type);
@ -350,24 +365,6 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
return typeMap;
}
private long nextTypeId(String name) {
if (Type.THREAD.getName().equals(name)) {
return Type.THREAD.getId();
}
if (Type.STRING.getName().equals(name)) {
return Type.STRING.getId();
}
if (Type.CLASS.getName().equals(name)) {
return Type.CLASS.getId();
}
for (Type type : Type.getKnownTypes()) {
if (type.getName().equals(name)) {
return type.getId();
}
}
return structTypeId++;
}
private String[] buildCategoryArray(String category) {
List<String> categories = new ArrayList<>();
StringBuilder sb = new StringBuilder();

View File

@ -261,7 +261,7 @@ final class MetadataReader {
if (Type.SUPER_TYPE_EVENT.equals(superType)) {
t = new PlatformEventType(typeName, id, false, false);
} else {
t = new Type(typeName, superType, id, false, simpleType);
t = new Type(typeName, superType, id, simpleType);
}
types.put(id, t);
descriptor.types.add(t);

View File

@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -53,25 +54,37 @@ public class Type implements Comparable<Type> {
public static final String SETTINGS_PREFIX = "jdk.settings.";
// Initialization of known types
private final static Map<Type, Class<?>> knownTypes = new HashMap<>();
static final Type BOOLEAN = register(boolean.class, new Type("boolean", null, 4));
static final Type CHAR = register(char.class, new Type("char", null, 5));
static final Type FLOAT = register(float.class, new Type("float", null, 6));
static final Type DOUBLE = register(double.class, new Type("double", null, 7));
static final Type BYTE = register(byte.class, new Type("byte", null, 8));
static final Type SHORT = register(short.class, new Type("short", null, 9));
static final Type INT = register(int.class, new Type("int", null, 10));
static final Type LONG = register(long.class, new Type("long", null, 11));
static final Type CLASS = register(Class.class, new Type("java.lang.Class", null, 20));
static final Type STRING = register(String.class, new Type("java.lang.String", null, 21));
static final Type THREAD = register(Thread.class, new Type("java.lang.Thread", null, 22));
static final Type STACK_TRACE = register(null, new Type(TYPES_PREFIX + "StackTrace", null, 23));
// To bootstrap the type system, the supported Java types
// are available here as statics. When metadata.xml is parsed
// fields are added to THREAD and STACK_TRACE.
private final static Map<Type, Class<?>> knownTypes = new LinkedHashMap<>();
static final Type BOOLEAN = createKnownType(boolean.class);
static final Type CHAR = createKnownType(char.class);
static final Type FLOAT = createKnownType(float.class);
static final Type DOUBLE = createKnownType(double.class);
static final Type BYTE = createKnownType(byte.class);
static final Type SHORT = createKnownType(short.class);
static final Type INT = createKnownType(int.class);
static final Type LONG = createKnownType(long.class);
static final Type CLASS = createKnownType(Class.class);
static final Type STRING = createKnownType(String.class);
static final Type THREAD = createKnownType(Thread.class);
static final Type STACK_TRACE = createKnownType(TYPES_PREFIX + "StackTrace", null);
private static Type createKnownType(Class<?> clazz) {
return createKnownType(clazz.getName(), clazz);
}
private static Type createKnownType(String name, Class<?> clazz) {
long id = JVM.getJVM().getTypeId(name);
Type t = new Type(name, null, id);
knownTypes.put(t, clazz);
return t;
}
private final AnnotationConstruct annos = new AnnotationConstruct();
private final String name;
private final String superType;
private final boolean constantPool;
private List<ValueDescriptor> fields = new ArrayList<>();
private Boolean simpleType; // calculated lazy
private boolean remove = true;
@ -86,20 +99,15 @@ public class Type implements Comparable<Type> {
*
*/
public Type(String javaTypeName, String superType, long typeId) {
this(javaTypeName, superType, typeId, false);
this(javaTypeName, superType, typeId, null);
}
Type(String javaTypeName, String superType, long typeId, boolean constantPool) {
this(javaTypeName, superType, typeId, constantPool, null);
}
Type(String javaTypeName, String superType, long typeId, boolean constantPool, Boolean simpleType) {
Type(String javaTypeName, String superType, long typeId, Boolean simpleType) {
Objects.requireNonNull(javaTypeName);
if (!isValidJavaIdentifier(javaTypeName)) {
throw new IllegalArgumentException(javaTypeName + " is not a valid Java identifier");
}
this.constantPool = constantPool;
this.superType = superType;
this.name = javaTypeName;
this.id = typeId;
@ -210,11 +218,6 @@ public class Type implements Comparable<Type> {
return id < JVM.RESERVED_CLASS_ID_LIMIT;
}
private static Type register(Class<?> clazz, Type type) {
knownTypes.put(type, clazz);
return type;
}
public void add(ValueDescriptor valueDescriptor) {
Objects.requireNonNull(valueDescriptor);
fields.add(valueDescriptor);
@ -236,10 +239,6 @@ public class Type implements Comparable<Type> {
return id;
}
public boolean isConstantPool() {
return constantPool;
}
public String getLabel() {
return annos.getLabel();
}

View File

@ -92,6 +92,10 @@ public class TestEventMetadata {
*/
public static void main(String[] args) throws Exception {
Set<String> types = new HashSet<>();
// These types contains reserved keywords (unfortunately) so
// exclude them from the check.
types.add("jdk.types.StackTrace");
types.add("java.lang.Class");
List<EventType> eventTypes = FlightRecorder.getFlightRecorder().getEventTypes();
Set<String> eventNames= new HashSet<>();
for (EventType eventType : eventTypes) {