Reduce jfr framework overhead JEP-349-branch
authoregahlin
Fri, 12 Jul 2019 15:04:28 +0200
branchJEP-349-branch
changeset 57470 025c9b8eaefd
parent 57467 de154169948b
child 57604 838f9a7635b6
Reduce jfr framework overhead
src/jdk.jfr/share/classes/jdk/jfr/consumer/EventParser.java
src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java
src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java
src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java
src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java
src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java
src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventParser.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventParser.java	Fri Jul 12 15:04:28 2019 +0200
@@ -101,7 +101,7 @@
     }
 
     public boolean isEnabled() {
-        return this.enabled;
+        return enabled;
     }
 
     public RecordedEvent parse(RecordingInput input) throws IOException {
@@ -110,16 +110,16 @@
         }
 
         long startTicks = input.readLong();
-        long durationTicks = 0;
+        long endTicks = startTicks;
         if (hasDuration) {
-            durationTicks = input.readLong();
+            long durationTicks = input.readLong();
             if (thresholdNanos > 0L) {
                 if (timeConverter.convertTimespan(durationTicks) < thresholdNanos) {
                     return null;
                 }
             }
+            endTicks += durationTicks;
         }
-        long endTicks = startTicks + durationTicks;
         if (firstNanos > 0L) {
             if (timeConverter.convertTimestamp(endTicks) < firstNanos) {
                 return null;
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/ParserFactory.java	Fri Jul 12 15:04:28 2019 +0200
@@ -204,10 +204,11 @@
         @Override
         public Object parse(RecordingInput input) throws IOException {
             long l = input.readLong();
-            if (l != last) {
-                last = l;
-                lastLongObject = Long.valueOf(l);
+            if (l == last) {
+                return lastLongObject;
             }
+            last = l;
+            lastLongObject = Long.valueOf(l);
             return lastLongObject;
         }
 
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java	Fri Jul 12 15:04:28 2019 +0200
@@ -40,6 +40,13 @@
 @StackTrace(false)
 public final class ActiveRecordingEvent extends AbstractJDKEvent {
 
+    public static final ThreadLocal<ActiveRecordingEvent> EVENT = new ThreadLocal<ActiveRecordingEvent>() {
+        @Override
+        protected ActiveRecordingEvent initialValue() {
+            return new ActiveRecordingEvent();
+        }
+    };
+
     @Label("Id")
     public long id;
 
--- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java	Fri Jul 12 15:04:28 2019 +0200
@@ -37,6 +37,13 @@
 @StackTrace(false)
 public final class ActiveSettingEvent extends AbstractJDKEvent {
 
+    public static final ThreadLocal<ActiveSettingEvent> EVENT = new ThreadLocal<ActiveSettingEvent>() {
+        @Override
+        protected ActiveSettingEvent initialValue() {
+            return new ActiveSettingEvent();
+        }
+    };
+
     @Label("Event Id")
     public long id;
 
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java	Fri Jul 12 15:04:28 2019 +0200
@@ -32,11 +32,7 @@
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 
 import jdk.internal.module.Modules;
 import jdk.jfr.AnnotationElement;
@@ -59,7 +55,14 @@
 // holds SettingControl instances that need to be released
 // when a class is unloaded (to avoid memory leaks).
 public final class EventControl {
-
+    final static class NamedControl {
+        public final String name;
+        public final Control control;
+        NamedControl(String name, Control control) {
+            this.name = name;
+            this.control = control;
+        }
+    }
     static final String FIELD_SETTING_PREFIX = "setting";
     private static final Type TYPE_ENABLED = TypeLibrary.createType(EnabledSetting.class);
     private static final Type TYPE_THRESHOLD = TypeLibrary.createType(ThresholdSetting.class);
@@ -67,24 +70,24 @@
     private static final Type TYPE_PERIOD = TypeLibrary.createType(PeriodSetting.class);
     private static final Type TYPE_CUTOFF = TypeLibrary.createType(CutoffSetting.class);
 
-    private final List<SettingInfo> settingInfos = new ArrayList<>();
-    private final Map<String, Control> eventControls = new HashMap<>(5);
+    private final ArrayList<SettingInfo> settingInfos = new ArrayList<>();
+    private final ArrayList<NamedControl> namedControls = new ArrayList<>(5);
     private final PlatformEventType type;
     private final String idName;
 
     EventControl(PlatformEventType eventType) {
-        eventControls.put(Enabled.NAME, defineEnabled(eventType));
+        addControl(Enabled.NAME, defineEnabled(eventType));
         if (eventType.hasDuration()) {
-            eventControls.put(Threshold.NAME, defineThreshold(eventType));
+            addControl(Threshold.NAME, defineThreshold(eventType));
         }
         if (eventType.hasStackTrace()) {
-            eventControls.put(StackTrace.NAME, defineStackTrace(eventType));
+            addControl(StackTrace.NAME, defineStackTrace(eventType));
         }
         if (eventType.hasPeriod()) {
-            eventControls.put(Period.NAME, definePeriod(eventType));
+            addControl(Period.NAME, definePeriod(eventType));
         }
         if (eventType.hasCutoff()) {
-            eventControls.put(Cutoff.NAME, defineCutoff(eventType));
+            addControl(Cutoff.NAME, defineCutoff(eventType));
         }
 
         ArrayList<AnnotationElement> aes = new ArrayList<>(eventType.getAnnotationElements());
@@ -99,6 +102,19 @@
         this.idName = String.valueOf(eventType.getId());
     }
 
+    private boolean hasControl(String name) {
+        for (NamedControl nc : namedControls) {
+            if (name.equals(nc.name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void addControl(String name, Control control) {
+        namedControls.add(new NamedControl(name, control));
+    }
+
     static void remove(PlatformEventType type, List<AnnotationElement> aes, Class<? extends java.lang.annotation.Annotation> clazz) {
         long id = Type.getTypeId(clazz);
         for (AnnotationElement a : type.getAnnotationElements()) {
@@ -131,7 +147,8 @@
                             if (n != null) {
                                 name = n.value();
                             }
-                            if (!eventControls.containsKey(name)) {
+
+                            if (!hasControl(name)) {
                                 defineSetting((Class<? extends SettingControl>) settingClass, m, type, name);
                             }
                         }
@@ -163,7 +180,7 @@
                     }
                 }
                 aes.trimToSize();
-                eventControls.put(settingName, si.settingControl);
+                addControl(settingName, si.settingControl);
                 eventType.add(PrivateAccess.getInstance().newSettingDescriptor(settingType, settingName, defaultValue, aes));
                 settingInfos.add(si);
             }
@@ -247,9 +264,9 @@
     }
 
     void disable() {
-        for (Control c : eventControls.values()) {
-            if (c instanceof EnabledSetting) {
-                c.setValueSafe("false");
+        for (NamedControl nc : namedControls) {
+            if (nc.control instanceof EnabledSetting) {
+                nc.control.setValueSafe("false");
                 return;
             }
         }
@@ -259,24 +276,23 @@
         if (!type.isRegistered()) {
             return;
         }
-        for (Map.Entry<String, Control> entry : eventControls.entrySet()) {
-            Control c = entry.getValue();
-            if (Utils.isSettingVisible(c, type.hasEventHook())) {
-                String value = c.getLastValue();
+        ActiveSettingEvent event = ActiveSettingEvent.EVENT.get();
+        for (NamedControl nc : namedControls) {
+            if (Utils.isSettingVisible(nc.control, type.hasEventHook())) {
+                String value = nc.control.getLastValue();
                 if (value == null) {
-                    value = c.getDefaultValue();
+                    value = nc.control.getDefaultValue();
                 }
-                ActiveSettingEvent ase = new ActiveSettingEvent();
-                ase.id = type.getId();
-                ase.name = entry.getKey();
-                ase.value = value;
-                ase.commit();
+                event.id = type.getId();
+                event.name = nc.name;
+                event.value = value;
+                event.commit();
             }
         }
     }
 
-    public Set<Entry<String, Control>> getEntries() {
-        return eventControls.entrySet();
+    public ArrayList<NamedControl> getNamedControls() {
+        return namedControls;
     }
 
     public PlatformEventType getEventType() {
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java	Fri Jul 12 15:04:28 2019 +0200
@@ -210,10 +210,14 @@
     }
 
     public synchronized List<EventControl> getEventControls() {
-        List<EventControl> controls = new ArrayList<>();
+        List<Class<? extends jdk.internal.event.Event>> eventClasses = jvm.getAllEventClasses();
+        ArrayList<EventControl> controls = new ArrayList<>(eventClasses.size() + nativeControls.size());
         controls.addAll(nativeControls);
-        for (EventHandler eh : getEventHandlers()) {
-            controls.add(eh.getEventControl());
+        for (Class<? extends jdk.internal.event.Event> clazz : eventClasses) {
+            EventHandler eh = Utils.getHandler(clazz);
+            if (eh != null) {
+                controls.add(eh.getEventControl());
+            }
         }
         return controls;
     }
@@ -319,4 +323,8 @@
         }
         this.flushMetadata = false;
     }
+
+
+
+
 }
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java	Fri Jul 12 15:04:28 2019 +0200
@@ -58,6 +58,7 @@
 
 public final class PlatformRecorder {
 
+
     private final List<PlatformRecording> recordings = new ArrayList<>();
     private final static List<SecureRecorderListener> changeListeners = new ArrayList<>();
     private final Repository repository;
@@ -417,11 +418,10 @@
     }
 
     private void writeMetaEvents() {
-
         if (activeRecordingEvent.isEnabled()) {
+            ActiveRecordingEvent event = ActiveRecordingEvent.EVENT.get();
             for (PlatformRecording r : getRecordings()) {
                 if (r.getState() == RecordingState.RUNNING && r.shouldWriteMetadataEvent()) {
-                    ActiveRecordingEvent event = new ActiveRecordingEvent();
                     event.id = r.getId();
                     event.name = r.getName();
                     WriteableUserPath p = r.getDestination();
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java	Thu Jul 11 02:21:18 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/SettingsManager.java	Fri Jul 12 15:04:28 2019 +0200
@@ -33,10 +33,10 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.StringJoiner;
 
+import jdk.jfr.internal.EventControl.NamedControl;
 import jdk.jfr.internal.handlers.EventHandler;
 
 final class SettingsManager {
@@ -213,18 +213,21 @@
 
     void setEventControl(EventControl ec) {
         InternalSetting is = getInternalSetting(ec);
-        Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "Applied settings for " + ec.getEventType().getLogName() + " {");
-        for (Entry<String, Control> entry : ec.getEntries()) {
+        boolean shouldLog = Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO);
+        if (shouldLog) {
+            Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "Applied settings for " + ec.getEventType().getLogName() + " {");
+        }
+        for (NamedControl nc: ec.getNamedControls()) {
             Set<String> values = null;
-            String settingName = entry.getKey();
+            String settingName = nc.name;
             if (is != null) {
                 values = is.getValues(settingName);
             }
-            Control control = entry.getValue();
+            Control control = nc.control;
             if (values != null) {
                 control.apply(values);
                 String after = control.getLastValue();
-                if (Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO)) {
+                if (shouldLog) {
                     if (Utils.isSettingVisible(control, ec.getEventType().hasEventHook())) {
                         if (values.size() > 1) {
                             StringJoiner sj = new StringJoiner(", ", "{", "}");
@@ -241,14 +244,16 @@
                 }
             } else {
                 control.setDefault();
-                if (Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO)) {
+                if (shouldLog) {
                     String message = "  " + settingName + "=\"" + control.getLastValue() + "\"";
                     Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, message);
                 }
             }
         }
         ec.writeActiveSettingEvent();
-        Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "}");
+        if (shouldLog) {
+            Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "}");
+        }
     }
 
     private InternalSetting getInternalSetting(EventControl ec) {