Skip to content
This repository has been archived by the owner on Sep 13, 2024. It is now read-only.

Commit

Permalink
Further simplifications.
Browse files Browse the repository at this point in the history
  • Loading branch information
christianhaeubl committed Apr 27, 2023
1 parent ab452d6 commit 92159f7
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,12 @@
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.TargetClass;

import jdk.jfr.events.ActiveRecordingEvent;
import jdk.jfr.events.ActiveSettingEvent;
import jdk.jfr.events.ErrorThrownEvent;
import jdk.jfr.events.ExceptionStatisticsEvent;
import jdk.jfr.events.ExceptionThrownEvent;
import jdk.jfr.events.FileForceEvent;
import jdk.jfr.events.FileReadEvent;
import jdk.jfr.events.FileWriteEvent;
import jdk.jfr.events.SocketReadEvent;
import jdk.jfr.events.SocketWriteEvent;

@TargetClass(className = "jdk.jfr.internal.instrument.JDKEvents", onlyWith = HasJfrSupport.class)
final class Target_jdk_jfr_internal_instrument_JDKEvents {

@Alias //
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true) private static Class<?>[] eventClasses = {
FileForceEvent.class,
FileReadEvent.class,
FileWriteEvent.class,
SocketReadEvent.class,
SocketWriteEvent.class,
ExceptionThrownEvent.class,
ExceptionStatisticsEvent.class,
ErrorThrownEvent.class,
ActiveSettingEvent.class,
ActiveRecordingEvent.class,
};

/*
* This is a list of the classes with instrumentation code that should be applied. In Native
* Image, instrumentation code is applied during the image build.
*/
@Alias //
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true) private static Class<?>[] instrumentationClasses = new Class<?>[]{};

@Alias //
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true) private static Class<?>[] mirrorEventClasses = new Class<?>[]{};
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,15 @@
*/
package com.oracle.svm.hosted.jfr;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

import org.graalvm.collections.EconomicMap;
import org.graalvm.nativeimage.AnnotationAccess;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider;
import com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor;
import com.oracle.svm.core.jfr.JfrJavaEvents;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.util.ReflectionUtil;

import jdk.jfr.internal.JVM;
import jdk.jfr.internal.SecuritySupport;
Expand All @@ -58,21 +53,19 @@ public class JfrEventSubstitution extends SubstitutionProcessor {
private final ConcurrentHashMap<ResolvedJavaType, Boolean> typeSubstitution;
private final ConcurrentHashMap<ResolvedJavaMethod, ResolvedJavaMethod> methodSubstitutions;
private final ConcurrentHashMap<ResolvedJavaField, ResolvedJavaField> fieldSubstitutions;
private final EconomicMap<String, Class<? extends jdk.jfr.Event>> mirrorEventMapping;

JfrEventSubstitution(MetaAccessProvider metaAccess) {
baseEventType = metaAccess.lookupJavaType(jdk.internal.event.Event.class);
typeSubstitution = new ConcurrentHashMap<>();
methodSubstitutions = new ConcurrentHashMap<>();
fieldSubstitutions = new ConcurrentHashMap<>();
mirrorEventMapping = createMirrorEventsMapping();
}

@Override
public ResolvedJavaField lookup(ResolvedJavaField field) {
ResolvedJavaType type = field.getDeclaringClass();
if (needsClassRedefinition(type)) {
typeSubstitution.computeIfAbsent(type, this::initEventClass);
typeSubstitution.computeIfAbsent(type, JfrEventSubstitution::initEventClass);
return fieldSubstitutions.computeIfAbsent(field, JfrEventSubstitution::initEventField);
}
return field;
Expand All @@ -82,7 +75,7 @@ public ResolvedJavaField lookup(ResolvedJavaField field) {
public ResolvedJavaMethod lookup(ResolvedJavaMethod method) {
ResolvedJavaType type = method.getDeclaringClass();
if (needsClassRedefinition(type)) {
typeSubstitution.computeIfAbsent(type, this::initEventClass);
typeSubstitution.computeIfAbsent(type, JfrEventSubstitution::initEventClass);
return methodSubstitutions.computeIfAbsent(method, JfrEventSubstitution::initEventMethod);
}
return method;
Expand All @@ -91,7 +84,7 @@ public ResolvedJavaMethod lookup(ResolvedJavaMethod method) {
@Override
public ResolvedJavaType lookup(ResolvedJavaType type) {
if (needsClassRedefinition(type)) {
typeSubstitution.computeIfAbsent(type, this::initEventClass);
typeSubstitution.computeIfAbsent(type, JfrEventSubstitution::initEventClass);
}
return type;
}
Expand Down Expand Up @@ -137,22 +130,19 @@ private static ResolvedJavaMethod initEventMethod(ResolvedJavaMethod oldMethod)
throw VMError.shouldNotReachHere("Could not re-resolve method: " + oldMethod);
}

private Boolean initEventClass(ResolvedJavaType eventType) throws RuntimeException {
private static Boolean initEventClass(ResolvedJavaType eventType) throws RuntimeException {
try {
Class<? extends jdk.internal.event.Event> newEventClass = OriginalClassProvider.getJavaClass(eventType).asSubclass(jdk.internal.event.Event.class);
eventType.initialize();

// It is crucial that mirror events are registered before the actual events.
Class<? extends jdk.jfr.Event> mirrorEventClass = mirrorEventMapping.get(newEventClass.getName());
if (mirrorEventClass != null) {
SecuritySupport.registerMirror(mirrorEventClass);
}

SecuritySupport.registerEvent(newEventClass);

JfrJavaEvents.registerEventClass(newEventClass);
// the reflection registration for the event handler field is delayed to the JfrFeature
// duringAnalysis callback so it does not race/interfere with other retransforms

/*
* The reflection registration for the event handler field is delayed to the
* JfrEventFeature.duringAnalysis, so that it does not race/interfere with other
* retransforms.
*/
JVM.getJVM().retransformClasses(new Class<?>[]{newEventClass});
return Boolean.TRUE;
} catch (Throwable ex) {
Expand All @@ -163,29 +153,4 @@ private Boolean initEventClass(ResolvedJavaType eventType) throws RuntimeExcepti
private boolean needsClassRedefinition(ResolvedJavaType type) {
return !type.isAbstract() && baseEventType.isAssignableFrom(type) && !baseEventType.equals(type);
}

/*
* Mirror events contain the JFR-specific annotations. The mirrored event does not have any
* dependency on JFR-specific classes. If the mirrored event is used, we must ensure that the
* mirror event is registered as well. Otherwise, incorrect JFR metadata would be emitted.
*/
@SuppressWarnings("unchecked")
private static EconomicMap<String, Class<? extends jdk.jfr.Event>> createMirrorEventsMapping() {
EconomicMap<String, Class<? extends jdk.jfr.Event>> result = EconomicMap.create();
Class<? extends Annotation> mirrorEventAnnotationClass = (Class<? extends Annotation>) ReflectionUtil.lookupClass(false, "jdk.jfr.internal.MirrorEvent");
Class<?> jdkEventsClass = ReflectionUtil.lookupClass(false, "jdk.jfr.internal.instrument.JDKEvents");
Class<?>[] mirrorEventClasses = ReflectionUtil.readStaticField(jdkEventsClass, "mirrorEventClasses");
for (int i = 0; i < mirrorEventClasses.length; i++) {
Class<? extends jdk.jfr.Event> mirrorEventClass = (Class<? extends jdk.jfr.Event>) mirrorEventClasses[i];
Annotation mirrorEvent = AnnotationAccess.getAnnotation(mirrorEventClass, mirrorEventAnnotationClass);
Method m = ReflectionUtil.lookupMethod(mirrorEventAnnotationClass, "className");
try {
String className = (String) m.invoke(mirrorEvent);
result.put(className, mirrorEventClass);
} catch (Exception e) {
throw VMError.shouldNotReachHere(e);
}
}
return result;
}
}

0 comments on commit 92159f7

Please sign in to comment.