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.
|
||||
*
|
||||
* 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.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.jfr.AnnotationElement;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.EventType;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.Period;
|
||||
import jdk.jfr.StackTrace;
|
||||
import jdk.jfr.Threshold;
|
||||
@ -54,8 +56,8 @@ public final class MetadataRepository {
|
||||
|
||||
private static final MetadataRepository instance = new MetadataRepository();
|
||||
|
||||
private final List<EventType> nativeEventTypes = new ArrayList<>(150);
|
||||
private final List<EventControl> nativeControls = new ArrayList<EventControl>(nativeEventTypes.size());
|
||||
private final Map<String, EventType> nativeEventTypes = LinkedHashMap.newHashMap(150);
|
||||
private final Map<String, EventControl> nativeControls = LinkedHashMap.newHashMap(150);
|
||||
private final SettingsManager settingsManager = new SettingsManager();
|
||||
private Constructor<EventConfiguration> cachedEventConfigurationConstructor;
|
||||
private boolean staleMetadata = true;
|
||||
@ -83,8 +85,9 @@ public final class MetadataRepository {
|
||||
PeriodicEvents.addJVMEvent(pEventType);
|
||||
}
|
||||
}
|
||||
nativeControls.add(new EventControl(pEventType));
|
||||
nativeEventTypes.add(eventType);
|
||||
String name = eventType.getName();
|
||||
nativeControls.put(name, new EventControl(pEventType));
|
||||
nativeEventTypes.put(name,eventType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,7 +104,7 @@ public final class MetadataRepository {
|
||||
eventTypes.add(ec.getEventType());
|
||||
}
|
||||
}
|
||||
for (EventType t : nativeEventTypes) {
|
||||
for (EventType t : nativeEventTypes.values()) {
|
||||
if (PrivateAccess.getInstance().isVisible(t)) {
|
||||
eventTypes.add(t);
|
||||
}
|
||||
@ -200,6 +203,32 @@ public final class MetadataRepository {
|
||||
if (pEventType == null) {
|
||||
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);
|
||||
EventControl ec = new EventControl(pEventType, eventClass);
|
||||
EventConfiguration configuration = newEventConfiguration(eventType, ec);
|
||||
@ -226,7 +255,7 @@ public final class MetadataRepository {
|
||||
public synchronized List<EventControl> getEventControls() {
|
||||
List<Class<? extends jdk.internal.event.Event>> eventClasses = JVM.getAllEventClasses();
|
||||
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) {
|
||||
EventConfiguration eh = JVMSupport.getConfiguration(clazz);
|
||||
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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
public void setFields(List<ValueDescriptor> fields) {
|
||||
this.fields = List.copyOf(fields);
|
||||
}
|
||||
|
||||
public void add(ValueDescriptor valueDescriptor) {
|
||||
Objects.requireNonNull(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.
|
||||
*
|
||||
* 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());
|
||||
if (vd != null) {
|
||||
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()) {
|
||||
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.
|
||||
*
|
||||
* 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.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -176,6 +177,19 @@ public final class Utils {
|
||||
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) {
|
||||
List<T> sanitized = new ArrayList<>(elements.size());
|
||||
for (T element : elements) {
|
||||
|
Loading…
Reference in New Issue
Block a user