src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java
changeset 58863 c16ac7a2eba4
parent 52334 a181612f0715
equal deleted inserted replaced
58861:2c3cc4b01880 58863:c16ac7a2eba4
     1 /*
     1 /*
     2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    30 import java.lang.reflect.InvocationTargetException;
    30 import java.lang.reflect.InvocationTargetException;
    31 import java.lang.reflect.Method;
    31 import java.lang.reflect.Method;
    32 import java.lang.reflect.Modifier;
    32 import java.lang.reflect.Modifier;
    33 import java.util.ArrayList;
    33 import java.util.ArrayList;
    34 import java.util.Collections;
    34 import java.util.Collections;
    35 import java.util.HashMap;
       
    36 import java.util.List;
    35 import java.util.List;
    37 import java.util.Map;
       
    38 import java.util.Map.Entry;
       
    39 import java.util.Set;
       
    40 
    36 
    41 import jdk.internal.module.Modules;
    37 import jdk.internal.module.Modules;
    42 import jdk.jfr.AnnotationElement;
    38 import jdk.jfr.AnnotationElement;
    43 import jdk.jfr.Enabled;
    39 import jdk.jfr.Enabled;
    44 import jdk.jfr.Name;
    40 import jdk.jfr.Name;
    57 
    53 
    58 // This class can't have a hard reference from PlatformEventType, since it
    54 // This class can't have a hard reference from PlatformEventType, since it
    59 // holds SettingControl instances that need to be released
    55 // holds SettingControl instances that need to be released
    60 // when a class is unloaded (to avoid memory leaks).
    56 // when a class is unloaded (to avoid memory leaks).
    61 public final class EventControl {
    57 public final class EventControl {
    62 
    58     final static class NamedControl {
       
    59         public final String name;
       
    60         public final Control control;
       
    61         NamedControl(String name, Control control) {
       
    62             this.name = name;
       
    63             this.control = control;
       
    64         }
       
    65     }
    63     static final String FIELD_SETTING_PREFIX = "setting";
    66     static final String FIELD_SETTING_PREFIX = "setting";
    64     private static final Type TYPE_ENABLED = TypeLibrary.createType(EnabledSetting.class);
    67     private static final Type TYPE_ENABLED = TypeLibrary.createType(EnabledSetting.class);
    65     private static final Type TYPE_THRESHOLD = TypeLibrary.createType(ThresholdSetting.class);
    68     private static final Type TYPE_THRESHOLD = TypeLibrary.createType(ThresholdSetting.class);
    66     private static final Type TYPE_STACK_TRACE = TypeLibrary.createType(StackTraceSetting.class);
    69     private static final Type TYPE_STACK_TRACE = TypeLibrary.createType(StackTraceSetting.class);
    67     private static final Type TYPE_PERIOD = TypeLibrary.createType(PeriodSetting.class);
    70     private static final Type TYPE_PERIOD = TypeLibrary.createType(PeriodSetting.class);
    68     private static final Type TYPE_CUTOFF = TypeLibrary.createType(CutoffSetting.class);
    71     private static final Type TYPE_CUTOFF = TypeLibrary.createType(CutoffSetting.class);
    69 
    72 
    70     private final List<SettingInfo> settingInfos = new ArrayList<>();
    73     private final ArrayList<SettingInfo> settingInfos = new ArrayList<>();
    71     private final Map<String, Control> eventControls = new HashMap<>(5);
    74     private final ArrayList<NamedControl> namedControls = new ArrayList<>(5);
    72     private final PlatformEventType type;
    75     private final PlatformEventType type;
    73     private final String idName;
    76     private final String idName;
    74 
    77 
    75     EventControl(PlatformEventType eventType) {
    78     EventControl(PlatformEventType eventType) {
    76         eventControls.put(Enabled.NAME, defineEnabled(eventType));
    79         addControl(Enabled.NAME, defineEnabled(eventType));
    77         if (eventType.hasDuration()) {
    80         if (eventType.hasDuration()) {
    78             eventControls.put(Threshold.NAME, defineThreshold(eventType));
    81             addControl(Threshold.NAME, defineThreshold(eventType));
    79         }
    82         }
    80         if (eventType.hasStackTrace()) {
    83         if (eventType.hasStackTrace()) {
    81             eventControls.put(StackTrace.NAME, defineStackTrace(eventType));
    84             addControl(StackTrace.NAME, defineStackTrace(eventType));
    82         }
    85         }
    83         if (eventType.hasPeriod()) {
    86         if (eventType.hasPeriod()) {
    84             eventControls.put(Period.NAME, definePeriod(eventType));
    87             addControl(Period.NAME, definePeriod(eventType));
    85         }
    88         }
    86         if (eventType.hasCutoff()) {
    89         if (eventType.hasCutoff()) {
    87             eventControls.put(Cutoff.NAME, defineCutoff(eventType));
    90             addControl(Cutoff.NAME, defineCutoff(eventType));
    88         }
    91         }
    89 
    92 
    90         ArrayList<AnnotationElement> aes = new ArrayList<>(eventType.getAnnotationElements());
    93         ArrayList<AnnotationElement> aes = new ArrayList<>(eventType.getAnnotationElements());
    91         remove(eventType, aes, Threshold.class);
    94         remove(eventType, aes, Threshold.class);
    92         remove(eventType, aes, Period.class);
    95         remove(eventType, aes, Period.class);
    95         remove(eventType, aes, Cutoff.class);
    98         remove(eventType, aes, Cutoff.class);
    96         aes.trimToSize();
    99         aes.trimToSize();
    97         eventType.setAnnotations(aes);
   100         eventType.setAnnotations(aes);
    98         this.type = eventType;
   101         this.type = eventType;
    99         this.idName = String.valueOf(eventType.getId());
   102         this.idName = String.valueOf(eventType.getId());
       
   103     }
       
   104 
       
   105     private boolean hasControl(String name) {
       
   106         for (NamedControl nc : namedControls) {
       
   107             if (name.equals(nc.name)) {
       
   108                 return true;
       
   109             }
       
   110         }
       
   111         return false;
       
   112     }
       
   113 
       
   114     private void addControl(String name, Control control) {
       
   115         namedControls.add(new NamedControl(name, control));
   100     }
   116     }
   101 
   117 
   102     static void remove(PlatformEventType type, List<AnnotationElement> aes, Class<? extends java.lang.annotation.Annotation> clazz) {
   118     static void remove(PlatformEventType type, List<AnnotationElement> aes, Class<? extends java.lang.annotation.Annotation> clazz) {
   103         long id = Type.getTypeId(clazz);
   119         long id = Type.getTypeId(clazz);
   104         for (AnnotationElement a : type.getAnnotationElements()) {
   120         for (AnnotationElement a : type.getAnnotationElements()) {
   129                             String name = m.getName();
   145                             String name = m.getName();
   130                             Name n = m.getAnnotation(Name.class);
   146                             Name n = m.getAnnotation(Name.class);
   131                             if (n != null) {
   147                             if (n != null) {
   132                                 name = n.value();
   148                                 name = n.value();
   133                             }
   149                             }
   134                             if (!eventControls.containsKey(name)) {
   150 
       
   151                             if (!hasControl(name)) {
   135                                 defineSetting((Class<? extends SettingControl>) settingClass, m, type, name);
   152                                 defineSetting((Class<? extends SettingControl>) settingClass, m, type, name);
   136                             }
   153                             }
   137                         }
   154                         }
   138                     }
   155                     }
   139                 }
   156                 }
   161                     if (ae != null) {
   178                     if (ae != null) {
   162                         aes.add(ae);
   179                         aes.add(ae);
   163                     }
   180                     }
   164                 }
   181                 }
   165                 aes.trimToSize();
   182                 aes.trimToSize();
   166                 eventControls.put(settingName, si.settingControl);
   183                 addControl(settingName, si.settingControl);
   167                 eventType.add(PrivateAccess.getInstance().newSettingDescriptor(settingType, settingName, defaultValue, aes));
   184                 eventType.add(PrivateAccess.getInstance().newSettingDescriptor(settingType, settingName, defaultValue, aes));
   168                 settingInfos.add(si);
   185                 settingInfos.add(si);
   169             }
   186             }
   170         } catch (InstantiationException e) {
   187         } catch (InstantiationException e) {
   171             // Programming error by user, fail fast
   188             // Programming error by user, fail fast
   245         type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_PERIOD, PeriodSetting.NAME, def, Collections.emptyList()));
   262         type.add(PrivateAccess.getInstance().newSettingDescriptor(TYPE_PERIOD, PeriodSetting.NAME, def, Collections.emptyList()));
   246         return new PeriodSetting(type, def);
   263         return new PeriodSetting(type, def);
   247     }
   264     }
   248 
   265 
   249     void disable() {
   266     void disable() {
   250         for (Control c : eventControls.values()) {
   267         for (NamedControl nc : namedControls) {
   251             if (c instanceof EnabledSetting) {
   268             if (nc.control instanceof EnabledSetting) {
   252                 c.setValueSafe("false");
   269                 nc.control.setValueSafe("false");
   253                 return;
   270                 return;
   254             }
   271             }
   255         }
   272         }
   256     }
   273     }
   257 
   274 
   258     void writeActiveSettingEvent() {
   275     void writeActiveSettingEvent() {
   259         if (!type.isRegistered()) {
   276         if (!type.isRegistered()) {
   260             return;
   277             return;
   261         }
   278         }
   262         for (Map.Entry<String, Control> entry : eventControls.entrySet()) {
   279         ActiveSettingEvent event = ActiveSettingEvent.EVENT.get();
   263             Control c = entry.getValue();
   280         for (NamedControl nc : namedControls) {
   264             if (Utils.isSettingVisible(c, type.hasEventHook())) {
   281             if (Utils.isSettingVisible(nc.control, type.hasEventHook())) {
   265                 String value = c.getLastValue();
   282                 String value = nc.control.getLastValue();
   266                 if (value == null) {
   283                 if (value == null) {
   267                     value = c.getDefaultValue();
   284                     value = nc.control.getDefaultValue();
   268                 }
   285                 }
   269                 ActiveSettingEvent ase = new ActiveSettingEvent();
   286                 event.id = type.getId();
   270                 ase.id = type.getId();
   287                 event.name = nc.name;
   271                 ase.name = entry.getKey();
   288                 event.value = value;
   272                 ase.value = value;
   289                 event.commit();
   273                 ase.commit();
   290             }
   274             }
   291         }
   275         }
   292     }
   276     }
   293 
   277 
   294     public ArrayList<NamedControl> getNamedControls() {
   278     public Set<Entry<String, Control>> getEntries() {
   295         return namedControls;
   279         return eventControls.entrySet();
       
   280     }
   296     }
   281 
   297 
   282     public PlatformEventType getEventType() {
   298     public PlatformEventType getEventType() {
   283         return type;
   299         return type;
   284     }
   300     }