| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
package jdk.jfr.internal;  | 
 | 
 | 
 | 
import java.lang.reflect.Modifier;  | 
 | 
 | 
 | 
import jdk.jfr.Event;  | 
 | 
import jdk.jfr.internal.handlers.EventHandler;  | 
 | 
import jdk.jfr.internal.instrument.JDKEvents;  | 
 | 
 | 
 | 
/**  | 
 | 
 * All upcalls from the JVM should go through this class.  | 
 | 
 *  | 
 | 
 */  | 
 | 
 | 
 | 
final class JVMUpcalls { | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static byte[] onRetransform(long traceId, boolean dummy, Class<?> clazz, byte[] oldBytes) throws Throwable { | 
 | 
        try { | 
 | 
            if (Event.class.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers())) { | 
 | 
                EventHandler handler = Utils.getHandler(clazz.asSubclass(Event.class));  | 
 | 
                if (handler == null) { | 
 | 
                    Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "No event handler found for " + clazz.getName() + ". Ignoring instrumentation request.");  | 
 | 
                      | 
 | 
                    return oldBytes;  | 
 | 
                }  | 
 | 
                Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Adding instrumentation to event class " + clazz.getName() + " using retransform");  | 
 | 
                EventInstrumentation ei = new EventInstrumentation(clazz.getSuperclass(), oldBytes, traceId);  | 
 | 
                byte[] bytes = ei.buildInstrumented();  | 
 | 
                ASMToolkit.logASM(clazz.getName(), bytes);  | 
 | 
                return bytes;  | 
 | 
            }  | 
 | 
            return JDKEvents.retransformCallback(clazz, oldBytes);  | 
 | 
        } catch (Throwable t) { | 
 | 
            Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Unexpected error when adding instrumentation to event class " + clazz.getName());  | 
 | 
        }  | 
 | 
        return oldBytes;  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static byte[] bytesForEagerInstrumentation(long traceId, boolean forceInstrumentation, Class<?> superClass, byte[] oldBytes) throws Throwable { | 
 | 
        if (JVMSupport.isNotAvailable()) { | 
 | 
            return oldBytes;  | 
 | 
        }  | 
 | 
        String eventName = "<Unknown>";  | 
 | 
        try { | 
 | 
            EventInstrumentation ei = new EventInstrumentation(superClass, oldBytes, traceId);  | 
 | 
            eventName = ei.getEventName();  | 
 | 
            if (!forceInstrumentation) { | 
 | 
                  | 
 | 
                MetadataRepository mr = MetadataRepository.getInstance();  | 
 | 
                // No need to generate bytecode if:  | 
 | 
                // 1) Event class is disabled, and there is not an external configuration that overrides.  | 
 | 
                  | 
 | 
                if (!mr.isEnabled(ei.getEventName()) && !ei.isEnabled() || !ei.isRegistered()) { | 
 | 
                    Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Skipping instrumentation for event type " + eventName + " since event was disabled on class load");  | 
 | 
                    return oldBytes;  | 
 | 
                }  | 
 | 
            }  | 
 | 
            // Corner case when we are forced to generate bytecode. We can't reference the event  | 
 | 
            // handler in #isEnabled() before event class has been registered, so we add a  | 
 | 
              | 
 | 
            ei.setGuardHandler(true);  | 
 | 
            Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Adding " + (forceInstrumentation ? "forced " : "") + "instrumentation for event type " + eventName + " during initial class load");  | 
 | 
            EventHandlerCreator eh = new EventHandlerCreator(traceId, ei.getSettingInfos(), ei.getFieldInfos());  | 
 | 
            // Handler class must be loaded before instrumented event class can  | 
 | 
              | 
 | 
            eh.makeEventHandlerClass();  | 
 | 
            byte[] bytes = ei.buildInstrumented();  | 
 | 
            ASMToolkit.logASM(ei.getClassName() + "(" + traceId + ")", bytes); | 
 | 
            return bytes;  | 
 | 
        } catch (Throwable t) { | 
 | 
            Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Unexpected error when adding instrumentation for event type " + eventName);  | 
 | 
            return oldBytes;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static Thread createRecorderThread(ThreadGroup systemThreadGroup, ClassLoader contextClassLoader) { | 
 | 
        return SecuritySupport.createRecorderThread(systemThreadGroup, contextClassLoader);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    static Class<? extends EventHandler> getEventHandlerProxyClass() { | 
 | 
        return EventHandlerProxyCreator.proxyClass;  | 
 | 
    }  | 
 | 
}  |