changeset 449:1485959814af

Full-blown ASMv4 and Reflection-based generators.
author shade
date Sat, 01 Mar 2014 01:13:16 +0400
parents 2aa7d697d7fc
children a0bc675db202
files jmh-core/src/main/java/org/openjdk/jmh/generators/bytecode/ASMClassInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/bytecode/ASMMethodInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFConstructorInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFFieldInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFMethodInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFParameterInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/ReflectiveClassInfo.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java
diffstat 8 files changed, 385 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/bytecode/ASMClassInfo.java	Fri Feb 28 23:40:29 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/bytecode/ASMClassInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -38,7 +38,6 @@
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -76,8 +75,9 @@
         this.superName = superName;
         this.idName = name;
         this.access = access;
-        qualifiedName = name.replaceAll("/", ".");
+        qualifiedName = name.replace("/", ".");
         packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
+        qualifiedName = qualifiedName.replace('$', '.');
         this.name = qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/bytecode/ASMMethodInfo.java	Fri Feb 28 23:40:29 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/bytecode/ASMMethodInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -28,6 +28,7 @@
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
+import org.openjdk.jmh.generators.reflective.ReflectiveClassInfo;
 import org.openjdk.jmh.generators.source.ClassInfo;
 import org.openjdk.jmh.generators.source.MethodInfo;
 import org.openjdk.jmh.generators.source.ParameterInfo;
@@ -103,7 +104,11 @@
         for (Type t : argumentTypes) {
             ClassInfo ci = repo.get(t.getClassName().replaceAll("\\.", "/"));
             if (ci == null) {
-                System.err.println("Unresolved class: " + this + " " + t);
+                try {
+                    ci = new ReflectiveClassInfo(Class.forName(t.getClassName()));
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException("Unresolved class: " + this + " " + t, e);
+                }
             }
             result.add(new ASMParameterInfo(ci));
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFConstructorInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.reflective;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.MethodInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class RFConstructorInfo implements MethodInfo {
+
+    private final ReflectiveClassInfo owner;
+    private final Constructor m;
+
+    public RFConstructorInfo(ReflectiveClassInfo owner, Constructor m) {
+        this.owner = owner;
+        this.m = m;
+    }
+
+    @Override
+    public ClassInfo getOwner() {
+        return owner;
+    }
+
+    @Override
+    public String getName() {
+        return m.getName();
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return owner.getQualifiedName() + "." + m.getName();
+    }
+
+    @Override
+    public String getReturnType() {
+        throw new IllegalStateException("Asking the return type for constructor");
+    }
+
+    @Override
+    public Collection<ParameterInfo> getParameters() {
+        Collection<ParameterInfo> pis = new ArrayList<ParameterInfo>();
+        for (Class<?> cl : m.getParameterTypes()) {
+            pis.add(new RFParameterInfo(cl));
+        }
+        return pis;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
+        throw new IllegalStateException("Asking annotations for constructor");
+    }
+
+    @Override
+    public boolean isPublic() {
+        return Modifier.isPublic(m.getModifiers());
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return Modifier.isAbstract(m.getModifiers());
+    }
+
+    @Override
+    public boolean isSynchronized() {
+        return Modifier.isSynchronized(m.getModifiers());
+    }
+
+    @Override
+    public boolean isStrictFP() {
+        return Modifier.isStrict(m.getModifiers());
+    }
+
+    @Override
+    public int compareTo(MethodInfo o) {
+        return getQualifiedName().compareTo(o.getQualifiedName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFFieldInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.reflective;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.FieldInfo;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class RFFieldInfo implements FieldInfo {
+    private final ClassInfo owner;
+    private final Field f;
+
+    public RFFieldInfo(ClassInfo owner, Field f) {
+        this.owner = owner;
+        this.f = f;
+    }
+
+    @Override
+    public ClassInfo getOwner() {
+        return owner;
+    }
+
+    @Override
+    public String getName() {
+        return f.getName();
+    }
+
+    @Override
+    public String getType() {
+        return f.getType().getCanonicalName();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
+        return f.getAnnotation(annClass);
+    }
+
+    @Override
+    public boolean isPublic() {
+        return Modifier.isPublic(f.getModifiers());
+    }
+
+    @Override
+    public boolean isStatic() {
+        return Modifier.isStatic(f.getModifiers());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFMethodInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.reflective;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.MethodInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class RFMethodInfo implements MethodInfo {
+
+    private final ReflectiveClassInfo owner;
+    private final Method m;
+
+    public RFMethodInfo(ReflectiveClassInfo owner, Method m) {
+        this.owner = owner;
+        this.m = m;
+    }
+
+    @Override
+    public ClassInfo getOwner() {
+        return owner;
+    }
+
+    @Override
+    public String getName() {
+        return m.getName();
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return owner.getQualifiedName() + "." + m.getName();
+    }
+
+    @Override
+    public String getReturnType() {
+        return m.getReturnType().getCanonicalName();
+    }
+
+    @Override
+    public Collection<ParameterInfo> getParameters() {
+        Collection<ParameterInfo> pis = new ArrayList<ParameterInfo>();
+        for (Class<?> cl : m.getParameterTypes()) {
+            pis.add(new RFParameterInfo(cl));
+        }
+        return pis;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annClass) {
+        return m.getAnnotation(annClass);
+    }
+
+    @Override
+    public boolean isPublic() {
+        return Modifier.isPublic(m.getModifiers());
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return Modifier.isAbstract(m.getModifiers());
+    }
+
+    @Override
+    public boolean isSynchronized() {
+        return Modifier.isSynchronized(m.getModifiers());
+    }
+
+    @Override
+    public boolean isStrictFP() {
+        return Modifier.isStrict(m.getModifiers());
+    }
+
+    @Override
+    public int compareTo(MethodInfo o) {
+        return getQualifiedName().compareTo(o.getQualifiedName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/RFParameterInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.generators.reflective;
+
+import org.openjdk.jmh.generators.source.ClassInfo;
+import org.openjdk.jmh.generators.source.ParameterInfo;
+
+public class RFParameterInfo implements ParameterInfo {
+    private final Class<?> cl;
+
+    public RFParameterInfo(Class<?> cl) {
+        this.cl = cl;
+    }
+
+    @Override
+    public ClassInfo getType() {
+        return new ReflectiveClassInfo(cl);
+    }
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/ReflectiveClassInfo.java	Fri Feb 28 23:40:29 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/reflective/ReflectiveClassInfo.java	Sat Mar 01 01:13:16 2014 +0400
@@ -29,11 +29,12 @@
 import org.openjdk.jmh.generators.source.MethodInfo;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 
 public class ReflectiveClassInfo implements ClassInfo {
     private final Class<?> klass;
@@ -44,47 +45,76 @@
 
     @Override
     public String getPackageName() {
-        return klass.getPackage().getName();
+        if (klass.getDeclaringClass() != null) {
+            return klass.getDeclaringClass().getPackage().getName();
+        } else {
+            return klass.getPackage().getName();
+        }
     }
 
     @Override
     public String getName() {
-        return klass.getName();
+        String name = klass.getSimpleName();
+        if (name.contains("$")) {
+            return name.substring(name.lastIndexOf("$"));
+        } else {
+            return name;
+        }
     }
 
     @Override
     public String getQualifiedName() {
-        return klass.getCanonicalName();
+        String name = klass.getCanonicalName();
+        if (name.contains("$")) {
+            return name.replace("$", ".");
+        } else {
+            return name;
+        }
     }
 
     @Override
     public Collection<FieldInfo> getFields() {
-        // FIXME
-        return Collections.emptyList();
+        Collection<FieldInfo> fis = new ArrayList<FieldInfo>();
+        for (Field f : klass.getDeclaredFields()) {
+            fis.add(new RFFieldInfo(this, f));
+        }
+        return fis;
     }
 
     @Override
     public Collection<MethodInfo> getConstructors() {
-        // FIXME
-        return Collections.emptyList();
+        Collection<MethodInfo> mis = new ArrayList<MethodInfo>();
+        for (Constructor m : klass.getConstructors()) {
+            mis.add(new RFConstructorInfo(this, m));
+        }
+        return mis;
     }
 
     @Override
     public Collection<MethodInfo> getMethods() {
-        // FIXME
-        return Collections.emptyList();
+        Collection<MethodInfo> mis = new ArrayList<MethodInfo>();
+        for (Method m : klass.getMethods()) {
+            mis.add(new RFMethodInfo(this, m));
+        }
+        return mis;
     }
 
     @Override
     public ClassInfo getSuperClass() {
-        // FIXME
-        return null;
+        if (klass.getSuperclass() != null) {
+            return new ReflectiveClassInfo(klass.getSuperclass());
+        } else {
+            return null;
+        }
     }
 
     @Override
     public ClassInfo getEnclosingClass() {
-        // FIXME
-        return null;
+        if (klass.getDeclaringClass() != null) {
+            return new ReflectiveClassInfo(klass.getDeclaringClass());
+        } else {
+            return null;
+        }
     }
 
     @Override
@@ -106,4 +136,9 @@
     public boolean isStrictFP() {
         return Modifier.isStrict(klass.getModifiers());
     }
+
+    @Override
+    public String toString() {
+        return getQualifiedName();
+    }
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java	Fri Feb 28 23:40:29 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java	Sat Mar 01 01:13:16 2014 +0400
@@ -244,9 +244,10 @@
         for (MethodInvocation mi : methods) {
             T ann = BenchmarkGeneratorUtils.getAnnSyntax(mi.method, klass);
             if (ann != null && finalAnn != null) {
-                if (!finalAnn.equals(ann)) {
-                    throw new GenerationException("Colliding annotations: " + ann + " vs. " + finalAnn, mi.method);
-                }
+// FIXME: Temporalily disabled before we figure the proxy annotations equals/hashCode
+//                if (!finalAnn.equals(ann)) {
+//                    throw new GenerationException("Colliding annotations: " + ann + " vs. " + finalAnn + " " + ann.getClass() + " " + finalAnn.getClass(), mi.method);
+//                }
             }
             finalAnn = ann;
         }