src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java
changeset 52334 a181612f0715
parent 50113 caf115bb98ad
child 57360 5d043a159d5c
child 58836 31ec3e55fa3d
equal deleted inserted replaced
52333:c401c536cea1 52334:a181612f0715
    31 import java.io.ByteArrayOutputStream;
    31 import java.io.ByteArrayOutputStream;
    32 import java.io.DataOutputStream;
    32 import java.io.DataOutputStream;
    33 import java.io.IOException;
    33 import java.io.IOException;
    34 import java.util.ArrayList;
    34 import java.util.ArrayList;
    35 import java.util.Collections;
    35 import java.util.Collections;
       
    36 import java.util.HashMap;
    36 import java.util.HashSet;
    37 import java.util.HashSet;
    37 import java.util.List;
    38 import java.util.List;
    38 import java.util.Map;
    39 import java.util.Map;
    39 
    40 
    40 import jdk.jfr.AnnotationElement;
    41 import jdk.jfr.AnnotationElement;
    54 
    55 
    55     private final List<EventType> nativeEventTypes = new ArrayList<>(100);
    56     private final List<EventType> nativeEventTypes = new ArrayList<>(100);
    56     private final List<EventControl> nativeControls = new ArrayList<EventControl>(100);
    57     private final List<EventControl> nativeControls = new ArrayList<EventControl>(100);
    57     private final TypeLibrary typeLibrary = TypeLibrary.getInstance();
    58     private final TypeLibrary typeLibrary = TypeLibrary.getInstance();
    58     private final SettingsManager settingsManager = new SettingsManager();
    59     private final SettingsManager settingsManager = new SettingsManager();
       
    60     private final Map<String, Class<? extends Event>> mirrors = new HashMap<>();
    59     private boolean staleMetadata = true;
    61     private boolean staleMetadata = true;
    60     private boolean unregistered;
    62     private boolean unregistered;
    61     private long lastUnloaded = -1;
    63     private long lastUnloaded = -1;
    62 
    64 
    63     public MetadataRepository() {
    65     public MetadataRepository() {
   103         }
   105         }
   104         eventTypes.addAll(nativeEventTypes);
   106         eventTypes.addAll(nativeEventTypes);
   105         return eventTypes;
   107         return eventTypes;
   106     }
   108     }
   107 
   109 
   108     public synchronized EventType getEventType(Class<? extends Event> eventClass) {
   110     public synchronized EventType getEventType(Class<? extends jdk.internal.event.Event> eventClass) {
   109         EventHandler h = getHandler(eventClass);
   111         EventHandler h = getHandler(eventClass);
   110         if (h != null && h.isRegistered()) {
   112         if (h != null && h.isRegistered()) {
   111             return h.getEventType();
   113             return h.getEventType();
   112         }
   114         }
   113         throw new IllegalStateException("Event class " + eventClass.getName() + " is not registered");
   115         throw new IllegalStateException("Event class " + eventClass.getName() + " is not registered");
   119         if (handler != null) {
   121         if (handler != null) {
   120             handler.setRegistered(false);
   122             handler.setRegistered(false);
   121         }
   123         }
   122         // never registered, ignore call
   124         // never registered, ignore call
   123     }
   125     }
   124     public synchronized EventType register(Class<? extends Event> eventClass) {
   126     public synchronized EventType register(Class<? extends jdk.internal.event.Event> eventClass) {
   125         return register(eventClass, Collections.emptyList(), Collections.emptyList());
   127         return register(eventClass, Collections.emptyList(), Collections.emptyList());
   126     }
   128     }
   127 
   129 
   128     public synchronized EventType register(Class<? extends Event> eventClass, List<AnnotationElement> dynamicAnnotations, List<ValueDescriptor> dynamicFields) {
   130     public synchronized EventType register(Class<? extends jdk.internal.event.Event> eventClass, List<AnnotationElement> dynamicAnnotations, List<ValueDescriptor> dynamicFields) {
   129         Utils.checkRegisterPermission();
   131         Utils.checkRegisterPermission();
   130         EventHandler handler = getHandler(eventClass);
   132         EventHandler handler = getHandler(eventClass);
   131         if (handler == null) {
   133         if (handler == null) {
   132             handler = makeHandler(eventClass, dynamicAnnotations, dynamicFields);
   134             if (eventClass.getAnnotation(MirrorEvent.class) != null) {
       
   135                 // don't register mirrors
       
   136                 return null;
       
   137             }
       
   138             PlatformEventType pe = findMirrorType(eventClass);
       
   139             handler = makeHandler(eventClass, pe, dynamicAnnotations, dynamicFields);
   133         }
   140         }
   134         handler.setRegistered(true);
   141         handler.setRegistered(true);
   135         typeLibrary.addType(handler.getPlatformEventType());
   142         typeLibrary.addType(handler.getPlatformEventType());
   136         if (jvm.isRecording()) {
   143         if (jvm.isRecording()) {
   137             storeDescriptorInJVM(); // needed for emergency dump
   144             storeDescriptorInJVM(); // needed for emergency dump
   141             setStaleMetadata();
   148             setStaleMetadata();
   142         }
   149         }
   143         return handler.getEventType();
   150         return handler.getEventType();
   144     }
   151     }
   145 
   152 
   146     private EventHandler getHandler(Class<? extends Event> eventClass) {
   153     private PlatformEventType findMirrorType(Class<? extends jdk.internal.event.Event> eventClass) throws InternalError {
       
   154         String fullName = eventClass.getModule().getName() + ":" + eventClass.getName();
       
   155         Class<? extends Event> mirrorClass = mirrors.get(fullName);
       
   156         if (mirrorClass == null) {
       
   157             return null; // not a mirror
       
   158         }
       
   159         Utils.verifyMirror(mirrorClass, eventClass);
       
   160         PlatformEventType et = (PlatformEventType) TypeLibrary.createType(mirrorClass);
       
   161         typeLibrary.removeType(et.getId());
       
   162         long id = Type.getTypeId(eventClass);
       
   163         et.setId(id);
       
   164         return et;
       
   165     }
       
   166 
       
   167     private EventHandler getHandler(Class<? extends jdk.internal.event.Event> eventClass) {
   147         Utils.ensureValidEventSubclass(eventClass);
   168         Utils.ensureValidEventSubclass(eventClass);
   148         SecuritySupport.makeVisibleToJFR(eventClass);
   169         SecuritySupport.makeVisibleToJFR(eventClass);
   149         Utils.ensureInitialized(eventClass);
   170         Utils.ensureInitialized(eventClass);
   150         return Utils.getHandler(eventClass);
   171         return Utils.getHandler(eventClass);
   151     }
   172     }
   152 
   173 
   153     private EventHandler makeHandler(Class<? extends Event> eventClass, List<AnnotationElement> dynamicAnnotations, List<ValueDescriptor> dynamicFields) throws InternalError {
   174     private EventHandler makeHandler(Class<? extends jdk.internal.event.Event> eventClass, PlatformEventType pEventType, List<AnnotationElement> dynamicAnnotations, List<ValueDescriptor> dynamicFields) throws InternalError {
   154         SecuritySupport.addHandlerExport(eventClass);
   175         SecuritySupport.addHandlerExport(eventClass);
   155         PlatformEventType pEventType = (PlatformEventType) TypeLibrary.createType(eventClass, dynamicAnnotations, dynamicFields);
   176         if (pEventType == null) {
       
   177             pEventType = (PlatformEventType) TypeLibrary.createType(eventClass, dynamicAnnotations, dynamicFields);
       
   178         }
   156         EventType eventType = PrivateAccess.getInstance().newEventType(pEventType);
   179         EventType eventType = PrivateAccess.getInstance().newEventType(pEventType);
   157         EventControl ec = new EventControl(pEventType, eventClass);
   180         EventControl ec = new EventControl(pEventType, eventClass);
   158         Class<? extends EventHandler> handlerClass = null;
   181         Class<? extends EventHandler> handlerClass = null;
   159         try {
   182         try {
   160             String eventHandlerName = EventHandlerCreator.makeEventHandlerName(eventType.getId());
   183             String eventHandlerName = EventHandlerCreator.makeEventHandlerName(eventType.getId());
   196         jvm.storeMetadataDescriptor(getBinaryRepresentation());
   219         jvm.storeMetadataDescriptor(getBinaryRepresentation());
   197         staleMetadata = false;
   220         staleMetadata = false;
   198     }
   221     }
   199 
   222 
   200     private static List<EventHandler> getEventHandlers() {
   223     private static List<EventHandler> getEventHandlers() {
   201         List<Class<? extends Event>> allEventClasses = jvm.getAllEventClasses();
   224         List<Class<? extends jdk.internal.event.Event>> allEventClasses = jvm.getAllEventClasses();
   202         List<EventHandler> eventHandlers = new ArrayList<>(allEventClasses.size());
   225         List<EventHandler> eventHandlers = new ArrayList<>(allEventClasses.size());
   203         for (Class<? extends Event> clazz : allEventClasses) {
   226         for (Class<? extends jdk.internal.event.Event> clazz : allEventClasses) {
   204             EventHandler eh = Utils.getHandler(clazz);
   227             EventHandler eh = Utils.getHandler(clazz);
   205             if (eh != null) {
   228             if (eh != null) {
   206                 eventHandlers.add(eh);
   229                 eventHandlers.add(eh);
   207             }
   230             }
   208         }
   231         }
   250 
   273 
   251     private void unregisterUnloaded() {
   274     private void unregisterUnloaded() {
   252         long unloaded = jvm.getUnloadedEventClassCount();
   275         long unloaded = jvm.getUnloadedEventClassCount();
   253         if (this.lastUnloaded != unloaded) {
   276         if (this.lastUnloaded != unloaded) {
   254             this.lastUnloaded = unloaded;
   277             this.lastUnloaded = unloaded;
   255             List<Class<? extends Event>> eventClasses = jvm.getAllEventClasses();
   278             List<Class<? extends jdk.internal.event.Event>> eventClasses = jvm.getAllEventClasses();
   256             HashSet<Long> knownIds = new HashSet<>(eventClasses.size());
   279             HashSet<Long> knownIds = new HashSet<>(eventClasses.size());
   257             for (Class<? extends Event>  ec: eventClasses) {
   280             for (Class<? extends jdk.internal.event.Event>  ec: eventClasses) {
   258                 knownIds.add(Type.getTypeId(ec));
   281                 knownIds.add(Type.getTypeId(ec));
   259             }
   282             }
   260             for (Type type : typeLibrary.getTypes()) {
   283             for (Type type : typeLibrary.getTypes()) {
   261                 if (type instanceof PlatformEventType) {
   284                 if (type instanceof PlatformEventType) {
   262                     if (!knownIds.contains(type.getId())) {
   285                     if (!knownIds.contains(type.getId())) {
   268                 }
   291                 }
   269             }
   292             }
   270         }
   293         }
   271     }
   294     }
   272 
   295 
   273     synchronized public void setUnregistered() {
   296     synchronized void setUnregistered() {
   274        unregistered = true;
   297        unregistered = true;
   275     }
   298     }
   276 
   299 
       
   300     public synchronized void registerMirror(Class<? extends Event> eventClass) {
       
   301         MirrorEvent me = eventClass.getAnnotation(MirrorEvent.class);
       
   302         if (me != null) {
       
   303             String fullName = me.module() + ":" + me.className();
       
   304             mirrors.put(fullName, eventClass);
       
   305             return;
       
   306         }
       
   307         throw new InternalError("Mirror class must have annotation " + MirrorEvent.class.getName());
       
   308     }
       
   309 
   277 }
   310 }