8216303: JFR: Simplify generated files
Reviewed-by: erikj, mgronlun
This commit is contained in:
parent
02fbf44cc7
commit
6fd44901ec
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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&" fieldType="Tickspan"/>
|
||||
<XmlType name="Ticks" contentType="tickstamp" javaType="long" parameterType="const Ticks&" fieldType="Ticks"/>
|
||||
<XmlType name="Tickspan" contentType="tickspan" unsigned="true" javaType="long" parameterType="const Tickspan&" fieldType="Tickspan"/>
|
||||
<XmlType name="Ticks" contentType="tickstamp" unsigned="true" javaType="long" parameterType="const Ticks&" 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)" />
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user