changeset 443:e574a5c575bb

@Param initializers should be usable in subclasses: track the class-field mappings more carefully.
author shade
date Fri, 28 Feb 2014 16:45:39 +0400
parents 0b204ee93eaf
children 94062407bac0
files jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGenerator.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGeneratorUtils.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/HelperMethodValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/ParamValidationPlugin.java jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java jmh-core/src/main/java/org/openjdk/jmh/generators/source/StateObject.java
diffstat 7 files changed, 49 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGenerator.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGenerator.java	Fri Feb 28 16:45:39 2014 +0400
@@ -214,7 +214,7 @@
         // validate all arguments are @State-s
         for (MethodInfo e : methods) {
             for (ParameterInfo var : e.getParameters()) {
-                if (BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(var.getType(), State.class) == null) {
+                if (BenchmarkGeneratorUtils.getAnnSuper(var.getType(), State.class) == null) {
                     throw new GenerationException(
                             "Method parameters should be @" + State.class.getSimpleName() + " classes.",
                             e);
@@ -224,7 +224,7 @@
         }
 
         // validate if enclosing class is implicit @State
-        if (BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(clazz, State.class) != null) {
+        if (BenchmarkGeneratorUtils.getAnnSuper(clazz, State.class) != null) {
             states.add(clazz);
         }
 
@@ -234,7 +234,7 @@
             // we need to preemptively check the annotation value, and
             // the API can only allow that by catching the exception, argh.
             try {
-                BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(state, State.class).value();
+                BenchmarkGeneratorUtils.getAnnSuper(state, State.class).value();
             } catch (IncompleteAnnotationException iae) {
                 throw new GenerationException("The " + State.class.getSimpleName() +
                         " annotation should have the explicit " + Scope.class.getSimpleName() + " argument",
@@ -260,7 +260,7 @@
         }
 
         // validate against rogue fields
-        if (BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(clazz, State.class) == null || clazz.isAbstract()) {
+        if (BenchmarkGeneratorUtils.getAnnSuper(clazz, State.class) == null || clazz.isAbstract()) {
             for (FieldInfo fi : BenchmarkGeneratorUtils.getAllFields(clazz)) {
                 // allow static fields
                 if (fi.isStatic()) continue;
@@ -283,7 +283,7 @@
                         + " method can not be abstract.", m);
             }
             if (m.isSynchronized()) {
-                if (BenchmarkGeneratorUtils.getAnnotationRecursive(m, State.class) == null) {
+                if (BenchmarkGeneratorUtils.getAnnSyntax(m, State.class) == null) {
                     throw new GenerationException("@" + GenerateMicroBenchmark.class.getSimpleName()
                             + " method can only be synchronized if the enclosing class is annotated with "
                             + "@" + State.class.getSimpleName() + ".", m);
@@ -293,7 +293,7 @@
 
         // check annotations
         for (MethodInfo m : methods) {
-            OperationsPerInvocation opi = BenchmarkGeneratorUtils.getAnnotationRecursive(m, OperationsPerInvocation.class);
+            OperationsPerInvocation opi = BenchmarkGeneratorUtils.getAnnSyntax(m, OperationsPerInvocation.class);
             if (opi != null && opi.value() < 1) {
                 throw new GenerationException("The " + OperationsPerInvocation.class.getSimpleName() +
                         " needs to be greater than 0.", m);
@@ -314,7 +314,7 @@
                 MethodInfo meth = group.methods().iterator().next();
                 if (meth.getAnnotation(Group.class) == null) {
                     for (ParameterInfo param : meth.getParameters()) {
-                        State stateAnn = BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(param.getType(), State.class);
+                        State stateAnn = BenchmarkGeneratorUtils.getAnnSuper(param.getType(), State.class);
                         if (stateAnn != null && stateAnn.value() == Scope.Group) {
                             throw new GenerationException(
                                     "Only @" + Group.class.getSimpleName() + " methods can reference @" + State.class.getSimpleName()
@@ -323,7 +323,7 @@
                         }
                     }
 
-                    State stateAnn = BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(meth.getOwner(), State.class);
+                    State stateAnn = BenchmarkGeneratorUtils.getAnnSuper(meth.getOwner(), State.class);
                     if (stateAnn != null && stateAnn.value() == Scope.Group) {
                         throw new GenerationException(
                                 "Only @" + Group.class.getSimpleName() + " methods can implicitly reference @" + State.class.getSimpleName()
@@ -369,7 +369,7 @@
                 result.put(groupName, group);
             }
 
-            BenchmarkMode mbAn = BenchmarkGeneratorUtils.getAnnotationRecursive(method, BenchmarkMode.class);
+            BenchmarkMode mbAn = BenchmarkGeneratorUtils.getAnnSyntax(method, BenchmarkMode.class);
             if (mbAn != null) {
                 group.addModes(mbAn.value());
             }
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGeneratorUtils.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/BenchmarkGeneratorUtils.java	Fri Feb 28 16:45:39 2014 +0400
@@ -86,38 +86,38 @@
         return ls;
     }
 
-    public static <T extends Annotation> T getAnnotationRecursiveSuper(ClassInfo ci, Class<T> annClass) {
+    public static <T extends Annotation> T getAnnSuper(ClassInfo ci, Class<T> annClass) {
         T ann = ci.getAnnotation(annClass);
         if (ann != null) {
             return ann;
         } else {
             ClassInfo eci = ci.getSuperclass();
             if (eci != null) {
-                return getAnnotationRecursive(eci, annClass);
+                return getAnnSuper(eci, annClass);
             }
         }
         return null;
     }
 
-    public static <T extends Annotation> T getAnnotationRecursive(ClassInfo ci, Class<T> annClass) {
+    public static <T extends Annotation> T getAnnSyntax(ClassInfo ci, Class<T> annClass) {
         T ann = ci.getAnnotation(annClass);
         if (ann != null) {
             return ann;
         } else {
             ClassInfo eci = ci.getEnclosingClass();
             if (eci != null) {
-                return getAnnotationRecursive(eci, annClass);
+                return getAnnSyntax(eci, annClass);
             }
         }
         return null;
     }
 
-    public static <T extends Annotation> T getAnnotationRecursive(MethodInfo mi, Class<T> annClass) {
+    public static <T extends Annotation> T getAnnSyntax(MethodInfo mi, Class<T> annClass) {
         T ann = mi.getAnnotation(annClass);
         if (ann != null) {
             return ann;
         } else {
-            return getAnnotationRecursive(mi.getOwner(), annClass);
+            return getAnnSyntax(mi.getOwner(), annClass);
         }
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/HelperMethodValidationPlugin.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/HelperMethodValidationPlugin.java	Fri Feb 28 16:45:39 2014 +0400
@@ -37,7 +37,7 @@
         try {
             for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, Setup.class)) {
                 // OK to have these annotation for @State objects
-                if (BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(element.getOwner(), State.class) != null) continue;
+                if (BenchmarkGeneratorUtils.getAnnSuper(element.getOwner(), State.class) != null) continue;
 
                 // Abstract classes are not instantiated, assume OK
                 if (element.getOwner().isAbstract()) continue;
@@ -51,7 +51,7 @@
 
             for (MethodInfo element : BenchmarkGeneratorUtils.getMethodsAnnotatedWith(source, TearDown.class)) {
                 // OK to have these annotation for @State objects
-                if (BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(element.getOwner(), State.class) != null) continue;
+                if (BenchmarkGeneratorUtils.getAnnSuper(element.getOwner(), State.class) != null) continue;
 
                 // Abstract classes are not instantiated, assume OK
                 if (element.getOwner().isAbstract()) continue;
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/ParamValidationPlugin.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/ParamValidationPlugin.java	Fri Feb 28 16:45:39 2014 +0400
@@ -42,7 +42,7 @@
                     );
                 }
 
-                if (BenchmarkGeneratorUtils.getAnnotationRecursive(element.getOwner(), State.class) == null) {
+                if (BenchmarkGeneratorUtils.getAnnSyntax(element.getOwner(), State.class) == null) {
                     source.printError(
                             "@" + Param.class.getSimpleName() + " annotation should be placed in @" + State.class.getSimpleName() +
                                     "-annotated class.",
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/core/StateObjectHandler.java	Fri Feb 28 16:45:39 2014 +0400
@@ -99,7 +99,7 @@
     }
 
     public void bindArg(MethodInfo mi, ParameterInfo pi) {
-        State ann = BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(pi.getType(), State.class);
+        State ann = BenchmarkGeneratorUtils.getAnnSuper(pi.getType(), State.class);
         if (ann != null) {
             bindState(mi, pi.getType(), ann.value(), null);
         } else {
@@ -112,7 +112,7 @@
     }
 
     public void bindImplicit(ClassInfo ci, String label, Scope scope) {
-        State ann = BenchmarkGeneratorUtils.getAnnotationRecursiveSuper(ci, State.class);
+        State ann = BenchmarkGeneratorUtils.getAnnSuper(ci, State.class);
         bindState(null, ci, (ann != null) ? ann.value() : scope, label);
     }
 
@@ -391,10 +391,9 @@
             result.add("        if (!" + so.fieldIdentifier + ".ready" + Level.Trial + ") {");
             if (!so.getParamsLabels().isEmpty()) {
                 result.add("            Field f;");
-                result.add("            Class c = " + so.userType + ".class;");
             }
             for (String paramName : so.getParamsLabels()) {
-                result.add("            f = c.getDeclaredField(\"" + paramName + "\");");
+                result.add("            f = " + so.getParam(paramName).getOwner().getQualifiedName() + ".class.getDeclaredField(\"" + paramName + "\");");
                 result.add("            f.setAccessible(true);");
                 result.add("            f.set(" + so.fieldIdentifier + ", " + so.getParamAccessor(paramName) + ");");
             }
@@ -419,11 +418,10 @@
             result.add(so.type + " tryInit_" + so.fieldIdentifier + "(InfraControl control, " + so.type + " val) throws Throwable {");
             result.add("    if (" + so.fieldIdentifier + " == null) {");
             if (!so.getParamsLabels().isEmpty()) {
-                result.add("        Field f;");
-                result.add("        Class c = " + so.userType + ".class;");
+                result.add("            Field f;");
             }
             for (String paramName : so.getParamsLabels()) {
-                result.add("        f = c.getDeclaredField(\"" + paramName + "\");");
+                result.add("        f = " + so.getParam(paramName).getOwner().getQualifiedName() + ".class.getDeclaredField(\"" + paramName + "\");");
                 result.add("        f.setAccessible(true);");
                 result.add("        f.set(val, " + so.getParamAccessor(paramName) + ");");
             }
@@ -455,10 +453,10 @@
             result.add("        if (!local.ready" + Level.Trial + ") {");
             if (!so.getParamsLabels().isEmpty()) {
                 result.add("            Field f;");
-                result.add("            Class c = " + so.userType + ".class;");
             }
             for (String paramName : so.getParamsLabels()) {
-                result.add("            f = c.getDeclaredField(\"" + paramName + "\");");
+                result.add("            f = " + so.getParam(paramName).getOwner().getQualifiedName() + ".class.getDeclaredField(\"" + paramName + "\");");
+                result.add("            f.setAccessible(true);");
                 result.add("            f.setAccessible(true);");
                 result.add("            f.set(local, " + so.getParamAccessor(paramName) + ");");
             }
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/MethodGroup.java	Fri Feb 28 16:45:39 2014 +0400
@@ -242,7 +242,7 @@
     private <T extends Annotation> T getFinal(Class<T> klass) {
         T finalAnn = null;
         for (MethodInvocation mi : methods) {
-            T ann = BenchmarkGeneratorUtils.getAnnotationRecursive(mi.method, klass);
+            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);
--- a/jmh-core/src/main/java/org/openjdk/jmh/generators/source/StateObject.java	Fri Feb 28 16:24:44 2014 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/generators/source/StateObject.java	Fri Feb 28 16:45:39 2014 +0400
@@ -45,7 +45,7 @@
     public final Scope scope;
     public final String localIdentifier;
     public final String fieldIdentifier;
-    public final Map<String, String> params;
+    public final Map<String, FieldInfo> params;
 
     public StateObject(String userType, String jmhType, Scope scope, String fieldIdentifier, String localIdentifier) {
         this.userType = userType;
@@ -53,7 +53,7 @@
         this.scope = scope;
         this.localIdentifier = localIdentifier;
         this.fieldIdentifier = fieldIdentifier;
-        this.params = new TreeMap<String, String>();
+        this.params = new TreeMap<String, FieldInfo>();
     }
 
     @Override
@@ -87,53 +87,49 @@
         return localIdentifier;
     }
 
-    public String getParamAccessor(String name) {
+    public Collection<String> getParamsLabels() {
+        return params.keySet();
+    }
+
+    public void addParam(FieldInfo fieldInfo) {
+        params.put(fieldInfo.getName(), fieldInfo);
+    }
+
+    public FieldInfo getParam(String name) {
         return params.get(name);
     }
 
-    public void addParam(FieldInfo fieldInfo) {
-        String type = fieldInfo.getType();
-        String name = fieldInfo.getName();
+    public String getParamAccessor(String name) {
+        String type = params.get(name).getType();
+
         if (type.equalsIgnoreCase("java.lang.String")) {
-            params.put(name, "control.getParam(\"" + name + "\")");
-            return;
+            return "control.getParam(\"" + name + "\")";
         }
         if (type.equalsIgnoreCase("boolean") || type.equalsIgnoreCase("java.lang.Boolean")) {
-            params.put(name, "Boolean.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Boolean.valueOf(control.getParam(\"" + name + "\"))";
         }
         if (type.equalsIgnoreCase("byte") || type.equalsIgnoreCase("java.lang.Byte")) {
-            params.put(name, "Byte.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Byte.valueOf(control.getParam(\"" + name + "\"))";
         }
         if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("java.lang.Character")) {
-            params.put(name, "(control.getParam(\"" + name + "\")).charAt(0)");
-            return;
+            return "(control.getParam(\"" + name + "\")).charAt(0)";
         }
         if (type.equalsIgnoreCase("short") || type.equalsIgnoreCase("java.lang.Short")) {
-            params.put(name, "Short.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Short.valueOf(control.getParam(\"" + name + "\"))";
         }
         if (type.equalsIgnoreCase("int") || type.equalsIgnoreCase("java.lang.Integer")) {
-            params.put(name, "Integer.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Integer.valueOf(control.getParam(\"" + name + "\"))";
         }
         if (type.equalsIgnoreCase("float") || type.equalsIgnoreCase("java.lang.Float")) {
-            params.put(name, "Float.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Float.valueOf(control.getParam(\"" + name + "\"))";
         }
         if (type.equalsIgnoreCase("long") || type.equalsIgnoreCase("java.lang.Long")) {
-            params.put(name, "Long.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Long.valueOf(control.getParam(\"" + name + "\"))";
         }
         if (type.equalsIgnoreCase("double") || type.equalsIgnoreCase("java.lang.Double")) {
-            params.put(name, "Double.valueOf(control.getParam(\"" + name + "\"))");
-            return;
+            return "Double.valueOf(control.getParam(\"" + name + "\"))";
         }
         throw new IllegalStateException("Unknown type: " + type);
     }
 
-    public Collection<String> getParamsLabels() {
-        return params.keySet();
-    }
 }