Path: blob/master/test/jdk/java/lang/instrument/ManyMethodsBenchmarkApp.java
41152 views
/*1* Copyright 2015 Google Inc. All Rights Reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.File;24import java.io.FileWriter;25import java.io.PrintStream;26import java.lang.reflect.InvocationTargetException;27import java.lang.reflect.Method;28import java.lang.reflect.Type;29import java.net.URL;30import java.net.URLClassLoader;31import java.util.Arrays;32import java.util.List;33import javax.tools.JavaCompiler;34import javax.tools.StandardJavaFileManager;35import javax.tools.ToolProvider;3637/**38* A manual benchmark of the JVMTI RedefineClasses when a39* single class (and its parent) contains many methods.40*/41public class ManyMethodsBenchmarkApp {42// Limit is 64k but we can not put such many as the CP limit is 32k.43// In practice, it means a real limit is much lower (less than 22000).44static final int METHOD_COUNT = 20000;4546static Class<?> loadClassInNewClassLoader(String className) throws Exception {47URL[] urls = { new File(".").toURI().toURL() };48URLClassLoader ucl = new URLClassLoader(urls, null);49Class<?> klazz = Class.forName(className, true, ucl);50return klazz;51}5253static void benchmarkClassOperations(String className) throws Exception {54Class<?> klazz = loadClassInNewClassLoader(className);5556Method[] methods = klazz.getDeclaredMethods();57if (methods.length != METHOD_COUNT) {58throw new AssertionError("unexpected method count: " + methods.length +59" expected: " + METHOD_COUNT);60}6162methods = klazz.getMethods();63// returned methods includes those inherited from Object64int objectMethodSlop = 100;65if (methods.length <= METHOD_COUNT ||66methods.length >= METHOD_COUNT + objectMethodSlop) {67throw new AssertionError("unexpected method count: " + methods.length);68}6970// Invoke methods to make them appear in the constant pool cache71Object obj = klazz.newInstance();72Object[] args = new Object[0];73for (Method m: methods) {74try {75Class<?>[] types = m.getParameterTypes();76String name = m.getName();77// System.out.println("method: " + name + "; argno: " + types.length);78if (types.length == 0 && name.length() == 2 && name.startsWith("f")) {79m.invoke(obj, args);80}81} catch (InvocationTargetException ex) {82ex.printStackTrace();83}84}85}8687public static void main(String[] args) throws Exception {88System.out.println("test started: ManyMethodsBenchmarkApp");8990// Create source files with many methods91File base = new File("Base.java");92try (FileWriter fw = new FileWriter(base)) {93fw.write("public class Base {\n");94final int L = 10;95// Each of the first L methods makes calls to its own chunk of METHOD_COUNT/L methods96for (int k = 0; k < L; k++) {97fw.write(" public void f" + k + "() {\n");98int shift = (k == 0) ? L : 0;99for (int i = (k * (METHOD_COUNT/L)) + shift; i < (k + 1) * METHOD_COUNT/L; i++) {100fw.write(" f" + i + "();\n");101}102fw.write(" }\n");103}104105// The rest of (METHOD_COUNT - L) methods have empty body106for (int i = L; i < METHOD_COUNT; i++) {107fw.write(" public static void f" + i + "() {}\n");108}109fw.write("}\n");110}111112// Compile the generated source files.113JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();114List<File> files = Arrays.asList(new File[] { base });115try (StandardJavaFileManager fileManager =116compiler.getStandardFileManager(null, null, null)) {117compiler.getTask(null, fileManager, null, null, null,118fileManager.getJavaFileObjectsFromFiles(files))119.call();120}121122benchmarkClassOperations("Base");123124ManyMethodsBenchmarkAgent.instr();125126// Cleanup127base.delete();128new File("Base.class").delete();129if (!ManyMethodsBenchmarkAgent.completed) {130throw new Exception("ERROR: ManyMethodsBenchmarkAgent did not complete.");131}132133if (ManyMethodsBenchmarkAgent.fail) {134throw new Exception("ERROR: ManyMethodsBenchmarkAgent failed.");135} else {136System.out.println("ManyMethodsBenchmarkAgent succeeded.");137}138System.out.println("test finished: ManyMethodsBenchmarkApp");139}140}141142143