diff -r c401c536cea1 -r a181612f0715 src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java --- 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 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);