Commit eb2a246e authored by Eric Bruneton's avatar Eric Bruneton

Merge the benchmark projects to remove code duplication.

parent 3c387b5d
Pipeline #552 passed with stage
in 9 minutes and 46 seconds
......@@ -32,68 +32,67 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
/**
* A benchmark to measure the memory usage of several Java bytecode libraries when reading Java
* classes.
* A benchmark to benchmark different versions of ASM and possibly other bytecode libraries.
*
* @author Eric Bruneton
*/
@State(Scope.Thread)
public class MemoryBenchmark {
public abstract class AbstractBenchmark {
// The directories where the different versions of ASM can be found.
private static final String BUILD_DIR = "/benchmarks/memory/build/";
private static final String BUILD_DIR = "/benchmarks/build/";
private static final String ASM4_0 = BUILD_DIR + "asm4.0/";
private static final String ASM5_0 = BUILD_DIR + "asm5.0.1/";
private static final String ASM6_0 = BUILD_DIR + "asm6.0/";
private static final String ASM_CORE_6_1 = "/asm/build/classes/java/main/";
private static final String ASM_TREE_6_1 = "/asm-tree/build/classes/java/main/";
// The fully qualified name of the ASMFactory class.
private static final String ASM_FACTORY = "org.objectweb.asm.benchmarks.ASMFactory";
private Factory asm4_0;
private Factory asm5_0;
private Factory asm6_0;
private Factory asm6_1;
private ArrayList<byte[]> classFiles;
private final String asmBenchmarkClass;
private final String userDir;
/** Some class files that can be used as input data for benchmarks. */
protected ArrayList<byte[]> classFiles;
/** The ASM versions that can be benchmarked. */
public enum AsmVersion {
V4_0,
V5_0,
V6_0,
V6_1;
URL[] getUrls(final String baseUrl) throws MalformedURLException {
switch (this) {
case V4_0:
return new URL[] {new URL(baseUrl + ASM4_0)};
case V5_0:
return new URL[] {new URL(baseUrl + ASM5_0)};
case V6_0:
return new URL[] {new URL(baseUrl + ASM6_0)};
case V6_1:
return new URL[] {new URL(baseUrl + ASM_CORE_6_1), new URL(baseUrl + ASM_TREE_6_1)};
default:
throw new AssertionError();
}
}
}
/**
* Prepares the benchmark by creating a {@link Factory} for each library to be tested, and by
* loading some test data (i.e. some classes to read).
* Constructs a new {@link AbstractBenchmark}.
*
* @throws Exception if an error occurs.
* @param asmBenchmarkClass the benchmark class to instantiate for the ASM benchmarks.
*/
@Setup
public void prepare() throws Exception {
String userDir = System.getProperty("user.dir");
String baseUrl = "file://" + userDir;
asm4_0 = new ASMFactoryFactory(new URL[] {new URL(baseUrl + ASM4_0)}).newAsmFactory();
asm5_0 = new ASMFactoryFactory(new URL[] {new URL(baseUrl + ASM5_0)}).newAsmFactory();
asm6_0 = new ASMFactoryFactory(new URL[] {new URL(baseUrl + ASM6_0)}).newAsmFactory();
asm6_1 =
new ASMFactoryFactory(
new URL[] {new URL(baseUrl + ASM_CORE_6_1), new URL(baseUrl + ASM_TREE_6_1)})
.newAsmFactory();
// Check that the correct versions of ASM have been loaded.
if (!asm4_0.getVersion().equals("ASM4")
|| !asm5_0.getVersion().equals("ASM5")
|| !asm6_0.getVersion().equals("ASM6")
|| !asm6_1.getVersion().equals("ASM6")) {
throw new IllegalStateException();
}
protected AbstractBenchmark(final String asmBenchmarkClass) {
this.asmBenchmarkClass = asmBenchmarkClass;
this.userDir = System.getProperty("user.dir");
}
/** Creates and populates {@link #classFiles} with some class files read from disk. */
protected void prepareClasses() throws IOException {
classFiles = new ArrayList<byte[]>();
findClasses(new File(userDir + ASM_CORE_6_1), classFiles);
findClasses(new File(userDir + ASM_TREE_6_1), classFiles);
......@@ -129,88 +128,39 @@ public class MemoryBenchmark {
}
}
@Benchmark
public void newClass_asm4_0() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm4_0.newClass(classFile));
}
}
@Benchmark
public void newClass_asm5_0() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm5_0.newClass(classFile));
}
}
@Benchmark
public void newClass_asm6_0() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm6_0.newClass(classFile));
}
}
@Benchmark
public void newClass_asm6_1() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm6_1.newClass(classFile));
}
}
@Benchmark
public void newClassNode_asm4_0() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm4_0.newClassNode(classFile));
}
}
@Benchmark
public void newClassNode_asm5_0() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm5_0.newClassNode(classFile));
}
}
@Benchmark
public void newClassNode_asm6_0() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm6_0.newClassNode(classFile));
}
}
@Benchmark
public void newClassNode_asm6_1() {
for (byte[] classFile : classFiles) {
MemoryProfiler.keepReference(asm6_1.newClassNode(classFile));
}
}
/** A factory of {@link ASMFactory} objects, using a specific version of the ASM library. */
private static class ASMFactoryFactory extends URLClassLoader {
/** A factory of ASM benchmark objects, using a specific version of the ASM library. */
class AsmBenchmarkFactory extends URLClassLoader {
/**
* Constructs an {@link ASMFactoryFactory}.
* Constructs an {@link AsmBenchmarkFactory}.
*
* @param asmDirectories the directories where the ASM library classes can be found.
* @param asmBenchmarkClass the class that must be instantiated by this factory.
* @throws MalformedURLException
*/
ASMFactoryFactory(final URL[] asmDirectories) {
super(asmDirectories);
AsmBenchmarkFactory(final AsmVersion asmVersion) throws MalformedURLException {
super(asmVersion.getUrls("file://" + userDir));
}
/**
* @return a new {@link ASMFactory} instance.
* @return a new instance of the class specified in the benchmark's constructor.
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws Exception
*/
public Factory newAsmFactory() throws Exception {
return (Factory) loadClass(ASM_FACTORY).newInstance();
public Object newAsmBenchmark()
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return loadClass(asmBenchmarkClass).newInstance();
}
@Override
protected Class<?> loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
// Force the loading of the ASMFactory class by this class loader (and not its parent). This
// is needed to make sure that the classes it references (i.e. the ASM library classes) will
// be loaded by this class loader too.
if (name.startsWith(ASM_FACTORY)) {
// Force the loading of the asmBenchmarkClass class by this class loader (and not its parent).
// This is needed to make sure that the classes it references (i.e. the ASM library classes)
// will be loaded by this class loader too.
if (name.startsWith(asmBenchmarkClass)) {
try {
byte[] classFile =
readInputStream(getResourceAsStream(name.replace('.', '/') + ".class"));
......
......@@ -27,19 +27,15 @@
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
/**
......@@ -48,19 +44,11 @@ import org.openjdk.jmh.infra.Blackhole;
*
* @author Eric Bruneton
*/
@Fork(1)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
public class AdapterBenchmark {
// The directories where the different versions of ASM can be found.
private static final String BUILD_DIR = "/benchmarks/read-write/build/";
private static final String ASM4_0 = BUILD_DIR + "asm4.0/";
private static final String ASM5_0 = BUILD_DIR + "asm5.0.1/";
private static final String ASM6_0 = BUILD_DIR + "asm6.0/";
private static final String ASM_CORE_6_1 = "/asm/build/classes/java/main/";
private static final String ASM_TREE_6_1 = "/asm-tree/build/classes/java/main/";
// The fully qualified name of the ASMAdapter class.
private static final String ASM_ADAPTER = "org.objectweb.asm.benchmarks.ASMAdapter";
public class AdapterBenchmark extends AbstractBenchmark {
private Adapter asm4_0;
private Adapter asm5_0;
......@@ -71,7 +59,9 @@ public class AdapterBenchmark {
private Adapter javassist;
private Adapter serp;
private ArrayList<byte[]> classFiles;
public AdapterBenchmark() {
super("org.objectweb.asm.benchmarks.ASMAdapter");
}
/**
* Prepares the benchmark by creating an {@link Adapter} for each library to be tested, and by
......@@ -81,20 +71,15 @@ public class AdapterBenchmark {
*/
@Setup
public void prepare() throws Exception {
String userDir = System.getProperty("user.dir");
String baseUrl = "file://" + userDir;
asm4_0 = new ASMAdapterFactory(new URL[] {new URL(baseUrl + ASM4_0)}).newAsmAdapter();
asm5_0 = new ASMAdapterFactory(new URL[] {new URL(baseUrl + ASM5_0)}).newAsmAdapter();
asm6_0 = new ASMAdapterFactory(new URL[] {new URL(baseUrl + ASM6_0)}).newAsmAdapter();
asm6_1 =
new ASMAdapterFactory(
new URL[] {new URL(baseUrl + ASM_CORE_6_1), new URL(baseUrl + ASM_TREE_6_1)})
.newAsmAdapter();
asm4_0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V4_0).newAsmBenchmark();
asm5_0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
asm6_0 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
asm6_1 = (Adapter) new AsmBenchmarkFactory(AsmVersion.V6_1).newAsmBenchmark();
aspectJBcel = new AspectJBCELAdapter();
bcel = new BCELAdapter();
javassist = new JavassistAdapter();
serp = new SERPAdapter();
// Check that the correct versions of ASM have been loaded.
if (!asm4_0.getVersion().equals("ASM4")
|| !asm5_0.getVersion().equals("ASM5")
......@@ -103,39 +88,7 @@ public class AdapterBenchmark {
throw new IllegalStateException();
}
classFiles = new ArrayList<byte[]>();
findClasses(new File(userDir + ASM_CORE_6_1), classFiles);
findClasses(new File(userDir + ASM_TREE_6_1), classFiles);
}
private static void findClasses(final File directory, final ArrayList<byte[]> classFiles)
throws IOException {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
findClasses(file, classFiles);
} else if (file.getName().endsWith(".class")) {
classFiles.add(readInputStream(new FileInputStream(file)));
}
}
}
private static byte[] readInputStream(final InputStream inputStream) throws IOException {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, bytesRead);
}
outputStream.flush();
return outputStream.toByteArray();
} finally {
try {
inputStream.close();
} catch (IOException e) {
// Nothing to do.
}
}
prepareClasses();
}
@Benchmark
......@@ -410,58 +363,4 @@ public class AdapterBenchmark {
blackhole.consume(asm6_1.readAndWriteWithObjectModel(classFile));
}
}
/** A factory of {@link ASMAdapter} objects, using a specific version of the ASM library. */
private static class ASMAdapterFactory extends URLClassLoader {
/**
* Constructs an {@link ASMAdapterFactory}.
*
* @param asmDirectories the directories where the ASM library classes can be found.
*/
ASMAdapterFactory(final URL[] asmDirectories) {
super(asmDirectories);
}
/**
* @return a new {@link ASMAdapter} instance.
* @throws Exception
*/
public Adapter newAsmAdapter() throws Exception {
return (Adapter) loadClass(ASM_ADAPTER).newInstance();
}
protected Class<?> loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
// Force the loading of the ASMAdapter class by this class loader (and not its parent). This
// is needed to make sure that the classes it references (i.e. the ASM library classes) will
// be loaded by this class loader too.
if (name.startsWith(ASM_ADAPTER)) {
try {
byte[] classFile =
readInputStream(getResourceAsStream(name.replace('.', '/') + ".class"));
Class<?> c = defineClass(name, classFile, 0, classFile.length);
if (resolve) {
resolveClass(c);
}
return c;
} catch (Exception e) {
throw new ClassNotFoundException(name, e);
}
}
// Look for the specified class *first* in asmDirectories, *then* using the parent class
// loader. This is the reverse of the default lookup order, and is necessary to make sure we
// load the correct version of ASM (the parent class loader may have an ASM version in its
// class path, because some components of the JMH framework depend on ASM).
try {
Class<?> c = findClass(name);
if (resolve) {
resolveClass(c);
}
return c;
} catch (ClassNotFoundException e) {
return super.loadClass(name, resolve);
}
}
}
}
......@@ -27,17 +27,15 @@
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
/**
* A benchmark to measure the performance of several libraries when generating a "Hello World!"
......@@ -45,31 +43,28 @@ import org.openjdk.jmh.annotations.State;
*
* @author Eric Bruneton
*/
@Fork(1)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
public class GeneratorBenchmark {
// The directories where the different versions of ASM can be found.
private static final String BUILD_DIR = "/benchmarks/write/build/";
private static final String ASM4_0 = BUILD_DIR + "asm4/";
private static final String ASM5_0 = BUILD_DIR + "asm5/";
private static final String ASM6_0 = BUILD_DIR + "asm6/";
private static final String ASM6_1 = "/asm/build/classes/java/main/";
// The fully qualified name of the ASMGenerator class.
private static final String ASM_GENERATOR = "org.objectweb.asm.benchmarks.ASMGenerator";
Generator asm4_0;
Generator asm5_0;
Generator asm6_0;
Generator asm6_1;
Generator aspectJBcel;
Generator bcel;
Generator cojen;
Generator csgBytecode;
Generator gnuByteCode;
Generator jclassLib;
Generator jiapi;
Generator mozillaClassFile;
public class GeneratorBenchmark extends AbstractBenchmark {
private Generator asm4_0;
private Generator asm5_0;
private Generator asm6_0;
private Generator asm6_1;
private Generator aspectJBcel;
private Generator bcel;
private Generator cojen;
private Generator csgBytecode;
private Generator gnuByteCode;
private Generator jclassLib;
private Generator jiapi;
private Generator mozillaClassFile;
public GeneratorBenchmark() {
super("org.objectweb.asm.benchmarks.ASMGenerator");
}
/**
* Prepares the benchmark by creating a {@link Generator} for each library to be tested.
......@@ -78,11 +73,10 @@ public class GeneratorBenchmark {
*/
@Setup
public void prepare() throws Exception {
String userDir = System.getProperty("user.dir");
asm4_0 = new ASMGeneratorFactory(userDir + ASM4_0).newAsmGenerator();
asm5_0 = new ASMGeneratorFactory(userDir + ASM5_0).newAsmGenerator();
asm6_0 = new ASMGeneratorFactory(userDir + ASM6_0).newAsmGenerator();
asm6_1 = new ASMGeneratorFactory(userDir + ASM6_1).newAsmGenerator();
asm4_0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V4_0).newAsmBenchmark();
asm5_0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
asm6_0 = (Generator) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
asm6_1 = (Generator) new AsmBenchmarkFactory(AsmVersion.V6_1).newAsmBenchmark();
aspectJBcel = new AspectJBCELGenerator();
bcel = new BCELGenerator();
cojen = new CojenGenerator();
......@@ -91,6 +85,7 @@ public class GeneratorBenchmark {
jclassLib = new JClassLibGenerator();
jiapi = new JiapiGenerator();
mozillaClassFile = new MozillaClassFileGenerator();
// Check that the correct versions of ASM have been loaded.
if (!asm4_0.getVersion().equals("ASM4")
|| !asm5_0.getVersion().equals("ASM5")
......@@ -159,65 +154,4 @@ public class GeneratorBenchmark {
public byte[] mozillaClassFile() {
return mozillaClassFile.generateClass();
}
/** A factory of {@link ASMGenerator} objects, using a specific version of the ASM library. */
private static class ASMGeneratorFactory extends URLClassLoader {
/**
* Constructs a {@link ASMGeneratorFactory}.
*
* @param asmDirectory the directory where the ASM library classes can be found.
* @throws MalformedURLException
*/
ASMGeneratorFactory(final String asmDirectory) throws MalformedURLException {
super(new URL[] {new URL("file://" + asmDirectory)});
}
/**
* @return a new {@link ASMGenerator} instance.
* @throws Exception
*/
public Generator newAsmGenerator() throws Exception {
return (Generator) loadClass(ASM_GENERATOR).newInstance();
}
protected Class<?> loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
// Force the loading of the ASMGenerator class by this class loader (and not its parent). This
// is needed to make sure that the classes it references (i.e. the ASM library classes) will
// be loaded by this class loader too.
if (name.equals(ASM_GENERATOR)) {
try (InputStream inputStream = getResourceAsStream(name.replace('.', '/') + ".class")) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[inputStream.available()];
int bytesRead;
while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, bytesRead);
}
outputStream.flush();
byte[] classFile = outputStream.toByteArray();
Class<?> c = defineClass(name, classFile, 0, classFile.length);
if (resolve) {
resolveClass(c);
}
return c;
} catch (Exception e) {
throw new ClassNotFoundException(name, e);
}
}
// Look for the specified class *first* in asmDirectory, *then* using the parent class loader.
// This is the reverse of the default lookup order, and is necessary to make sure we load the
// correct version of ASM (the parent class loader may have an ASM version in its class path,
// because some components of the JMH framework depend on ASM).
try {
Class<?> c = findClass(name);
if (resolve) {
resolveClass(c);
}
return c;
} catch (ClassNotFoundException e) {
return super.loadClass(name, resolve);
}
}
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
/**
* A benchmark to measure the memory usage of several Java bytecode libraries when reading Java
* classes.
*
* @author Eric Bruneton
*/
@Fork(1)
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
public class MemoryBenchmark extends AbstractBenchmark {
private Factory asm4_0;
private Factory asm5_0;
private Factory asm6_0;
private Factory asm6_1;
public MemoryBenchmark() {
super("org.objectweb.asm.benchmarks.ASMFactory");
}
/**
* Prepares the benchmark by creating a {@link Factory} for each library to be tested, and by
* loading some test data (i.e. some classes to read).
*
* @throws Exception if an error occurs.
*/
@Setup
public void prepare() throws Exception {
asm4_0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V4_0).newAsmBenchmark();
asm5_0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V5_0).newAsmBenchmark();
asm6_0 = (Factory) new AsmBenchmarkFactory(AsmVersion.V6_0).newAsmBenchmark();
asm6_1 = (Factory) new AsmBenchmarkFactory(AsmVersion.V6_1).newAsmBenchmark();
// Check that the correct versions of ASM have been loaded.
if (!asm4_0.getVersion().equals("ASM4")
|| !asm5_0.getVersion().equals("ASM5")
|| !asm6_0.getVersion().equals("ASM6")
|| !asm6_1.getVersion().equals("ASM6")) {