src/jdk.jfr/share/classes/jdk/jfr/internal/RequestEngine.java
changeset 52899 325c95779368
parent 50113 caf115bb98ad
child 57360 5d043a159d5c
child 58863 c16ac7a2eba4
equal deleted inserted replaced
52898:f3d5dcb6924b 52899:325c95779368
    32 import java.util.Collection;
    32 import java.util.Collection;
    33 import java.util.List;
    33 import java.util.List;
    34 import java.util.Objects;
    34 import java.util.Objects;
    35 import java.util.concurrent.CopyOnWriteArrayList;
    35 import java.util.concurrent.CopyOnWriteArrayList;
    36 import java.util.function.Predicate;
    36 import java.util.function.Predicate;
       
    37 import jdk.jfr.Event;
       
    38 import jdk.jfr.EventType;
    37 
    39 
    38 public final class RequestEngine {
    40 public final class RequestEngine {
    39 
    41 
    40     private final static JVM jvm = JVM.getJVM();
    42     private final static JVM jvm = JVM.getJVM();
    41 
    43 
    58         }
    60         }
    59 
    61 
    60         private void execute() {
    62         private void execute() {
    61             try {
    63             try {
    62                 if (accessControllerContext == null) { // native
    64                 if (accessControllerContext == null) { // native
    63                     jvm.emitEvent(type.getId(), JVM.counterTime(), 0);
    65                     if (type.isJDK()) {
       
    66                         hook.run();
       
    67                     } else {
       
    68                         jvm.emitEvent(type.getId(), JVM.counterTime(), 0);
       
    69                     }
    64                     Logger.log(LogTag.JFR_SYSTEM_EVENT, LogLevel.DEBUG, ()-> "Executed periodic hook for " + type.getLogName());
    70                     Logger.log(LogTag.JFR_SYSTEM_EVENT, LogLevel.DEBUG, ()-> "Executed periodic hook for " + type.getLogName());
    65                 } else {
    71                 } else {
    66                     executeSecure();
    72                     executeSecure();
    67                 }
    73                 }
    68             } catch (Throwable e) {
    74             } catch (Throwable e) {
    89     }
    95     }
    90 
    96 
    91     private final static List<RequestHook> entries = new CopyOnWriteArrayList<>();
    97     private final static List<RequestHook> entries = new CopyOnWriteArrayList<>();
    92     private static long lastTimeMillis;
    98     private static long lastTimeMillis;
    93 
    99 
    94     // Insertion takes O(2*n), could be O(1) with HashMap, but
       
    95     // thinking is that CopyOnWriteArrayList is faster
       
    96     // to iterate over, which will happen more over time.
       
    97     public static void addHook(AccessControlContext acc, PlatformEventType type, Runnable hook) {
   100     public static void addHook(AccessControlContext acc, PlatformEventType type, Runnable hook) {
    98         Objects.requireNonNull(acc);
   101         Objects.requireNonNull(acc);
       
   102         addHookInternal(acc, type, hook);
       
   103     }
       
   104 
       
   105     private static void addHookInternal(AccessControlContext acc, PlatformEventType type, Runnable hook) {
    99         RequestHook he = new RequestHook(acc, type, hook);
   106         RequestHook he = new RequestHook(acc, type, hook);
   100         for (RequestHook e : entries) {
   107         for (RequestHook e : entries) {
   101             if (e.hook == hook) {
   108             if (e.hook == hook) {
   102                 throw new IllegalArgumentException("Hook has already been added");
   109                 throw new IllegalArgumentException("Hook has already been added");
   103             }
   110             }
   104         }
   111         }
   105         he.type.setEventHook(true);
   112         he.type.setEventHook(true);
       
   113         // Insertion takes O(2*n), could be O(1) with HashMap, but
       
   114         // thinking is that CopyOnWriteArrayList is faster
       
   115         // to iterate over, which will happen more over time.
   106         entries.add(he);
   116         entries.add(he);
   107         logHook("Added", type);
   117         logHook("Added", type);
   108     }
   118     }
   109 
   119 
       
   120     public static void addTrustedJDKHook(Class<? extends Event> eventClass, Runnable runnable) {
       
   121         if (eventClass.getClassLoader() != null) {
       
   122             throw new SecurityException("Hook can only be registered for event classes that are loaded by the bootstrap class loader");
       
   123         }
       
   124         if (runnable.getClass().getClassLoader() != null) {
       
   125             throw new SecurityException("Runnable hook class must be loaded by the bootstrap class loader");
       
   126         }
       
   127         EventType eType = MetadataRepository.getInstance().getEventType(eventClass);
       
   128         PlatformEventType pType = PrivateAccess.getInstance().getPlatformEventType(eType);
       
   129         addHookInternal(null, pType, runnable);
       
   130     }
   110 
   131 
   111     private static void logHook(String action, PlatformEventType type) {
   132     private static void logHook(String action, PlatformEventType type) {
   112         if (type.isJDK() || type.isJVM()) {
   133         if (type.isJDK() || type.isJVM()) {
   113             Logger.log(LogTag.JFR_SYSTEM_EVENT, LogLevel.INFO, action + " periodic hook for " + type.getLogName());
   134             Logger.log(LogTag.JFR_SYSTEM_EVENT, LogLevel.INFO, action + " periodic hook for " + type.getLogName());
   114         } else {
   135         } else {