From 8d78e8cadcc06aea7179ec97d3bf8b7cee63b447 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Tue, 7 May 2024 18:59:41 +0000 Subject: [PATCH] 8319997: JFR: Reduce use of dynamic proxies Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/EventType.java | 11 ++--- .../jdk/jfr/internal/AnnotationConstruct.java | 33 +++++++------ .../jdk/jfr/internal/EventControl.java | 46 +++++-------------- .../jdk/jfr/internal/MetadataRepository.java | 8 ++-- .../share/classes/jdk/jfr/internal/Type.java | 8 ++++ 5 files changed, 46 insertions(+), 60 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/EventType.java b/src/jdk.jfr/share/classes/jdk/jfr/EventType.java index 07c82d5bf53..d9b4e50fca8 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/EventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/EventType.java @@ -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 @@ -50,7 +50,7 @@ import jdk.jfr.internal.util.Utils; */ public final class EventType { private static final String UNKNOWN = new String(); - private static final List UNCATEGORIZED = List.of("Uncategorized"); + private static final String[] UNCATEGORIZED = { "Uncategorized" }; private final PlatformEventType platformEventType; private Map cache; // create lazy to avoid memory overhead private String label = UNKNOWN; @@ -235,11 +235,8 @@ public final class EventType { * @see Category */ public List 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 diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/AnnotationConstruct.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/AnnotationConstruct.java index 8b5b45fb223..9a203ff3725 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/AnnotationConstruct.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/AnnotationConstruct.java @@ -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 @@ -72,19 +72,11 @@ public final class AnnotationConstruct { } 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") @@ -100,7 +92,20 @@ public final class AnnotationConstruct { return annotationElements; } - private AnnotationElement getAnnotationElement(Class clazz) { + /** + * Convenience method that returns the annotation value, or a default value + * if the type lacks the annotation. + */ + @SuppressWarnings("unchecked") + public T getAnnotationValue(Class clazz, T defaultValue) { + AnnotationElement ae = getAnnotationElement(clazz); + if (ae == null) { + return defaultValue; + } + return (T) ae.getValues().get(0); + } + + AnnotationElement getAnnotationElement(Class 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. @@ -123,8 +128,8 @@ public final class AnnotationConstruct { // 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; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 68aa3eb8478..2a758aa8add 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -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 @@ -290,72 +290,48 @@ public final class EventControl { } 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); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 7d61d3c984f..9a2bbfe4c63 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -73,10 +73,10 @@ public final class MetadataRepository { 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()) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java index bc949b8c7ff..0306541b4f7 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java @@ -264,6 +264,10 @@ public class Type implements Comparable { return annos.getUnmodifiableAnnotationElements(); } + public T getAnnotationValue(Class clazz, T defaultValue) { + return annos.getAnnotationValue(clazz, defaultValue); + } + public T getAnnotation(Class clazz) { return annos.getAnnotation(clazz); } @@ -359,4 +363,8 @@ public class Type implements Comparable { public boolean isInternal() { return internal; } + + public boolean hasAnnotation(Class clazz) { + return annos.getAnnotationElement(clazz) != null; + } }