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())) { |