changeset 71:d1e165fb0892

jmh-core: @GMB -> @BenchmarkMode
author shade
date Tue, 04 Jun 2013 13:28:58 +0400
parents 8e00ee4713e8
children 17dd93b91f6d
files jmh-core/src/main/java/org/openjdk/jmh/annotations/BenchmarkMode.java jmh-core/src/main/java/org/openjdk/jmh/annotations/BenchmarkType.java jmh-core/src/main/java/org/openjdk/jmh/annotations/DefaultMode.java jmh-core/src/main/java/org/openjdk/jmh/annotations/GenerateMicroBenchmark.java jmh-core/src/main/java/org/openjdk/jmh/logic/results/IterationData.java jmh-core/src/main/java/org/openjdk/jmh/output/format/CsvFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/format/OutputFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/format/PrettyPrintFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/format/SilentFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/format/TextReportFormat.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerateMicroBenchmarkProcessor.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodGroup.java jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MicroBenchmarkProcessor.java jmh-core/src/main/java/org/openjdk/jmh/runner/BaseMicroBenchmarkHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/BaseRunner.java jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkRecord.java jmh-core/src/main/java/org/openjdk/jmh/runner/ForkedRunner.java jmh-core/src/main/java/org/openjdk/jmh/runner/LoopMicroBenchmarkHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkHandlers.java jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkList.java jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java jmh-core/src/main/java/org/openjdk/jmh/runner/ShotMicroBenchmarkHandler.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/BaseOptions.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/HarnessOptions.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/BenchmarkTypeOptionHandler.java jmh-core/src/test/java/org/openjdk/jmh/runner/TestMicroBenchmarkList.java jmh-core/src/test/resources/org/openjdk/jmh/runner/MicroBenchmarks
diffstat 28 files changed, 582 insertions(+), 290 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/annotations/BenchmarkMode.java	Tue Jun 04 13:28:58 2013 +0400
@@ -0,0 +1,34 @@
+/**
+ * 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.annotations;
+
+/**
+ * Annotations declares the default mode in which benchmark should be run.
+ */
+public @interface BenchmarkMode {
+
+    BenchmarkType value();
+
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/annotations/BenchmarkType.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/annotations/BenchmarkType.java	Tue Jun 04 13:28:58 2013 +0400
@@ -24,6 +24,9 @@
  */
 package org.openjdk.jmh.annotations;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Benchmark type.
  *
@@ -36,30 +39,82 @@
     /**
      * Operations per unit of time,
      * {@link org.openjdk.jmh.logic.results.OpsPerTimeUnit}. */
-    OpsPerTimeUnit,
+    OpsPerTimeUnit("thrpt", "Throughput, ops/time"),
 
     /**
      * Average time per operation
      * {@link org.openjdk.jmh.logic.results.AverageTimePerOp}.
      */
-    AverageTimePerOp,
+    AverageTimePerOp("avgt", "Average time, time/op"),
 
     /**
      * Time distribution, percentile estimation
      * {@link org.openjdk.jmh.logic.results.SampleTimePerOp}.
      */
-    SampleTimePerOp,
+    SampleTimePerOp("sample", "Sampling time"),
 
     /**
      * Time the single execution
      * {@link org.openjdk.jmh.logic.results.SingleShotTime}.
      */
-    SingleShotTime,
+    SingleShotTime("ss", "Single shot invocation time"),
 
     /**
      * Meta-mode: all the modes.
      * This is mostly useful for testing.
      */
-    All,
+    All("all", "TEST MODE"),
+
+    ;
+    private final String shortLabel;
+    private final String longLabel;
+
+    BenchmarkType(String shortLabel, String longLabel) {
+        this.shortLabel = shortLabel;
+        this.longLabel = longLabel;
+    }
+
+    public String shortLabel() {
+        return shortLabel;
+    }
+
+    public String longLabel() {
+        return longLabel;
+    }
+
+    public static BenchmarkType deepValueOf(String name) {
+        try {
+            return BenchmarkType.valueOf(name);
+        } catch (IllegalArgumentException iae) {
+            BenchmarkType inferred = null;
+            for (BenchmarkType type : values()) {
+                if (type.shortLabel().startsWith(name)) {
+                    if (inferred == null) {
+                        inferred = type;
+                    } else {
+                        throw new IllegalStateException("Unable to parse benchmark mode, ambiguous prefix given: \"" + name + "\"\n" +
+                                "Known values are " + getKnown());
+                    }
+                }
+            }
+            if (inferred != null) {
+                return inferred;
+            } else {
+                throw new IllegalStateException("Unable to parse benchmark mode: \"" + name + "\"\n" +
+                        "Known values are " + getKnown());
+            }
+        }
+    }
+
+    public static List<String> getKnown() {
+        List<String> res = new ArrayList<String>();
+        for (BenchmarkType type : BenchmarkType.values()) {
+            res.add(type.toString());
+        }
+        for (BenchmarkType type : BenchmarkType.values()) {
+            res.add(type.shortLabel());
+        }
+        return res;
+    }
 
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/annotations/DefaultMode.java	Tue Jun 04 13:25:13 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/**
- * 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.annotations;
-
-/**
- * Annotations declares the default mode in which benchmark should be run.
- */
-public @interface DefaultMode {
-
-    BenchmarkType value();
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/annotations/GenerateMicroBenchmark.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/annotations/GenerateMicroBenchmark.java	Tue Jun 04 13:28:58 2013 +0400
@@ -78,10 +78,4 @@
 @Retention(RetentionPolicy.SOURCE)
 public @interface GenerateMicroBenchmark {
 
-    /**
-     * The type of result to return from the generated microbenchmark.
-     * See {@link BenchmarkType} for available result types.
-     */
-    public BenchmarkType[] value() default { BenchmarkType.OpsPerTimeUnit };
-
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/logic/results/IterationData.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/logic/results/IterationData.java	Tue Jun 04 13:28:58 2013 +0400
@@ -26,6 +26,7 @@
 
 import org.openjdk.jmh.logic.results.internal.IterationResult;
 import org.openjdk.jmh.profile.ProfilerResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
 import java.util.ArrayList;
@@ -38,7 +39,7 @@
  */
 public class IterationData {
 
-    private final String benchmark;
+    private final BenchmarkRecord benchmark;
     private final List<Result> perThreadResults;
     private final List<ProfilerResult> profilerResults;
     private final int numThreads;
@@ -46,7 +47,7 @@
     private IterationResult aggregated;
     private boolean isWarmup;
 
-    public IterationData(String benchmark, int threadCount, TimeValue runTime) {
+    public IterationData(BenchmarkRecord benchmark, int threadCount, TimeValue runTime) {
         this.benchmark = benchmark;
         this.numThreads = threadCount;
         this.runTime = runTime;
@@ -95,7 +96,7 @@
         return this;
     }
 
-    public String getBenchmark() {
+    public BenchmarkRecord getBenchmark() {
         return benchmark;
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/output/format/CsvFormat.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/format/CsvFormat.java	Tue Jun 04 13:28:58 2013 +0400
@@ -28,6 +28,7 @@
 import org.openjdk.jmh.logic.results.internal.IterationResult;
 import org.openjdk.jmh.logic.results.internal.RunResult;
 import org.openjdk.jmh.profile.ProfilerResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.parameters.MicroBenchmarkParameters;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
@@ -51,7 +52,7 @@
     }
 
     @Override
-    public void iterationResult(String name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
+    public void iterationResult(BenchmarkRecord name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
         out.print(name + DELIMITER + iteration + DELIMITER);
         for (Result r : result.getResult().values()) {
             out.print(convertDouble(r.getScore()) + DELIMITER);
@@ -64,7 +65,7 @@
     }
 
     @Override
-    public void startBenchmark(String name, MicroBenchmarkParameters mbParams, boolean verbose) {
+    public void startBenchmark(BenchmarkRecord name, MicroBenchmarkParameters mbParams, boolean verbose) {
         if (!headerPrinted) {
             headerPrinted = true;
 
@@ -80,7 +81,7 @@
     }
 
     @Override
-    public void endBenchmark(String name, RunResult result) {
+    public void endBenchmark(BenchmarkRecord name, RunResult result) {
         // don't print anything
     }
 
@@ -95,7 +96,7 @@
     }
 
     @Override
-    public void iteration(String benchmark, int iteration, int threads, TimeValue runTime) {
+    public void iteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue runTime) {
         // don't print anything
     }
 
@@ -109,12 +110,12 @@
     }
 
     @Override
-    public void warmupIteration(String benchmark, int iteration, int threads, TimeValue warmupTime) {
+    public void warmupIteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue warmupTime) {
         // don't print anything
     }
 
     @Override
-    public void warmupIterationResult(String benchmark, int iteration, int thread, IterationResult result) {
+    public void warmupIterationResult(BenchmarkRecord benchmark, int iteration, int thread, IterationResult result) {
         // don't print anything
     }
 
@@ -123,7 +124,7 @@
     }
 
     @Override
-    public void detailedResults(String name, int iteration, int threads, IterationResult results) {
+    public void detailedResults(BenchmarkRecord name, int iteration, int threads, IterationResult results) {
         int count = 0;
 
         for (Result result : results.getSubresults().values()) {
@@ -141,7 +142,7 @@
     }
 
     @Override
-    public void threadSubStatistics(String name, int threads, RunResult result) {
+    public void threadSubStatistics(BenchmarkRecord name, int threads, RunResult result) {
 
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/output/format/OutputFormat.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/format/OutputFormat.java	Tue Jun 04 13:28:58 2013 +0400
@@ -27,6 +27,7 @@
 import org.openjdk.jmh.logic.results.internal.IterationResult;
 import org.openjdk.jmh.logic.results.internal.RunResult;
 import org.openjdk.jmh.profile.ProfilerResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.parameters.MicroBenchmarkParameters;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
@@ -51,7 +52,7 @@
      * @param threads   Number of threads we executed on
      * @param warmupTime Time to spend per iteration
      */
-    public void warmupIteration(String benchmark, int iteration, int threads, TimeValue warmupTime);
+    public void warmupIteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue warmupTime);
 
     /**
      * Format for end-of-warmup-iteration.
@@ -61,7 +62,7 @@
      * @param thread    amount of threads used
      * @param result    result of iteration
      */
-    public void warmupIterationResult(String benchmark, int iteration, int thread, IterationResult result);
+    public void warmupIterationResult(BenchmarkRecord benchmark, int iteration, int thread, IterationResult result);
 
     /**
      * Format for iteration start.
@@ -71,7 +72,7 @@
      * @param threads threads to run
      * @param runTime time to spend per iteration
      */
-    public void iteration(String benchmark, int iteration, int threads, TimeValue runTime);
+    public void iteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue runTime);
 
     /**
      * Format for end-of-iteration.
@@ -82,14 +83,14 @@
      * @param result    result of iteration
      * @param profiles  profiler results
      */
-    public void iterationResult(String name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles);
+    public void iterationResult(BenchmarkRecord name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles);
 
     /**
      * Format for start-of-benchmark output.
      *
      * @param verbose Should we output verbose info?
      */
-    public void startBenchmark(String name, MicroBenchmarkParameters mbParams, boolean verbose);
+    public void startBenchmark(BenchmarkRecord name, MicroBenchmarkParameters mbParams, boolean verbose);
 
     /**
      * Format for end-of-benchmark.
@@ -97,7 +98,7 @@
      * @param name       benchmark name
      * @param result statistics of the run
      */
-    public void endBenchmark(String name, RunResult result);
+    public void endBenchmark(BenchmarkRecord name, RunResult result);
 
     /**
      * Format for start-of-benchmark output.
@@ -121,7 +122,7 @@
      * @param threads   thread count
      * @param results   AggregatedResults with detailed run results
      */
-    public void detailedResults(String name, int iteration, int threads, IterationResult results);
+    public void detailedResults(BenchmarkRecord name, int iteration, int threads, IterationResult results);
 
     /**
      * Format for sub-thread statistics.
@@ -130,7 +131,7 @@
      * @param threads   thread count
      * @param result    result of iterations of the current threadcount
      */
-    public void threadSubStatistics(String name, int threads, RunResult result);
+    public void threadSubStatistics(BenchmarkRecord name, int threads, RunResult result);
 
     /* ------------- SPECIAL TRACING METHODS -------------------- */
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/output/format/PrettyPrintFormat.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/format/PrettyPrintFormat.java	Tue Jun 04 13:28:58 2013 +0400
@@ -28,6 +28,7 @@
 import org.openjdk.jmh.logic.results.internal.IterationResult;
 import org.openjdk.jmh.logic.results.internal.RunResult;
 import org.openjdk.jmh.profile.ProfilerResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.parameters.MicroBenchmarkParameters;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 import org.openjdk.jmh.util.internal.HashMultimap;
@@ -52,7 +53,7 @@
     }
 
     @Override
-    public void iterationResult(String name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
+    public void iterationResult(BenchmarkRecord name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
         boolean firstProfiler = true;
         out.print(String.format("%s", result.toPrintable()));
         for (ProfilerResult profRes : profiles) {
@@ -75,7 +76,7 @@
 
 
     @Override
-    public void startBenchmark(String name, MicroBenchmarkParameters mbParams, boolean verbose) {
+    public void startBenchmark(BenchmarkRecord name, MicroBenchmarkParameters mbParams, boolean verbose) {
         if (verbose) {
             out.println("# Starting run at: " + new Date());
         }
@@ -97,13 +98,14 @@
             out.println("# Threads will synchronize iterations");
         }
 
-        out.println("# Running: " + name);
+        out.println("# Benchmark mode: " + name.getMode().longLabel());
+        out.println("# Running: " + name.getUsername());
     }
 
-    private final Multimap<String, RunResult> benchmarkResults = new HashMultimap<String, RunResult>();
+    private final Multimap<BenchmarkRecord, RunResult> benchmarkResults = new HashMultimap<BenchmarkRecord, RunResult>();
 
     @Override
-    public void endBenchmark(String name, RunResult result) {
+    public void endBenchmark(BenchmarkRecord name, RunResult result) {
         benchmarkResults.put(name, result);
 
         out.println();
@@ -120,7 +122,7 @@
 
     @Override
     public void endRun(String message) {
-        for (String key : benchmarkResults.keys()) {
+        for (BenchmarkRecord key : benchmarkResults.keys()) {
             Collection<RunResult> forkedResults = benchmarkResults.get(key);
             if (forkedResults.size() > 1) {
                 out.println(key + ", aggregate over forked runs:");
@@ -139,27 +141,27 @@
     }
 
     @Override
-    public void iteration(String benchmark, int iteration, int threads, TimeValue timeValue) {
+    public void iteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue timeValue) {
         out.print(String.format("Iteration %3d (%s in %d %s): ", iteration,
                 timeValue, threads, getThreadsString(threads)));
         out.flush();
     }
 
     @Override
-    public void warmupIteration(String benchmark, int iteration, int threads, TimeValue timeValue) {
+    public void warmupIteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue timeValue) {
         out.print(String.format("# Warmup Iteration %3d (%s in %d %s): ", iteration,
                 timeValue, threads, getThreadsString(threads)));
         out.flush();
     }
 
     @Override
-    public void warmupIterationResult(String benchmark, int iteration, int thread, IterationResult result) {
+    public void warmupIterationResult(BenchmarkRecord benchmark, int iteration, int thread, IterationResult result) {
         out.println(String.format("%s", result.toPrintable()));
         out.flush();
     }
 
     @Override
-    public void detailedResults(String name, int iteration, int threads, IterationResult results) {
+    public void detailedResults(BenchmarkRecord name, int iteration, int threads, IterationResult results) {
         out.print("Results per thread: [");
 
         boolean first = true;
@@ -180,7 +182,7 @@
     }
 
     @Override
-    public void threadSubStatistics(String name, int threads, RunResult result) {
+    public void threadSubStatistics(BenchmarkRecord name, int threads, RunResult result) {
         out.println();
 
         for (String label : result.getStatistics().keySet()) {
--- a/jmh-core/src/main/java/org/openjdk/jmh/output/format/SilentFormat.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/format/SilentFormat.java	Tue Jun 04 13:28:58 2013 +0400
@@ -27,6 +27,7 @@
 import org.openjdk.jmh.logic.results.internal.IterationResult;
 import org.openjdk.jmh.logic.results.internal.RunResult;
 import org.openjdk.jmh.profile.ProfilerResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.parameters.MicroBenchmarkParameters;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
@@ -53,27 +54,27 @@
     }
 
     @Override
-    public void warmupIteration(String benchmark, int iteration, int threads, TimeValue warmupTime) {
+    public void warmupIteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue warmupTime) {
 
     }
 
     @Override
-    public void startBenchmark(String name, MicroBenchmarkParameters mbParams, boolean verbose) {
+    public void startBenchmark(BenchmarkRecord name, MicroBenchmarkParameters mbParams, boolean verbose) {
 
     }
 
     @Override
-    public void endBenchmark(String name, RunResult result) {
+    public void endBenchmark(BenchmarkRecord name, RunResult result) {
 
     }
 
     @Override
-    public void detailedResults(String name, int iteration, int threads, IterationResult results) {
+    public void detailedResults(BenchmarkRecord name, int iteration, int threads, IterationResult results) {
 
     }
 
     @Override
-    public void iteration(String benchmark, int iteration, int threads, TimeValue runTime) {
+    public void iteration(BenchmarkRecord benchmark, int iteration, int threads, TimeValue runTime) {
 
     }
 
@@ -86,16 +87,16 @@
     }
 
     @Override
-    public void iterationResult(String name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
+    public void iterationResult(BenchmarkRecord name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
 
     }
 
     @Override
-    public void warmupIterationResult(String benchmark, int iteration, int thread, IterationResult result) {
+    public void warmupIterationResult(BenchmarkRecord benchmark, int iteration, int thread, IterationResult result) {
     }
 
     @Override
-    public void threadSubStatistics(String name, int threads, RunResult results) {
+    public void threadSubStatistics(BenchmarkRecord name, int threads, RunResult results) {
 
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/output/format/TextReportFormat.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/format/TextReportFormat.java	Tue Jun 04 13:28:58 2013 +0400
@@ -28,6 +28,7 @@
 import org.openjdk.jmh.logic.results.internal.IterationResult;
 import org.openjdk.jmh.logic.results.internal.RunResult;
 import org.openjdk.jmh.profile.ProfilerResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.parameters.IterationParams;
 import org.openjdk.jmh.runner.parameters.MicroBenchmarkParameters;
 import org.openjdk.jmh.util.ClassUtils;
@@ -52,22 +53,22 @@
 public class TextReportFormat extends PrettyPrintFormat {
 
     private final Multimap<BenchmarkIdentifier, IterationResult> benchmarkResults;
-    private final Map<String, IterationParams> benchmarkSettings;
+    private final Map<BenchmarkRecord, IterationParams> benchmarkSettings;
 
     public TextReportFormat(PrintStream out, boolean verbose) {
         super(out, verbose);
         benchmarkResults = new TreeMultimap<BenchmarkIdentifier, IterationResult>();
-        benchmarkSettings = new TreeMap<String, IterationParams>();
+        benchmarkSettings = new TreeMap<BenchmarkRecord, IterationParams>();
     }
 
     @Override
-    public void startBenchmark(String name, MicroBenchmarkParameters mbParams, boolean verbose) {
+    public void startBenchmark(BenchmarkRecord name, MicroBenchmarkParameters mbParams, boolean verbose) {
         super.startBenchmark(name, mbParams, verbose);
         benchmarkSettings.put(name, mbParams.getIteration());
     }
 
     @Override
-    public void iterationResult(String name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
+    public void iterationResult(BenchmarkRecord name, int iteration, int thread, IterationResult result, Collection<ProfilerResult> profiles) {
         super.iterationResult(name, iteration, thread, result, profiles);
         benchmarkResults.put(new BenchmarkIdentifier(name, thread), result);
     }
@@ -97,7 +98,7 @@
 
                     boolean onlyResult = runResult.getStatistics().size() <= 1;
                     for (String label : runResult.getStatistics().keySet()) {
-                        benchNames.add(key.benchmark + (onlyResult ? "" : ":" + label));
+                        benchNames.add(key.benchmark.getUsername() + (onlyResult ? "" : ":" + label));
                     }
                 }
             }
@@ -112,8 +113,8 @@
         }
         nameLen += 2;
 
-        out.printf("%-" + nameLen + "s %3s %6s %4s %12s %12s %12s %8s%n",
-                "Benchmark", "Thr", "Cnt", "Sec",
+        out.printf("%-" + nameLen + "s %6s %3s %6s %4s %12s %12s %12s %8s%n",
+                "Benchmark", "Mode", "Thr", "Cnt", "Sec",
                 "Mean", "Mean error", "Var", "Units");
         for (BenchmarkIdentifier key : benchmarkResults.keys()) {
 
@@ -139,8 +140,10 @@
                             interval = stats.getConfidenceInterval(0.01);
                         }
 
-                        out.printf("%-" + nameLen + "s %3d %6d %4d %12.3f %12.3f %12.3f %8s%n",
-                                benchPrefixes.get(key.benchmark + (onlyResult ? "" : ":" + label)), key.threads, stats.getN(),
+                        out.printf("%-" + nameLen + "s %6s %3d %6d %4d %12.3f %12.3f %12.3f %8s%n",
+                                benchPrefixes.get(key.benchmark.getUsername() + (onlyResult ? "" : ":" + label)),
+                                key.benchmark.getMode().shortLabel(),
+                                key.threads, stats.getN(),
                                 settings.getTime().convertTo(TimeUnit.SECONDS),
                                 stats.getMean(), (interval[1] - interval[0]) / 2,
                                 stats.getVariance(), runResult.getScoreUnit());
@@ -150,8 +153,10 @@
             }
 
             if (!resultOK) {
-                out.printf("%-" + nameLen + "s %3d %6d %4d %12.3f %12.3f %12.3f %8s%n",
-                        benchPrefixes.get(key.benchmark), key.threads, 0,
+                out.printf("%-" + nameLen + "s %6s, %3d %6d %4d %12.3f %12.3f %12.3f %8s%n",
+                        benchPrefixes.get(key.benchmark.getUsername()),
+                        key.benchmark.getMode().shortLabel(),
+                        key.threads, 0,
                         settings.getTime().convertTo(TimeUnit.SECONDS),
                         Double.NaN, Double.NaN, Double.NaN,
                         "N/A");
@@ -163,10 +168,10 @@
     }
 
     private static class BenchmarkIdentifier implements Comparable<BenchmarkIdentifier> {
-        final String benchmark;
+        final BenchmarkRecord benchmark;
         final int threads;
 
-        BenchmarkIdentifier(String benchmark, int threads) {
+        BenchmarkIdentifier(BenchmarkRecord benchmark, int threads) {
             this.benchmark = benchmark;
             this.threads = threads;
         }
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerateMicroBenchmarkProcessor.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/GenerateMicroBenchmarkProcessor.java	Tue Jun 04 13:28:58 2013 +0400
@@ -33,6 +33,7 @@
 import org.openjdk.jmh.logic.results.Result;
 import org.openjdk.jmh.logic.results.SampleTimePerOp;
 import org.openjdk.jmh.logic.results.SingleShotTime;
+import org.openjdk.jmh.runner.MicroBenchmarkList;
 import org.openjdk.jmh.util.internal.CollectionUtils;
 import org.openjdk.jmh.util.internal.SampleBuffer;
 
@@ -49,7 +50,9 @@
 import javax.lang.model.util.ElementFilter;
 import javax.lang.model.util.Types;
 import javax.tools.Diagnostic.Kind;
+import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
 import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
@@ -66,11 +69,28 @@
 @SupportedSourceVersion(SourceVersion.RELEASE_6)
 public class GenerateMicroBenchmarkProcessor extends AbstractProcessor {
 
+    private final Set<BenchmarkInfo> benchmarkInfos = new HashSet<BenchmarkInfo>();
+
     @Override
     public Set<String> getSupportedAnnotationTypes() {
         return Collections.singleton(GenerateMicroBenchmark.class.getName());
     }
 
+    public static class BenchmarkInfo {
+        public final String userName;
+        public final String generatedName;
+        public final String generatedPackageName;
+        public final String generatedClassName;
+        public final Map<String, MethodGroup> methodGroups;
+
+        public BenchmarkInfo(String userName, String generatedPackageName, String generatedClassName, Map<String, MethodGroup> methods) {
+            this.userName = userName;
+            this.generatedPackageName = generatedPackageName;
+            this.generatedClassName = generatedClassName;
+            this.generatedName = generatedPackageName + "." + generatedClassName;
+            this.methodGroups = methods;
+        }
+    }
 
     @Override
     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
@@ -83,9 +103,27 @@
                     // Generate code for all found Classes and Methods
                     for (Map.Entry<TypeElement, Set<? extends Element>> typeElementSetEntry : clazzes.entrySet()) {
                         TypeElement clazz = typeElementSetEntry.getKey();
-                        generateClass(clazz, validateAndSplit(clazz, typeElementSetEntry.getValue()));
+                        BenchmarkInfo info = validateAndSplit(clazz, typeElementSetEntry.getValue());
+                        generateClass(clazz, info);
+                        benchmarkInfos.add(info);
                     }
                 }
+            } else {
+                // Processing completed, final round. Print all added methods to file
+                try {
+                    FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "",
+                            MicroBenchmarkList.MICROBENCHMARK_LIST.substring(1));
+                    PrintWriter writer = new PrintWriter(file.openWriter());
+                    for (BenchmarkInfo info : benchmarkInfos) {
+                        for (String method : info.methodGroups.keySet()) {
+                            MethodGroup group = info.methodGroups.get(method);
+                            writer.println(info.userName + "." + method + ", " + info.generatedName + "." + method + ", " + group.getMode());
+                        }
+                    }
+                    writer.close();
+                } catch (IOException ex) {
+                    processingEnv.getMessager().printMessage(Kind.ERROR, "Error writing MicroBenchmark list " + ex);
+                }
             }
         } catch (Throwable t) {
             processingEnv.getMessager().printMessage(Kind.ERROR, "Annotation processor had throw exception: " + t);
@@ -129,7 +167,7 @@
      * @param methods
      * @return
      */
-    private Map<String, MethodGroup> validateAndSplit(TypeElement clazz, Set<? extends Element> methods) {
+    private BenchmarkInfo validateAndSplit(TypeElement clazz, Set<? extends Element> methods) {
         // validate against rogue fields
         if (clazz.getAnnotation(State.class) == null || clazz.getModifiers().contains(Modifier.ABSTRACT)) {
             for (VariableElement field : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
@@ -153,34 +191,48 @@
 
             boolean methodStrictFP = method.getModifiers().contains(Modifier.STRICTFP);
 
-            BenchmarkType type = BenchmarkType.OpsPerTimeUnit;
-            DefaultMode mbAn = method.getAnnotation(DefaultMode.class);
+            Group groupAnn = method.getAnnotation(Group.class);
+            String groupName = (groupAnn != null) ? groupAnn.value() : method.getSimpleName().toString();
+            MethodGroup group = result.get(groupName);
+            if (group == null) {
+                group = new MethodGroup(convertToJavaIdentfier(groupName));
+                result.put(groupName, group);
+            }
+
+            BenchmarkMode mbAn = method.getAnnotation(BenchmarkMode.class);
             if (mbAn != null) {
-                type = mbAn.value();
+                group.setMode(mbAn.value());
             } else {
-                mbAn = method.getEnclosingElement().getAnnotation(DefaultMode.class);
+                mbAn = method.getEnclosingElement().getAnnotation(BenchmarkMode.class);
                 if (mbAn != null) {
-                    type = mbAn.value();
+                    group.setMode(mbAn.value());
                 }
             }
 
-            MethodGroup group = getMethodGroup(result, method, type);
             group.addStrictFP(classStrictFP);
             group.addStrictFP(methodStrictFP);
             group.addMethod(method, getThreads(method));
         }
-        return result;
-    }
 
-    private MethodGroup getMethodGroup(Map<String, MethodGroup> groups, Element method, BenchmarkType defaultMode) {
-        Group groupAnn = method.getAnnotation(Group.class);
-        String groupName = (groupAnn != null) ? groupAnn.value() : method.getSimpleName().toString();
-        MethodGroup methodGroup = groups.get(groupName);
-        if (methodGroup == null) {
-            methodGroup = new MethodGroup(convertToJavaIdentfier(groupName), defaultMode);
-            groups.put(groupName, methodGroup);
+        // enforce the default value
+        for (MethodGroup group : result.values()) {
+            if (group.getMode() == null) {
+                group.setMode(BenchmarkType.OpsPerTimeUnit);
+            }
         }
-        return methodGroup;
+
+        String sourcePackage = packageName(clazz);
+        if (sourcePackage.isEmpty()) {
+            processingEnv.getMessager().printMessage(Kind.ERROR,
+                    "Microbenchmark should have package other than default (" + clazz + ")");
+            return null;
+        }
+
+        // Build package name and class name for the Class to generate
+        String generatedPackageName = sourcePackage + ".generated";
+        String generatedClassName = clazz.getSimpleName().toString();
+
+        return new BenchmarkInfo(clazz.getQualifiedName().toString(), generatedPackageName, generatedClassName, result);
     }
 
     public static String convertToJavaIdentfier(String id) {
@@ -216,33 +268,21 @@
      * Create and generate Java code for a class and it's methods
      *
      * @param clazz
-     * @param methods
      */
-    private void generateClass(TypeElement clazz, Map<String, MethodGroup> methods) {
+    private void generateClass(TypeElement clazz, BenchmarkInfo info) {
         try {
-            String sourcePackage = packageName(clazz);
-            if (sourcePackage.isEmpty()) {
-                processingEnv.getMessager().printMessage(Kind.ERROR,
-                        "Microbenchmark should have package other than default (" + clazz + ")");
-                return;
-            }
-
-            // Build package name and class name for the Class to generate
-            String generatedPackageName = sourcePackage + ".generated";
-            String generatedClassName = clazz.getSimpleName().toString();
-
             // Create file and open an outputstream
-            JavaFileObject jof = processingEnv.getFiler().createSourceFile(generatedPackageName + "." + generatedClassName, clazz);
+            JavaFileObject jof = processingEnv.getFiler().createSourceFile(info.generatedName, clazz);
             PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(jof.openOutputStream()), 64*1024), false);
 
             // Write package and imports
-            writer.println("package " + generatedPackageName + ';');
+            writer.println("package " + info.generatedPackageName + ';');
             writer.println();
 
             generateImport(writer);
             // Write class header
-            writer.println(generateClassAnnotation(methods.keySet()));
-            writer.println("public final class " + generatedClassName + " {");
+            writer.println(generateClassAnnotation(info.methodGroups.keySet()));
+            writer.println("public final class " + info.generatedClassName + " {");
             writer.println();
             generatePadding(writer);
 
@@ -257,8 +297,8 @@
             states.bindImplicit(processingEnv.getElementUtils().getTypeElement(BlackHole.class.getCanonicalName()), "blackhole", Scope.Thread);
 
             // Write all methods
-            for (String groupName : methods.keySet()) {
-                for (Element method : methods.get(groupName).methods()) {
+            for (String groupName : info.methodGroups.keySet()) {
+                for (Element method : info.methodGroups.get(groupName).methods()) {
                     // Final checks...
                     verifyAnnotations(method);
 
@@ -272,8 +312,8 @@
                 }
 
                 for (BenchmarkType benchmarkKind : BenchmarkType.values()) {
-                    if (benchmarkKind == BenchmarkType.All) continue; // FIXME: This mode should be EOL'ed
-                    generateMethod(benchmarkKind, writer, methods.get(groupName), states);
+                    if (benchmarkKind == BenchmarkType.All) continue;
+                    generateMethod(benchmarkKind, writer, info.methodGroups.get(groupName), states);
                 }
                 states.clearArgs();
             }
@@ -345,12 +385,6 @@
                             + " annotation only supports methods with @State-bearing typed parameters, "
                             + clazz + '.' + method);
         }
-        if (method.getAnnotation(GenerateMicroBenchmark.class).value().length == 0) {
-            processingEnv.getMessager().printMessage(Kind.ERROR,
-                    "The " + GenerateMicroBenchmark.class.getSimpleName()
-                            + " annotation should have one or more " + BenchmarkType.class.getSimpleName() + " parameters, "
-                            + clazz + '.' + method);
-        }
     }
 
     private void generatePadding(PrintWriter writer) {
@@ -384,7 +418,7 @@
         writer.println("import " + Measurement.class.getName() + ';');
         writer.println("import " + Threads.class.getName() + ';');
         writer.println("import " + Warmup.class.getName() + ';');
-        writer.println("import " + DefaultMode.class.getName() + ';');
+        writer.println("import " + BenchmarkMode.class.getName() + ';');
         writer.println("import " + RawResultPair.class.getName() + ';');
         writer.println();
     }
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodGroup.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MethodGroup.java	Tue Jun 04 13:28:58 2013 +0400
@@ -34,14 +34,13 @@
 
 public class MethodGroup implements Comparable<MethodGroup> {
     private final String name;
-    private final BenchmarkType defaultMode;
     private final Set<MethodInvocation> methods;
     private boolean strictFP;
+    private BenchmarkType mode;
 
-    MethodGroup(String name, BenchmarkType defaultMode) {
+    MethodGroup(String name) {
         this.name = name;
         this.methods = new LinkedHashSet<MethodInvocation>();
-        this.defaultMode = defaultMode;
     }
 
     @Override
@@ -106,4 +105,18 @@
     public boolean isStrictFP() {
         return strictFP;
     }
+
+    public void setMode(BenchmarkType eMode) {
+        if (mode == null) {
+            mode = eMode;
+        } else {
+            if (mode != eMode) {
+                throw new IllegalStateException("Clashing benchmark modes: mode = " + mode + ", trying to set = " + eMode);
+            }
+        }
+    }
+
+    public BenchmarkType getMode() {
+        return mode;
+    }
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MicroBenchmarkProcessor.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/processor/internal/MicroBenchmarkProcessor.java	Tue Jun 04 13:28:58 2013 +0400
@@ -51,8 +51,6 @@
 @SupportedSourceVersion(SourceVersion.RELEASE_6)
 public class MicroBenchmarkProcessor extends AbstractProcessor {
 
-    private final Set<String> methods = new TreeSet<String>();
-
     @Override
     public Set<String> getSupportedAnnotationTypes() {
         return Collections.singleton(MicroBenchmark.class.getName());
@@ -70,32 +68,11 @@
                 // Still processing add all annotated methods to the set
                 for (TypeElement annotation : annotations) {
                     for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
-                        // Check that Method has the correct
-                        if (!(element instanceof ExecutableElement)
-                                || !validMethodSignature((ExecutableElement) element)) {
-                            processingEnv.getMessager().printMessage(Kind.ERROR,
-                                    "The " + MicroBenchmark.class.getSimpleName()
-                                            + " annotation only supports methods return type " + Result.class.getName()
-                                            + " and a single " + Loop.class.getName() + " parameter. "
-                                            + element.getEnclosingElement() + '.' + element.toString());
-                        } else {
-                            methods.add(element.getEnclosingElement() + "." + element.getSimpleName());
-                        }
+                        processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING,
+                                "The " + MicroBenchmark.class.getSimpleName()
+                                        + " is detected. This is not the supported API anymore."
+                                        + element.getEnclosingElement() + '.' + element.toString());
                     }
-
-                }
-            } else {
-                // Processing completed, final round. Print all added methods to file
-                try {
-                    FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "",
-                            MicroBenchmarkList.MICROBENCHMARK_LIST.substring(1));
-                    PrintWriter writer = new PrintWriter(file.openWriter());
-                    for (String method : methods) {
-                        writer.println(method);
-                    }
-                    writer.close();
-                } catch (IOException ex) {
-                    processingEnv.getMessager().printMessage(Kind.ERROR, "Error writing MicroBenchmark list " + ex);
                 }
             }
         } catch (Throwable t) {
@@ -105,27 +82,4 @@
         return true;
     }
 
-    /**
-     * Check that the method signature is correct for MicroBenchmark methods
-     *
-     * @param element The annotated method
-     * @return True iff the method has the correct signature
-     */
-    public static boolean validMethodSignature(ExecutableElement element) {
-        if (!element.getReturnType().toString().equals(Result.class.getName())) {
-            return false;
-        }
-
-        List<? extends VariableElement> variables = element.getParameters();
-
-        if (variables.size() != 1) {
-            return false;
-        }
-
-        if (!variables.get(0).asType().toString().equals(Loop.class.getName())) {
-            return false;
-        }
-
-        return true;
-    }
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/BaseMicroBenchmarkHandler.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/BaseMicroBenchmarkHandler.java	Tue Jun 04 13:28:58 2013 +0400
@@ -49,7 +49,7 @@
     /**
      * Name of micro benchmark
      */
-    protected final String microbenchmark;
+    protected final BenchmarkRecord microbenchmark;
 
     /**
      * Thread-pool for threads executing the benchmark tasks
@@ -63,10 +63,10 @@
 
     private final List<Profiler> registeredProfilers;
 
-    public BaseMicroBenchmarkHandler(OutputFormat format, String microbenchmark, final Class<?> clazz, BaseOptions options, MicroBenchmarkParameters executionParams) {
+    public BaseMicroBenchmarkHandler(OutputFormat format, BenchmarkRecord microbenchmark, final Class<?> clazz, BaseOptions options, MicroBenchmarkParameters executionParams) {
         this.microbenchmark = microbenchmark;
         this.registeredProfilers = createProfilers(options);
-        this.executor = createExecutor(executionParams.getMaxThreads(), microbenchmark);
+        this.executor = createExecutor(executionParams.getMaxThreads(), microbenchmark.getUsername());
         this.threadLocal = new ThreadLocal<InstanceProvider>() {
             @Override
             protected InstanceProvider initialValue() {
@@ -204,7 +204,7 @@
      * {@inheritDoc}
      */
     @Override
-    public String getName() {
+    public BenchmarkRecord getBenchmark() {
         return microbenchmark;
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/BaseRunner.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/BaseRunner.java	Tue Jun 04 13:28:58 2013 +0400
@@ -64,20 +64,16 @@
      * The method manages both warmup and measurements iterations
      * @param benchmark benchmark to run
      */
-    void runClassicBenchmark(String benchmark) {
+    void runClassicBenchmark(BenchmarkRecord benchmark) {
         List<IterationData> allResults = new ArrayList<IterationData>();
         try {
-            int index = benchmark.lastIndexOf('.');
-            String className = benchmark.substring(0, index);
-            String methodName = benchmark.substring(index + 1);
-
-            Class<?> clazz = ClassUtils.loadClass(className);
-            Method method = MicroBenchmarkHandlers.findBenchmarkMethod(clazz, methodName);
+            Class<?> clazz = ClassUtils.loadClass(benchmark.generatedClass());
+            Method method = MicroBenchmarkHandlers.findBenchmarkMethod(clazz, benchmark.generatedMethod());
 
             MicroBenchmarkParameters executionParams = MicroBenchmarkParametersFactory.makeParams(options, method);
             MicroBenchmarkHandler handler = MicroBenchmarkHandlers.getInstance(outputHandler, benchmark, clazz, method, executionParams, options);
 
-            outputHandler.startBenchmark(handler.getName(), executionParams, this.options.isVerbose());
+            outputHandler.startBenchmark(handler.getBenchmark(), executionParams, this.options.isVerbose());
 
             int iteration = 0;
             final Collection<ThreadIterationParams> threadIterationSequence = executionParams.getThreadIterationSequence();
@@ -96,7 +92,7 @@
             // only print end-of-run output if we have actual results
             if (!allResults.isEmpty()) {
                 RunResult result = aggregateIterationData(allResults);
-                outputHandler.endBenchmark(handler.getName(), result);
+                outputHandler.endBenchmark(handler.getBenchmark(), result);
             }
 
             handler.shutdown();
@@ -122,7 +118,7 @@
             }
 
             // run benchmark iteration
-            outputHandler.iteration(handler.getName(), startIterNum + i, tip.getThreads(), tip.getTime());
+            outputHandler.iteration(handler.getBenchmark(), startIterNum + i, tip.getThreads(), tip.getTime());
 
             boolean isLastIteration = (i == tip.getCount());
             IterationData iterData = handler.runIteration(tip.getThreads(), tip.getTime(), isLastIteration);
@@ -135,12 +131,12 @@
                 results.add(iterData);
 
                 // print out score for this iteration
-                outputHandler.iterationResult(handler.getName(), startIterNum + i, tip.getThreads(), iterData.getAggregatedResult(), iterData.getProfilerResults());
+                outputHandler.iterationResult(handler.getBenchmark(), startIterNum + i, tip.getThreads(), iterData.getAggregatedResult(), iterData.getProfilerResults());
 
                 // detailed output
                 if (showDetailedResults) {
                     // print (or not) detailed per-thread results
-                    outputHandler.detailedResults(handler.getName(), startIterNum + i, tip.getThreads(), iterData.getAggregatedResult());
+                    outputHandler.detailedResults(handler.getBenchmark(), startIterNum + i, tip.getThreads(), iterData.getAggregatedResult());
                 }
 
             }
@@ -151,7 +147,7 @@
             // if threads and the next iteration will change the count,
             // OR if we're finished iterating
             RunResult aggregatedResult = aggregateIterationData(results);
-            outputHandler.threadSubStatistics(handler.getName(), tip.getThreads(), aggregatedResult);
+            outputHandler.threadSubStatistics(handler.getBenchmark(), tip.getThreads(), aggregatedResult);
         }
         return results;
     }
@@ -178,10 +174,10 @@
                 outputHandler.verbosePrintln("System.gc() executed");
             }
 
-            outputHandler.warmupIteration(handler.getName(), i, warmup.getThreads(), warmup.getTime());
+            outputHandler.warmupIteration(handler.getBenchmark(), i, warmup.getThreads(), warmup.getTime());
             boolean isLastIteration = false; // warmup is never the last iteration
             IterationData iterData = handler.runIteration(warmup.getThreads(), warmup.getTime(), isLastIteration).setWarmup();
-            outputHandler.warmupIterationResult(handler.getName(), i, warmup.getThreads(), iterData.getAggregatedResult());
+            outputHandler.warmupIterationResult(handler.getBenchmark(), i, warmup.getThreads(), iterData.getAggregatedResult());
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkRecord.java	Tue Jun 04 13:28:58 2013 +0400
@@ -0,0 +1,111 @@
+/**
+ * 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.runner;
+
+import org.openjdk.jmh.annotations.BenchmarkType;
+
+import java.io.Serializable;
+
+public class BenchmarkRecord implements Comparable<BenchmarkRecord>, Serializable {
+
+    private final String userName;
+    private final String generatedName;
+    private BenchmarkType mode;
+
+    private BenchmarkRecord(String userName, String generatedName, BenchmarkType mode) {
+        this.userName = userName;
+        this.generatedName = generatedName;
+        this.mode = mode;
+    }
+
+    public BenchmarkRecord(String line) {
+        String[] args = line.split(",");
+
+        if (args.length != 3) {
+            throw new IllegalStateException("Mismatched format for the line: " + line);
+        }
+
+        this.userName = args[0].trim();
+        this.generatedName = args[1].trim();
+        this.mode = BenchmarkType.deepValueOf(args[2].trim());
+    }
+
+    public String toLine() {
+        return userName + ", " + generatedName + ", " + mode;
+    }
+
+    public BenchmarkRecord cloneWith(BenchmarkType mode) {
+        return new BenchmarkRecord(userName, generatedName, mode);
+    }
+
+    @Override
+    public int compareTo(BenchmarkRecord o) {
+        int v = userName.compareTo(o.userName);
+        if (v != 0) {
+            return v;
+        }
+
+        return mode.compareTo(o.mode);
+    }
+
+    public String generatedTarget(BenchmarkType type) {
+        return generatedName + "_" + type;
+    }
+
+    public String generatedTarget() {
+        return generatedTarget(mode);
+    }
+
+    public String generatedClass() {
+        String s = generatedTarget();
+        return s.substring(0, s.lastIndexOf('.'));
+    }
+
+    public String generatedMethod() {
+        String s = generatedTarget();
+        return s.substring(s.lastIndexOf('.') + 1);
+    }
+
+    public String getUsername() {
+        return userName;
+    }
+
+    public void setMode(BenchmarkType mode) {
+        this.mode = mode;
+    }
+
+    public BenchmarkType getMode() {
+        return mode;
+    }
+
+    @Override
+    public String toString() {
+        return "BenchmarkRecord{" +
+                "userName='" + userName + '\'' +
+                ", generatedName='" + generatedName + '\'' +
+                ", mode=" + mode +
+                '}';
+    }
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/ForkedRunner.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/ForkedRunner.java	Tue Jun 04 13:28:58 2013 +0400
@@ -47,17 +47,19 @@
             // override output handler
             outputHandler = OutputFormatFactory.createBinaryHook(options.getHostName(), options.getHostPort());
         }
-        String benchmark = options.getBenchmark();
+
+        // expect the tuple from the parent process
+        BenchmarkRecord benchmark = new BenchmarkRecord(options.getBenchmark());
         if (options.isVerbose()) {
             outputHandler.println("Benchmarks: ");
-            outputHandler.println(benchmark);
+            outputHandler.println(benchmark.getUsername());
         }
         runForkedBenchmarks(benchmark);
         outputHandler.flush();
         outputHandler.close();
     }
 
-    private void runForkedBenchmarks(String benchmark) {
+    private void runForkedBenchmarks(BenchmarkRecord benchmark) {
         outputHandler.startRun("Measurement Section");
         runClassicBenchmark(benchmark);
         outputHandler.endRun(null);
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/LoopMicroBenchmarkHandler.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/LoopMicroBenchmarkHandler.java	Tue Jun 04 13:28:58 2013 +0400
@@ -75,7 +75,7 @@
      * @param options      Options from the command line
      * @param executionParams
      */
-    LoopMicroBenchmarkHandler(OutputFormat format, String microbenchmark, Class<?> clazz, Method method, BaseOptions options, MicroBenchmarkParameters executionParams) {
+    LoopMicroBenchmarkHandler(OutputFormat format, BenchmarkRecord microbenchmark, Class<?> clazz, Method method, BaseOptions options, MicroBenchmarkParameters executionParams) {
         super(format, microbenchmark, clazz, options, executionParams);
         this.method = method;
         this.shouldSynchIterations = executionParams.shouldSynchIterations();
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkHandler.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkHandler.java	Tue Jun 04 13:28:58 2013 +0400
@@ -59,7 +59,7 @@
      * returns benchmark name.
      * @return
      */
-    public String getName();
+    public BenchmarkRecord getBenchmark();
 }
 
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkHandlers.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkHandlers.java	Tue Jun 04 13:28:58 2013 +0400
@@ -44,13 +44,9 @@
     private MicroBenchmarkHandlers() {
     }
 
-    public static Method findBenchmarkMethod(String benchmark) {
-        int index = benchmark.lastIndexOf('.');
-        String className = benchmark.substring(0, index);
-        String methodName = benchmark.substring(index + 1);
-
-        Class<?> clazz = ClassUtils.loadClass(className);
-        return findBenchmarkMethod(clazz, methodName);
+    public static Method findBenchmarkMethod(BenchmarkRecord benchmark) {
+        Class<?> clazz = ClassUtils.loadClass(benchmark.generatedClass());
+        return findBenchmarkMethod(clazz, benchmark.generatedMethod());
     }
 
     public static Method findBenchmarkMethod(Class<?> clazz, String methodName) {
@@ -73,7 +69,7 @@
         return method;
     }
 
-    public static MicroBenchmarkHandler getInstance(OutputFormat outputHandler, String microbenchmark, Class<?> clazz, Method method, MicroBenchmarkParameters executionParams, BaseOptions options) {
+    public static MicroBenchmarkHandler getInstance(OutputFormat outputHandler, BenchmarkRecord microbenchmark, Class<?> clazz, Method method, MicroBenchmarkParameters executionParams, BaseOptions options) {
         MicroBenchmark mb = method.getAnnotation(MicroBenchmark.class);
         if(mb.value() == BenchmarkType.SingleShotTime) {
             return new ShotMicroBenchmarkHandler(outputHandler, microbenchmark, clazz, method, options, executionParams);
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkList.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/MicroBenchmarkList.java	Tue Jun 04 13:28:58 2013 +0400
@@ -73,7 +73,7 @@
      * @param excludes List of regexps to match excludes against
      * @return A list of all benchmarks, excluding matched
      */
-    public Set<String> getAll(OutputFormat out, List<String> excludes) {
+    public Set<BenchmarkRecord> getAll(OutputFormat out, List<String> excludes) {
         return find(out, ".*", excludes);
     }
 
@@ -84,7 +84,7 @@
      * @param excludes List of regexps to match excludes against
      * @return Names of all micro benchmarks in the list that matches the include and NOT matching excludes
      */
-    public Set<String> find(OutputFormat out, String regexp, List<String> excludes) {
+    public Set<BenchmarkRecord> find(OutputFormat out, String regexp, List<String> excludes) {
         return find(out, Collections.singletonList(regexp), excludes);
     }
 
@@ -95,7 +95,7 @@
      * @param excludes List of regexps to match excludes against
      * @return Names of all micro benchmarks in the list that matches includes and NOT matching excludes
      */
-    public Set<String> find(OutputFormat out, List<String> regexps, List<String> excludes) {
+    public Set<BenchmarkRecord> find(OutputFormat out, List<String> regexps, List<String> excludes) {
 
         // compile all patterns
         List<Pattern> includePatterns = new ArrayList<Pattern>(regexps.size());
@@ -108,7 +108,7 @@
         }
 
         // find all benchmarks matching pattern
-        Set<String> result = new TreeSet<String>();
+        Set<BenchmarkRecord> result = new TreeSet<BenchmarkRecord>();
         try {
             for (Reader r : getReaders()) {
                 BufferedReader reader = new BufferedReader(r);
@@ -122,14 +122,16 @@
                         continue;
                     }
 
+                    BenchmarkRecord br = new BenchmarkRecord(line);
+
                     for (Pattern pattern : includePatterns) {
-                        if (pattern.matcher(line).matches()) {
+                        if (pattern.matcher(br.getUsername()).matches()) {
                             boolean exclude = false;
 
                             // excludes override
                             for (Pattern excludePattern : excludePatterns) {
                                 if (excludePattern.matcher(line).matches()) {
-                                    out.verbosePrintln("Excluding " + line + ", matches " + excludePattern);
+                                    out.verbosePrintln("Excluding " + br.getUsername() + ", matches " + excludePattern);
 
                                     exclude = true;
                                     break;
@@ -137,11 +139,11 @@
                             }
 
                             if (!exclude) {
-                                result.add(line);
+                                result.add(br);
                             }
                             break;
                         } else {
-                            out.verbosePrintln("Excluding: " + line + ", does not match " + pattern);
+                            out.verbosePrintln("Excluding: " + br.getUsername() + ", does not match " + pattern);
                         }
                     }
                 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Tue Jun 04 13:28:58 2013 +0400
@@ -24,6 +24,7 @@
  */
 package org.openjdk.jmh.runner;
 
+import org.openjdk.jmh.annotations.BenchmarkType;
 import org.openjdk.jmh.annotations.Fork;
 import org.openjdk.jmh.logic.results.IterationData;
 import org.openjdk.jmh.logic.results.internal.RunResult;
@@ -49,6 +50,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
@@ -145,13 +147,13 @@
             outputHandler = createOutputHandler(options);
         }
 
-        Set<String> benchmarks;
+        Set<BenchmarkRecord> benchmarks;
 
         // get a list of benchmarks
         if (options.getRegexps().isEmpty()) {
             outputHandler.println("No regexp to match against benchmarks was given. Use -h for help or \".*\" for every benchmark.");
             outputHandler.flush();
-            benchmarks = Collections.<String>emptySet();
+            benchmarks = Collections.<BenchmarkRecord>emptySet();
         } else {
             benchmarks = list.find(outputHandler, options.getRegexps(), options.getExcludes());
         }
@@ -165,10 +167,34 @@
             outputHandler.println("Benchmarks: ");
 
             // list microbenchmarks if -l and/or -v
-            for (String benchmark : benchmarks) {
-                outputHandler.println(benchmark);
+            for (BenchmarkRecord benchmark : benchmarks) {
+                outputHandler.println(benchmark.getUsername());
             }
         }
+
+        // override the benchmark type
+        if (options.getBenchType() != null) {
+            for (BenchmarkRecord br : benchmarks) {
+                br.setMode(options.getBenchType());
+            }
+        }
+
+        // clone with all the modes
+        List<BenchmarkRecord> newBenchmarks = new ArrayList<BenchmarkRecord>();
+        for (BenchmarkRecord br : benchmarks) {
+            if (br.getMode() == BenchmarkType.All) {
+                for (BenchmarkType mode : BenchmarkType.values()) {
+                    if (mode == BenchmarkType.All) continue;
+                    newBenchmarks.add(br.cloneWith(mode));
+                }
+            } else {
+                newBenchmarks.add(br);
+            }
+        }
+
+        benchmarks.clear();
+        benchmarks.addAll(newBenchmarks);
+
         // exit if list only, else run benchmarks
         if (!options.shouldList() && !benchmarks.isEmpty()) {
             switch (ExecutionMode.getExecutionMode(options)) {
@@ -196,13 +222,13 @@
      * @param benchmarks
      * @param list
      */
-    private void runBulkWarmupBenchmarks(Set<String> benchmarks, MicroBenchmarkList list) {
+    private void runBulkWarmupBenchmarks(Set<BenchmarkRecord> benchmarks, MicroBenchmarkList list) {
         // Attention: Here is violation of outputHandler.startRun/endRun contract,
         // but because of such code was done before me,
         // I won't touch this in order do not crash output parsers. (SK)
 
         // list of micros executed before iteration
-        Set<String> warmupMicros = new TreeSet<String>();
+        Set<BenchmarkRecord> warmupMicros = new TreeSet<BenchmarkRecord>();
 
         List<String> warmupMicrosRegexp = options.getWarmupMicros();
         if (warmupMicrosRegexp != null && !warmupMicrosRegexp.isEmpty()) {
@@ -222,7 +248,7 @@
             // increased variance.
             // currently valid only for non-external JVM runs
             outputHandler.startRun("Warmup Section");
-            for (String benchmark : warmupMicros) {
+            for (BenchmarkRecord benchmark : warmupMicros) {
                 runBulkWarmupModeMicroBenchmark(benchmark, true);
             }
             outputHandler.endRun(null);
@@ -230,7 +256,7 @@
         // run microbenchmarks
         //
         outputHandler.startRun("Measurement Section");
-        for (String benchmark : benchmarks) {
+        for (BenchmarkRecord benchmark : benchmarks) {
             runBulkWarmupModeMicroBenchmark(benchmark, false);
         }
         outputHandler.endRun(null);
@@ -248,12 +274,12 @@
         }
     }
 
-    private void runBenchmarks(Set<String> benchmarks) {
-        Set<String> embedded = new TreeSet<String>();
-        Set<String> forked = new TreeSet<String>();
+    private void runBenchmarks(Set<BenchmarkRecord> benchmarks) {
+        Set<BenchmarkRecord> embedded = new TreeSet<BenchmarkRecord>();
+        Set<BenchmarkRecord> forked = new TreeSet<BenchmarkRecord>();
 
         outputHandler.startRun("Measurement Section");
-        for (String benchmark : benchmarks) {
+        for (BenchmarkRecord benchmark : benchmarks) {
             int f = decideForks(options.getForkCount(), benchForks(benchmark));
             if (f > 0) {
                 forked.add(benchmark);
@@ -262,7 +288,7 @@
             }
         }
 
-        for (String benchmark : embedded) {
+        for (BenchmarkRecord benchmark : embedded) {
             runClassicBenchmark(benchmark);
         }
 
@@ -270,11 +296,11 @@
         outputHandler.endRun(null);
     }
 
-    private void runSeparate(Set<String> benchmarksToFork) {
+    private void runSeparate(Set<BenchmarkRecord> benchmarksToFork) {
         BinaryOutputFormatReader reader = null;
         try {
             reader = new BinaryOutputFormatReader(outputHandler);
-            for (String benchmark : benchmarksToFork) {
+            for (BenchmarkRecord benchmark : benchmarksToFork) {
                 runSeparateMicroBenchmark(reader, benchmark, reader.getHost(), reader.getPort());
             }
         } catch (IOException e) {
@@ -291,7 +317,7 @@
      * @param benchmark
      * @return
      */
-    private int benchForks(String benchmark) {
+    private int benchForks(BenchmarkRecord benchmark) {
         Method m = MicroBenchmarkHandlers.findBenchmarkMethod(benchmark);
         Fork fork = m.getAnnotation(Fork.class);
         return (fork != null) ? fork.value() : -1;
@@ -304,7 +330,7 @@
      * @param host host VM host
      * @param port host VM port
      */
-    private void runSeparateMicroBenchmark(BinaryOutputFormatReader reader, String benchmark, String host, int port) {
+    private void runSeparateMicroBenchmark(BinaryOutputFormatReader reader, BenchmarkRecord benchmark, String host, int port) {
 
         /*
          * Running microbenchmark in separate JVM requires to read some options from annotations.
@@ -399,12 +425,13 @@
      *
      * @param benchmark benchmark to run
      */
-    private List<IterationData> runBulkWarmupModeMicroBenchmark(String benchmark, boolean warmup) {
+    private List<IterationData> runBulkWarmupModeMicroBenchmark(BenchmarkRecord benchmark, boolean warmup) {
         List<IterationData> allResults = new ArrayList<IterationData>();
         try {
-            int index = benchmark.lastIndexOf('.');
-            String className = benchmark.substring(0, index);
-            String methodName = benchmark.substring(index + 1);
+            String benchName = benchmark.generatedTarget();
+            int index = benchName.lastIndexOf('.');
+            String className = benchName.substring(0, index);
+            String methodName = benchName.substring(index + 1);
 
             Class<?> clazz = ClassUtils.loadClass(className);
             Method method = MicroBenchmarkHandlers.findBenchmarkMethod(clazz, methodName);
@@ -414,7 +441,7 @@
             if (warmup) {
                 executionParams = executionParams.warmupToIteration();
             }
-            outputHandler.startBenchmark(handler.getName(), executionParams, options.isVerbose());
+            outputHandler.startBenchmark(handler.getBenchmark(), executionParams, options.isVerbose());
             int iteration = 0;
             final Collection<ThreadIterationParams> threadIterationSequence = executionParams.getThreadIterationSequence();
             for (ThreadIterationParams tip : threadIterationSequence) {
@@ -425,7 +452,7 @@
             // only print end-of-run output if we have actual results
             if (!allResults.isEmpty()) {
                 RunResult result = aggregateIterationData(allResults);
-                outputHandler.endBenchmark(handler.getName(), result);
+                outputHandler.endBenchmark(handler.getBenchmark(), result);
             }
 
             handler.shutdown();
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/ShotMicroBenchmarkHandler.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/ShotMicroBenchmarkHandler.java	Tue Jun 04 13:28:58 2013 +0400
@@ -66,7 +66,7 @@
      * @param options      Options from the command line
      * @param executionParams
      */
-    ShotMicroBenchmarkHandler(OutputFormat format, String microbenchmark, Class<?> clazz, Method method, BaseOptions options, MicroBenchmarkParameters executionParams) {
+    ShotMicroBenchmarkHandler(OutputFormat format, BenchmarkRecord microbenchmark, Class<?> clazz, Method method, BaseOptions options, MicroBenchmarkParameters executionParams) {
         super(format, microbenchmark, clazz, options, executionParams);
         this.method = method;
         this.shouldFailOnError = options.shouldFailOnError();
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/BaseOptions.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/BaseOptions.java	Tue Jun 04 13:28:58 2013 +0400
@@ -25,7 +25,9 @@
 package org.openjdk.jmh.runner.options;
 
 import org.kohsuke.args4j.Option;
+import org.openjdk.jmh.annotations.BenchmarkType;
 import org.openjdk.jmh.profile.ProfilerFactory;
+import org.openjdk.jmh.runner.options.handlers.BenchmarkTypeOptionHandler;
 import org.openjdk.jmh.runner.options.handlers.BooleanOptionHandler;
 import org.openjdk.jmh.runner.options.handlers.ProfilersOptionHandler;
 import org.openjdk.jmh.runner.options.handlers.ThreadCountsOptionHandler;
@@ -79,6 +81,9 @@
     @Option(name = "-w", aliases = {"--warmup"}, metaVar = "TIME", usage = "Run time for warmup iterations. Result not used when calculating score. Examples 100s, 200ms; defaults to " + Defaults.WARMUP_TIME_SECS + "", handler = TimeValueOptionHandler.class)
     protected TimeValue warmupTime = null;
 
+    @Option(name = "-bt", aliases = {"--type"}, metaVar = "TYPE", usage = "Benchmark type", handler = BenchmarkTypeOptionHandler.class)
+    protected BenchmarkType benchType = null;
+
     @Option(name = "-t", aliases = {"--threads"}, usage = "Number of threads to run the microbenchmark with. Special value \"max\" or 0 will use Runtime.availableProcessors()", handler = ThreadsOptionHandler.class)
     protected int threads = -1;
 
@@ -180,6 +185,9 @@
         if (TimeValue.class.equals(t)) {
             return timeValueFieldToString(f);
         }
+        if (BenchmarkType.class.equals(t)) {
+            return benchTypeFieldToString(f);
+        }
         throw new IllegalArgumentException("Unknown forwarding field type, field="+f.toString());
     }
 
@@ -285,6 +293,19 @@
         }
     }
 
+    private String benchTypeFieldToString(Field f) {
+        try {
+            Object value = f.get(this);
+            if (value != null && value instanceof BenchmarkType) {
+                return f.getAnnotation(Option.class).name() + " " + value;
+            } else {
+                return null;
+            }
+        } catch (IllegalAccessException e) {
+            throw new IllegalAccessError("Caused by: " + e.getMessage());
+        }
+    }
+
     /**
      * Getter
      *
@@ -447,5 +468,7 @@
         return profilers;
     }
 
-
+    public BenchmarkType getBenchType() {
+        return benchType;
+    }
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/HarnessOptions.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/HarnessOptions.java	Tue Jun 04 13:28:58 2013 +0400
@@ -30,6 +30,7 @@
 import org.kohsuke.args4j.Option;
 import org.openjdk.jmh.ForkedMain;
 import org.openjdk.jmh.output.OutputFormatType;
+import org.openjdk.jmh.runner.BenchmarkRecord;
 import org.openjdk.jmh.runner.CompilerHints;
 import org.openjdk.jmh.runner.options.handlers.ForkOptionHandler;
 
@@ -149,7 +150,7 @@
      * @param port host VM port
      * @return the final command to execute
      */
-    public String[] getSeparateExecutionCommand(String benchmark, String annJvmArgs, String annJvmArgsPrepend, String annJvmArgsAppend, String host, int port) {
+    public String[] getSeparateExecutionCommand(BenchmarkRecord benchmark, String annJvmArgs, String annJvmArgsPrepend, String annJvmArgsAppend, String host, int port) {
 
         Properties props = System.getProperties();
         String javaHome = (String) props.get("java.home");
@@ -230,7 +231,7 @@
         // if user supplied micro flags, give those as well
         Collections.addAll(command, toCommandLine());
 
-        command.add(benchmark);
+        command.add(benchmark.toLine());
 
         command.add("--hostName");
         command.add(host);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/handlers/BenchmarkTypeOptionHandler.java	Tue Jun 04 13:28:58 2013 +0400
@@ -0,0 +1,73 @@
+/**
+ * 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.runner.options.handlers;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+import org.openjdk.jmh.annotations.BenchmarkType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * OptionHandler for BenchmarkType options.
+ */
+public class BenchmarkTypeOptionHandler extends OptionHandler<BenchmarkType> {
+
+    /**
+     * Constructor
+     *
+     * @param parser CmdLineParser parent
+     * @param option Run-time copy of the Option
+     * @param setter Setter to feed back the value
+     */
+    public BenchmarkTypeOptionHandler(CmdLineParser parser, OptionDef option, Setter<BenchmarkType> setter) {
+        super(parser, option, setter);
+    }
+
+    @Override
+    public int parseArguments(Parameters params) throws CmdLineException {
+        if (params.size() > 0) {
+            String param = params.getParameter(0);
+            try {
+                BenchmarkType value = BenchmarkType.deepValueOf(param);
+                setter.addValue(value);
+                return 1;
+            } catch (Exception e) {
+                throw new CmdLineException(owner, e.getMessage());
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public String getDefaultMetaVariable() {
+        return "TYPE";
+    }
+}
--- a/jmh-core/src/test/java/org/openjdk/jmh/runner/TestMicroBenchmarkList.java	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/test/java/org/openjdk/jmh/runner/TestMicroBenchmarkList.java	Tue Jun 04 13:28:58 2013 +0400
@@ -60,7 +60,7 @@
         // make sure we get nothing
         excludes.clear();
         excludes.add(".*");
-        Set<String> micros = list.getAll(out, excludes);
+        Set<BenchmarkRecord> micros = list.getAll(out, excludes);
         assertEquals(0, micros.size());
     }
 
@@ -68,7 +68,7 @@
     public void testListGetAll() throws Exception {
         excludes.clear();
         // make sure we get em all
-        Set<String> micros = list.getAll(out, excludes);
+        Set<BenchmarkRecord> micros = list.getAll(out, excludes);
         assertEquals(20, micros.size());
     }
 
@@ -76,7 +76,7 @@
     public void testListFindSingle() throws Exception {
         // check find without excldues
         excludes.clear();
-        Set<String> micros = list.find(out, ".*Hash.*", excludes);
+        Set<BenchmarkRecord> micros = list.find(out, ".*Hash.*", excludes);
         assertEquals(7, micros.size());
     }
 
@@ -85,7 +85,7 @@
         // check find with excludes
         excludes.clear();
         excludes.add(".*Int.*");
-        Set<String> micros = list.find(out, ".*Hash.*", excludes);
+        Set<BenchmarkRecord> micros = list.find(out, ".*Hash.*", excludes);
         assertEquals(2, micros.size());
     }
 
@@ -94,16 +94,16 @@
         // micros should be sorted
         excludes.clear();
         excludes.add(".*Int.*");
-        Set<String> micros = list.find(out, ".*Hash.*", excludes);
-        String first = micros.iterator().next();
-        assertTrue("oracle.micro.benchmarks.api.java.util.concurrent.GeneratedMaps.testConcurrentHashMap".equals(first));
+        Set<BenchmarkRecord> micros = list.find(out, ".*Hash.*", excludes);
+        BenchmarkRecord first = micros.iterator().next();
+        assertTrue("oracle.micro.benchmarks.api.java.util.concurrent.GeneratedMaps.testConcurrentHashMap".equals(first.getUsername()));
     }
 
     @Test
     public void testListGetWithIncludesAndExcludes() throws Exception {
         excludes.clear();
         excludes.add(".*Int.*");
-        Set<String> micros = list.find(out, ".*Concurrent.*", excludes);
+        Set<BenchmarkRecord> micros = list.find(out, ".*Concurrent.*", excludes);
         assertEquals(2, micros.size());
     }
 }
--- a/jmh-core/src/test/resources/org/openjdk/jmh/runner/MicroBenchmarks	Tue Jun 04 13:25:13 2013 +0400
+++ b/jmh-core/src/test/resources/org/openjdk/jmh/runner/MicroBenchmarks	Tue Jun 04 13:28:58 2013 +0400
@@ -22,23 +22,23 @@
 #    questions.
 #
 
-oracle.micro.benchmarks.api.java.util.concurrent.NormalMaps.testConcurrentHashMap
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005HashMapGetInt
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005HashMapGetIntGC
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005HashMapGetInteger
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005ResizedHashMapGetInt
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005ResizedHashMapGetInteger
-oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64.printBase64Binary_128bytes
-oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64.printBase64Binary_32bytes
-oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64.printBase64Binary_512bytes
-oracle.micro.benchmarks.api.java.util.concurrent.GeneratedMaps.testConcurrentHashMap
-org.openjdk.jmh.runner.TestMicro.dummy
-org.openjdk.jmh.runner.TestMicro.dummyWarm
-org.openjdk.jmh.runner.TestMicro.dummyWarmOnly
-org.openjdk.jmh.runner.TestMicro.dummySetupPayload
-org.openjdk.jmh.runner.TestMicro.boom_Exception
-org.openjdk.jmh.runner.TestMicro.boom_Error
-org.openjdk.jmh.runner.TestMicro.boom_Throwable
-org.openjdk.jmh.runner.TestMicro.blackholed
-org.openjdk.jmh.runner.TestBrokenMicro.dummyPayload
-org.openjdk.jmh.runner.TestExceptionThrowingMicro.ouch
\ No newline at end of file
+oracle.micro.benchmarks.api.java.util.concurrent.NormalMaps.testConcurrentHashMap, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005HashMapGetInt, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005HashMapGetIntGC, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005HashMapGetInteger, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005ResizedHashMapGetInt, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap.jbb2005ResizedHashMapGetInteger, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64.printBase64Binary_128bytes, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64.printBase64Binary_32bytes, xxx, AverageTimePerOp
+oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64.printBase64Binary_512bytes, xxx, AverageTimePerOp
+oracle.micro.benchmarks.api.java.util.concurrent.GeneratedMaps.testConcurrentHashMap, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.dummy, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.dummyWarm, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.dummyWarmOnly, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.dummySetupPayload, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.boom_Exception, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.boom_Error, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.boom_Throwable, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestMicro.blackholed, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestBrokenMicro.dummyPayload, xxx, AverageTimePerOp
+org.openjdk.jmh.runner.TestExceptionThrowingMicro.ouch, xxx, AverageTimePerOp
\ No newline at end of file