Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8319997: JFR: Reduce use of dynamic proxies #19106

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/jdk.jfr/share/classes/jdk/jfr/EventType.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -50,7 +50,7 @@
*/
public final class EventType {
private static final String UNKNOWN = new String();
private static final List<String> UNCATEGORIZED = List.of("Uncategorized");
private static final String[] UNCATEGORIZED = { "Uncategorized" };
private final PlatformEventType platformEventType;
private Map<String, ValueDescriptor> cache; // create lazy to avoid memory overhead
private String label = UNKNOWN;
Expand Down Expand Up @@ -235,11 +235,8 @@ public List<SettingDescriptor> getSettingDescriptors() {
* @see Category
*/
public List<String> getCategoryNames() {
Category c = platformEventType.getAnnotation(Category.class);
if (c == null) {
return UNCATEGORIZED;
}
return List.of(c.value());
String[] categories = platformEventType.getAnnotationValue(Category.class, UNCATEGORIZED);
return List.of(categories);
}

// package private
Expand Down
33 changes: 19 additions & 14 deletions src/jdk.jfr/share/classes/jdk/jfr/internal/AnnotationConstruct.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, 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
Expand Down Expand Up @@ -72,19 +72,11 @@ public void setAnnotationElements(List<AnnotationElement> elements) {
}

public String getLabel() {
Label label = getAnnotation(Label.class);
if (label == null) {
return null;
}
return label.value();
return getAnnotationValue(Label.class, null);
}

public String getDescription() {
Description description = getAnnotation(Description.class);
if (description == null) {
return null;
}
return description.value();
return getAnnotationValue(Description.class, null);
}

@SuppressWarnings("unchecked")
Expand All @@ -100,7 +92,20 @@ public List<AnnotationElement> getUnmodifiableAnnotationElements() {
return annotationElements;
}

private AnnotationElement getAnnotationElement(Class<? extends Annotation> clazz) {
/**
* Convenience method that returns the annotation value, or a default value
* if the type lacks the annotation.
*/
@SuppressWarnings("unchecked")
public <T> T getAnnotationValue(Class<? extends java.lang.annotation.Annotation> clazz, T defaultValue) {
AnnotationElement ae = getAnnotationElement(clazz);
if (ae == null) {
return defaultValue;
}
return (T) ae.getValues().get(0);
}

AnnotationElement getAnnotationElement(Class<? extends Annotation> clazz) {
// if multiple annotation elements with the same name exists, prioritize
// the one with the same id. Note, id alone is not a guarantee, since it
// may differ between JVM instances.
Expand All @@ -123,8 +128,8 @@ public boolean hasUnsigned() {
// Must be initialized lazily since some annotation elements
// are added after construction
if (unsignedFlag < 0) {
Unsigned unsigned = getAnnotation(Unsigned.class);
unsignedFlag = (byte) (unsigned == null ? 0 :1);
AnnotationElement ae = getAnnotationElement(Unsigned.class);
unsignedFlag = (byte) (ae == null ? 0 :1);
}
return unsignedFlag == (byte)1 ? true : false;
}
Expand Down
46 changes: 11 additions & 35 deletions src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -290,72 +290,48 @@ private SettingControl instantiateSettingControl(Class<? extends SettingControl>
}

private static Control defineEnabled(PlatformEventType type) {
Enabled enabled = type.getAnnotation(Enabled.class);
// Java events are enabled by default,
// JVM events are not, maybe they should be? Would lower learning curve
// there too.
String def = type.isJVM() ? "false" : "true";
if (enabled != null) {
def = Boolean.toString(enabled.value());
}
Boolean defaultValue = Boolean.valueOf(!type.isJVM());
String def = type.getAnnotationValue(Enabled.class, defaultValue).toString();
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_ENABLED, Enabled.NAME, def, Collections.emptyList()));
return new Control(new EnabledSetting(type, def), def);
}

private static Control defineThreshold(PlatformEventType type) {
Threshold threshold = type.getAnnotation(Threshold.class);
String def = "0 ns";
if (threshold != null) {
def = threshold.value();
}
String def = type.getAnnotationValue(Threshold.class, "0 ns");
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_THRESHOLD, Threshold.NAME, def, Collections.emptyList()));
return new Control(new ThresholdSetting(type), def);
}

private static Control defineStackTrace(PlatformEventType type) {
StackTrace stackTrace = type.getAnnotation(StackTrace.class);
String def = "true";
if (stackTrace != null) {
def = Boolean.toString(stackTrace.value());
}
String def = type.getAnnotationValue(StackTrace.class, Boolean.TRUE).toString();
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_STACK_TRACE, StackTrace.NAME, def, Collections.emptyList()));
return new Control(new StackTraceSetting(type, def), def);
}

private static Control defineCutoff(PlatformEventType type) {
Cutoff cutoff = type.getAnnotation(Cutoff.class);
String def = Cutoff.INFINITY;
if (cutoff != null) {
def = cutoff.value();
}
String def = type.getAnnotationValue(Cutoff.class, Cutoff.INFINITY);
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_CUTOFF, Cutoff.NAME, def, Collections.emptyList()));
return new Control(new CutoffSetting(type), def);
}

private static Control defineThrottle(PlatformEventType type) {
Throttle throttle = type.getAnnotation(Throttle.class);
String def = Throttle.DEFAULT;
if (throttle != null) {
def = throttle.value();
}
String def = type.getAnnotationValue(Throttle.class, Throttle.DEFAULT);
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_THROTTLE, Throttle.NAME, def, Collections.emptyList()));
return new Control(new ThrottleSetting(type), def);
}

private static Control defineLevel(PlatformEventType type) {
Level level = type.getAnnotation(Level.class);
String[] values = level.value();
String def = values[0];
String[] levels = type.getAnnotationValue(Level.class, new String[0]);
String def = levels[0]; // Level value always exists
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_LEVEL, Level.NAME, def, Collections.emptyList()));
return new Control(new LevelSetting(type, values), def);
return new Control(new LevelSetting(type, levels), def);
}

private static Control definePeriod(PlatformEventType type) {
Period period = type.getAnnotation(Period.class);
String def = "everyChunk";
if (period != null) {
def = period.value();
}
String def = type.getAnnotationValue(Period.class, "everyChunk");
type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_PERIOD, PeriodSetting.NAME, def, Collections.emptyList()));
return new Control(new PeriodSetting(type), def);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ private void initializeJVMEventTypes() {
for (Type type : TypeLibrary.getTypes()) {
if (type instanceof PlatformEventType pEventType) {
EventType eventType = PrivateAccess.getInstance().newEventType(pEventType);
pEventType.setHasCutoff(eventType.getAnnotation(Cutoff.class) != null);
pEventType.setHasThrottle(eventType.getAnnotation(Throttle.class) != null);
pEventType.setHasLevel(eventType.getAnnotation(Level.class) != null);
pEventType.setHasPeriod(eventType.getAnnotation(Period.class) != null);
pEventType.setHasCutoff(type.hasAnnotation(Cutoff.class));
pEventType.setHasThrottle(type.hasAnnotation(Throttle.class));
pEventType.setHasLevel(type.hasAnnotation(Level.class));
pEventType.setHasPeriod(type.hasAnnotation(Period.class));
// Must add hook before EventControl is created as it removes
// annotations, such as Period and Threshold.
if (pEventType.hasPeriod()) {
Expand Down
8 changes: 8 additions & 0 deletions src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ public List<AnnotationElement> getAnnotationElements() {
return annos.getUnmodifiableAnnotationElements();
}

public <T> T getAnnotationValue(Class<? extends java.lang.annotation.Annotation> clazz, T defaultValue) {
return annos.getAnnotationValue(clazz, defaultValue);
}

public <T> T getAnnotation(Class<? extends java.lang.annotation.Annotation> clazz) {
return annos.getAnnotation(clazz);
}
Expand Down Expand Up @@ -359,4 +363,8 @@ public void setInternal(boolean internal) {
public boolean isInternal() {
return internal;
}

public boolean hasAnnotation(Class<? extends java.lang.annotation.Annotation> clazz) {
return annos.getAnnotationElement(clazz) != null;
}
}