src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java
changeset 52334 a181612f0715
parent 50745 a390cbb82d47
child 52850 f527b24990d7
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java	Tue Oct 30 15:17:58 2018 -0700
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java	Wed Oct 31 02:10:21 2018 +0100
@@ -267,7 +267,7 @@
         return (long) (nanos * JVM.getJVM().getTimeConversionFactor());
     }
 
-    static synchronized EventHandler getHandler(Class<? extends Event> eventClass) {
+    static synchronized EventHandler getHandler(Class<? extends jdk.internal.event.Event> eventClass) {
         Utils.ensureValidEventSubclass(eventClass);
         try {
             Field f = eventClass.getDeclaredField(EventInstrumentation.FIELD_EVENT_HANDLER);
@@ -278,7 +278,7 @@
         }
     }
 
-    static synchronized void setHandler(Class<? extends Event> eventClass, EventHandler handler) {
+    static synchronized void setHandler(Class<? extends jdk.internal.event.Event> eventClass, EventHandler handler) {
         Utils.ensureValidEventSubclass(eventClass);
         try {
             Field field = eventClass.getDeclaredField(EventInstrumentation.FIELD_EVENT_HANDLER);
@@ -322,7 +322,7 @@
     static List<Field> getVisibleEventFields(Class<?> clazz) {
         Utils.ensureValidEventSubclass(clazz);
         List<Field> fields = new ArrayList<>();
-        for (Class<?> c = clazz; c != Event.class; c = c.getSuperclass()) {
+        for (Class<?> c = clazz; c != jdk.internal.event.Event.class; c = c.getSuperclass()) {
             for (Field field : c.getDeclaredFields()) {
                 // skip private field in base classes
                 if (c == clazz || !Modifier.isPrivate(field.getModifiers())) {
@@ -334,10 +334,10 @@
     }
 
     public static void ensureValidEventSubclass(Class<?> eventClass) {
-        if (Event.class.isAssignableFrom(eventClass) && Modifier.isAbstract(eventClass.getModifiers())) {
+        if (jdk.internal.event.Event.class.isAssignableFrom(eventClass) && Modifier.isAbstract(eventClass.getModifiers())) {
             throw new IllegalArgumentException("Abstract event classes are not allowed");
         }
-        if (eventClass == Event.class || !Event.class.isAssignableFrom(eventClass)) {
+        if (eventClass == Event.class || eventClass == jdk.internal.event.Event.class || !jdk.internal.event.Event.class.isAssignableFrom(eventClass)) {
             throw new IllegalArgumentException("Must be a subclass to " + Event.class.getName());
         }
     }
@@ -366,7 +366,7 @@
         }
     }
 
-    public static void ensureInitialized(Class<? extends Event> eventClass) {
+    public static void ensureInitialized(Class<? extends jdk.internal.event.Event> eventClass) {
         SecuritySupport.ensureClassIsInitialized(eventClass);
     }
 
@@ -499,6 +499,50 @@
         return eventName;
     }
 
+    public static void verifyMirror(Class<?> mirror, Class<?> real) {
+        Class<?> cMirror = Objects.requireNonNull(mirror);
+        Class<?> cReal = Objects.requireNonNull(real);
+
+        while (cReal != null) {
+            Map<String, Field> mirrorFields = new HashMap<>();
+            if (cMirror != null) {
+                for (Field f : cMirror.getDeclaredFields()) {
+                    if (isSupportedType(f.getType())) {
+                        mirrorFields.put(f.getName(), f);
+                    }
+                }
+            }
+            for (Field realField : cReal.getDeclaredFields()) {
+                if (isSupportedType(realField.getType())) {
+                    String fieldName = realField.getName();
+                    Field mirrorField = mirrorFields.get(fieldName);
+                    if (mirrorField == null) {
+                        throw new InternalError("Missing mirror field for " + cReal.getName() + "#" + fieldName);
+                    }
+                    if (realField.getModifiers() != mirrorField.getModifiers()) {
+                        throw new InternalError("Incorrect modifier for mirror field "+ cMirror.getName() + "#" + fieldName);
+                    }
+                    mirrorFields.remove(fieldName);
+                }
+            }
+            if (!mirrorFields.isEmpty()) {
+                throw new InternalError(
+                        "Found additional fields in mirror class " + cMirror.getName() + " " + mirrorFields.keySet());
+            }
+            if (cMirror != null) {
+                cMirror = cMirror.getSuperclass();
+            }
+            cReal = cReal.getSuperclass();
+        }
+    }
+
+    private static boolean isSupportedType(Class<?> type) {
+        if (Modifier.isTransient(type.getModifiers()) || Modifier.isStatic(type.getModifiers())) {
+            return false;
+        }
+        return Type.isValidJavaFieldType(type.getName());
+    }
+
     public static String makeFilename(Recording recording) {
         String pid = JVM.getJVM().getPid();
         String date = Repository.REPO_DATE_FORMAT.format(LocalDateTime.now());