src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java
changeset 52334 a181612f0715
parent 50113 caf115bb98ad
child 52698 ca6b58b8ffc5
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java	Tue Oct 30 15:17:58 2018 -0700
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java	Wed Oct 31 02:10:21 2018 +0100
@@ -102,6 +102,7 @@
     private static final Type ANNOTATION_TYPE_ENABLED = Type.getType(Enabled.class);
     private static final Type TYPE_EVENT_HANDLER = Type.getType(EventHandler.class);
     private static final Type TYPE_SETTING_CONTROL = Type.getType(SettingControl.class);
+    private static final Type TYPE_OBJECT  = Type.getType(Object.class);
     private static final Method METHOD_COMMIT = new Method("commit", Type.VOID_TYPE, new Type[0]);
     private static final Method METHOD_BEGIN = new Method("begin", Type.VOID_TYPE, new Type[0]);
     private static final Method METHOD_END = new Method("end", Type.VOID_TYPE, new Type[0]);
@@ -117,6 +118,7 @@
     private final Method writeMethod;
     private final String eventHandlerXInternalName;
     private final String eventName;
+    private final boolean untypedEventHandler;
     private boolean guardHandlerReference;
     private Class<?> superClass;
 
@@ -125,11 +127,20 @@
         this.classNode = createClassNode(bytes);
         this.settingInfos = buildSettingInfos(superClass, classNode);
         this.fieldInfos = buildFieldInfos(superClass, classNode);
+        this.untypedEventHandler = hasUntypedHandler();
         this.writeMethod = makeWriteMethod(fieldInfos);
         this.eventHandlerXInternalName = ASMToolkit.getInternalName(EventHandlerCreator.makeEventHandlerName(id));
         String n =  annotationValue(classNode, ANNOTATION_TYPE_NAME.getDescriptor(), String.class);
         this.eventName = n == null ? classNode.name.replace("/", ".") : n;
+    }
 
+    private boolean hasUntypedHandler() {
+        for (FieldNode field : classNode.fields) {
+            if (FIELD_EVENT_HANDLER.equals(field.name)) {
+                return field.desc.equals(TYPE_OBJECT.getDescriptor());
+            }
+        }
+        throw new InternalError("Class missing handler field");
     }
 
     public String getClassName() {
@@ -225,7 +236,7 @@
                 }
             }
         }
-        for (Class<?> c = superClass; c != Event.class; c = c.getSuperclass()) {
+        for (Class<?> c = superClass; c != jdk.internal.event.Event.class; c = c.getSuperclass()) {
             for (java.lang.reflect.Method method : c.getDeclaredMethods()) {
                 if (!methodSet.contains(method.getName())) {
                     // skip private method in base classes
@@ -249,7 +260,6 @@
             }
         }
         return settingInfos;
-
     }
 
     private static List<FieldInfo> buildFieldInfos(Class<?> superClass, ClassNode classNode) {
@@ -264,14 +274,13 @@
         fieldInfos.add(new FieldInfo("startTime", Type.LONG_TYPE.getDescriptor(), classNode.name));
         fieldInfos.add(new FieldInfo("duration", Type.LONG_TYPE.getDescriptor(), classNode.name));
         for (FieldNode field : classNode.fields) {
-            String className = Type.getType(field.desc).getClassName();
-            if (!fieldSet.contains(field.name) && isValidField(field.access, className)) {
+            if (!fieldSet.contains(field.name) && isValidField(field.access, Type.getType(field.desc).getClassName())) {
                 FieldInfo fi = new FieldInfo(field.name, field.desc, classNode.name);
                 fieldInfos.add(fi);
                 fieldSet.add(field.name);
             }
         }
-        for (Class<?> c = superClass; c != Event.class; c = c.getSuperclass()) {
+        for (Class<?> c = superClass; c != jdk.internal.event.Event.class; c = c.getSuperclass()) {
             for (Field field : c.getDeclaredFields()) {
                 // skip private field in base classes
                 if (!Modifier.isPrivate(field.getModifiers())) {
@@ -321,10 +330,10 @@
         updateMethod(METHOD_IS_ENABLED, methodVisitor -> {
             Label nullLabel = new Label();
             if (guardHandlerReference) {
-                methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, TYPE_EVENT_HANDLER.getDescriptor());
+                getEventHandler(methodVisitor);
                 methodVisitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);
             }
-            methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, TYPE_EVENT_HANDLER.getDescriptor());
+            getEventHandler(methodVisitor);
             ASMToolkit.invokeVirtual(methodVisitor, TYPE_EVENT_HANDLER.getInternalName(), METHOD_IS_ENABLED);
             methodVisitor.visitInsn(Opcodes.IRETURN);
             if (guardHandlerReference) {
@@ -408,7 +417,7 @@
                 // eventHandler.write(...);
                 // }
                 methodVisitor.visitJumpInsn(Opcodes.IFEQ, end);
-                methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, Type.getDescriptor(EventHandler.class));
+                getEventHandler(methodVisitor);
 
                 methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, eventHandlerXInternalName);
                 for (FieldInfo fi : fieldInfos) {
@@ -426,8 +435,8 @@
         // MyEvent#shouldCommit()
         updateMethod(METHOD_EVENT_SHOULD_COMMIT, methodVisitor -> {
             Label fail = new Label();
-            // if (!eventHandler.shoouldCommit(duration) goto fail;
-            methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, Type.getDescriptor(EventHandler.class));
+            // if (!eventHandler.shouldCommit(duration) goto fail;
+            getEventHandler(methodVisitor);
             methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
             methodVisitor.visitFieldInsn(Opcodes.GETFIELD, getInternalClassName(), FIELD_DURATION, "J");
             ASMToolkit.invokeVirtual(methodVisitor, TYPE_EVENT_HANDLER.getInternalName(), METHOD_EVENT_HANDLER_SHOULD_COMMIT);
@@ -435,7 +444,11 @@
             for (SettingInfo si : settingInfos) {
                 // if (!settingsMethod(eventHandler.settingX)) goto fail;
                 methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
-                methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, Type.getDescriptor(EventHandler.class));
+                if (untypedEventHandler) {
+                    methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, TYPE_OBJECT.getDescriptor());
+                } else {
+                    methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, Type.getDescriptor(EventHandler.class));
+                }
                 methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, eventHandlerXInternalName);
                 methodVisitor.visitFieldInsn(Opcodes.GETFIELD, eventHandlerXInternalName, si.fieldName, TYPE_SETTING_CONTROL.getDescriptor());
                 methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, si.internalSettingName);
@@ -452,6 +465,15 @@
         });
     }
 
+    private void getEventHandler(MethodVisitor methodVisitor) {
+        if (untypedEventHandler) {
+            methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, TYPE_OBJECT.getDescriptor());
+            methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, TYPE_EVENT_HANDLER.getInternalName());
+        } else {
+            methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, getInternalClassName(), FIELD_EVENT_HANDLER, Type.getDescriptor(EventHandler.class));
+        }
+    }
+
     private void makeUninstrumented() {
         updateExistingWithReturnFalse(METHOD_EVENT_SHOULD_COMMIT);
         updateExistingWithReturnFalse(METHOD_IS_ENABLED);