8326838: JFR: Native mirror events
Reviewed-by: mgronlun
This commit is contained in:
parent
b8fc4186d5
commit
d29cefb6eb
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -35,12 +35,14 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import jdk.jfr.AnnotationElement;
|
import jdk.jfr.AnnotationElement;
|
||||||
import jdk.jfr.Event;
|
import jdk.jfr.Event;
|
||||||
import jdk.jfr.EventType;
|
import jdk.jfr.EventType;
|
||||||
|
import jdk.jfr.Name;
|
||||||
import jdk.jfr.Period;
|
import jdk.jfr.Period;
|
||||||
import jdk.jfr.StackTrace;
|
import jdk.jfr.StackTrace;
|
||||||
import jdk.jfr.Threshold;
|
import jdk.jfr.Threshold;
|
||||||
@ -54,8 +56,8 @@ public final class MetadataRepository {
|
|||||||
|
|
||||||
private static final MetadataRepository instance = new MetadataRepository();
|
private static final MetadataRepository instance = new MetadataRepository();
|
||||||
|
|
||||||
private final List<EventType> nativeEventTypes = new ArrayList<>(150);
|
private final Map<String, EventType> nativeEventTypes = LinkedHashMap.newHashMap(150);
|
||||||
private final List<EventControl> nativeControls = new ArrayList<EventControl>(nativeEventTypes.size());
|
private final Map<String, EventControl> nativeControls = LinkedHashMap.newHashMap(150);
|
||||||
private final SettingsManager settingsManager = new SettingsManager();
|
private final SettingsManager settingsManager = new SettingsManager();
|
||||||
private Constructor<EventConfiguration> cachedEventConfigurationConstructor;
|
private Constructor<EventConfiguration> cachedEventConfigurationConstructor;
|
||||||
private boolean staleMetadata = true;
|
private boolean staleMetadata = true;
|
||||||
@ -83,8 +85,9 @@ public final class MetadataRepository {
|
|||||||
PeriodicEvents.addJVMEvent(pEventType);
|
PeriodicEvents.addJVMEvent(pEventType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nativeControls.add(new EventControl(pEventType));
|
String name = eventType.getName();
|
||||||
nativeEventTypes.add(eventType);
|
nativeControls.put(name, new EventControl(pEventType));
|
||||||
|
nativeEventTypes.put(name,eventType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +104,7 @@ public final class MetadataRepository {
|
|||||||
eventTypes.add(ec.getEventType());
|
eventTypes.add(ec.getEventType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (EventType t : nativeEventTypes) {
|
for (EventType t : nativeEventTypes.values()) {
|
||||||
if (PrivateAccess.getInstance().isVisible(t)) {
|
if (PrivateAccess.getInstance().isVisible(t)) {
|
||||||
eventTypes.add(t);
|
eventTypes.add(t);
|
||||||
}
|
}
|
||||||
@ -200,6 +203,32 @@ public final class MetadataRepository {
|
|||||||
if (pEventType == null) {
|
if (pEventType == null) {
|
||||||
pEventType = (PlatformEventType) TypeLibrary.createType(eventClass, dynamicAnnotations, dynamicFields);
|
pEventType = (PlatformEventType) TypeLibrary.createType(eventClass, dynamicAnnotations, dynamicFields);
|
||||||
}
|
}
|
||||||
|
// Check for native mirror.
|
||||||
|
// Note, defining an event in metadata.xml is not a generic mechanism to emit
|
||||||
|
// native data in Java. For example, calling JVM.getStackTraceId(int, long)
|
||||||
|
// and assign the result to a long field is not enough to always get a proper
|
||||||
|
// stack trace. Purpose of the mechanism is to transfer metadata, such as
|
||||||
|
// native type IDs, without specialized Java logic for each type.
|
||||||
|
if (eventClass.getClassLoader() == null) {
|
||||||
|
Name name = eventClass.getAnnotation(Name.class);
|
||||||
|
if (name != null) {
|
||||||
|
String n = name.value();
|
||||||
|
EventType nativeType = nativeEventTypes.get(n);
|
||||||
|
if (nativeType != null) {
|
||||||
|
var nativeFields = nativeType.getFields();
|
||||||
|
var eventFields = pEventType.getFields();
|
||||||
|
var comparator = Comparator.comparing(ValueDescriptor::getName);
|
||||||
|
if (!Utils.compareLists(nativeFields, eventFields, comparator)) {
|
||||||
|
throw new InternalError("Field for native mirror event " + n + " doesn't match Java event");
|
||||||
|
}
|
||||||
|
nativeEventTypes.remove(n);
|
||||||
|
nativeControls.remove(n);
|
||||||
|
TypeLibrary.removeType(nativeType.getId());
|
||||||
|
pEventType.setAnnotations(nativeType.getAnnotationElements());
|
||||||
|
pEventType.setFields(nativeType.getFields());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
EventType eventType = PrivateAccess.getInstance().newEventType(pEventType);
|
EventType eventType = PrivateAccess.getInstance().newEventType(pEventType);
|
||||||
EventControl ec = new EventControl(pEventType, eventClass);
|
EventControl ec = new EventControl(pEventType, eventClass);
|
||||||
EventConfiguration configuration = newEventConfiguration(eventType, ec);
|
EventConfiguration configuration = newEventConfiguration(eventType, ec);
|
||||||
@ -226,7 +255,7 @@ public final class MetadataRepository {
|
|||||||
public synchronized List<EventControl> getEventControls() {
|
public synchronized List<EventControl> getEventControls() {
|
||||||
List<Class<? extends jdk.internal.event.Event>> eventClasses = JVM.getAllEventClasses();
|
List<Class<? extends jdk.internal.event.Event>> eventClasses = JVM.getAllEventClasses();
|
||||||
ArrayList<EventControl> controls = new ArrayList<>(eventClasses.size() + nativeControls.size());
|
ArrayList<EventControl> controls = new ArrayList<>(eventClasses.size() + nativeControls.size());
|
||||||
controls.addAll(nativeControls);
|
controls.addAll(nativeControls.values());
|
||||||
for (Class<? extends jdk.internal.event.Event> clazz : eventClasses) {
|
for (Class<? extends jdk.internal.event.Event> clazz : eventClasses) {
|
||||||
EventConfiguration eh = JVMSupport.getConfiguration(clazz);
|
EventConfiguration eh = JVMSupport.getConfiguration(clazz);
|
||||||
if (eh != null) {
|
if (eh != null) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -222,6 +222,10 @@ public class Type implements Comparable<Type> {
|
|||||||
return id < JVM.RESERVED_CLASS_ID_LIMIT;
|
return id < JVM.RESERVED_CLASS_ID_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFields(List<ValueDescriptor> fields) {
|
||||||
|
this.fields = List.copyOf(fields);
|
||||||
|
}
|
||||||
|
|
||||||
public void add(ValueDescriptor valueDescriptor) {
|
public void add(ValueDescriptor valueDescriptor) {
|
||||||
Objects.requireNonNull(valueDescriptor);
|
Objects.requireNonNull(valueDescriptor);
|
||||||
fields.add(valueDescriptor);
|
fields.add(valueDescriptor);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -322,7 +322,7 @@ public final class TypeLibrary {
|
|||||||
ValueDescriptor vd = dynamicFieldSet.get(field.getName());
|
ValueDescriptor vd = dynamicFieldSet.get(field.getName());
|
||||||
if (vd != null) {
|
if (vd != null) {
|
||||||
if (!vd.getTypeName().equals(field.getType().getName())) {
|
if (!vd.getTypeName().equals(field.getType().getName())) {
|
||||||
throw new InternalError("Type expected to match for field " + vd.getName() + " expected " + field.getName() + " but got " + vd.getName());
|
throw new InternalError("Type expected to match for field " + vd.getName() + " expected " + field.getType().getName() + " but got " + vd.getTypeName());
|
||||||
}
|
}
|
||||||
for (AnnotationElement ae : vd.getAnnotationElements()) {
|
for (AnnotationElement ae : vd.getAnnotationElements()) {
|
||||||
newTypes.add(PrivateAccess.getInstance().getType(ae));
|
newTypes.add(PrivateAccess.getInstance().getType(ae));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -37,6 +37,7 @@ import java.nio.file.Path;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -176,6 +177,19 @@ public final class Utils {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> boolean compareLists(List<T> a, List<T> b, Comparator<T> c) {
|
||||||
|
int size = a.size();
|
||||||
|
if (size != b.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (c.compare(a.get(i), b.get(i)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> List<T> sanitizeNullFreeList(List<T> elements, Class<T> clazz) {
|
public static <T> List<T> sanitizeNullFreeList(List<T> elements, Class<T> clazz) {
|
||||||
List<T> sanitized = new ArrayList<>(elements.size());
|
List<T> sanitized = new ArrayList<>(elements.size());
|
||||||
for (T element : elements) {
|
for (T element : elements) {
|
||||||
|
Loading…
Reference in New Issue
Block a user