Path: blob/master/test/hotspot/jtreg/vmTestbase/metaspace/stressHierarchy/common/generateHierarchy/GenerateHierarchyHelper.java
41162 views
/*1* Copyright (c) 2013, 2020, Oracle and/or its affiliates. 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*/22package metaspace.stressHierarchy.common.generateHierarchy;2324import java.util.*;2526import vm.share.InMemoryJavaCompiler;27import jdk.test.lib.Utils;2829public class GenerateHierarchyHelper {3031public static enum Type {32CLASSES, INTERFACES, MIXED;33}3435// Class-container that represents generated source file36private static class ClassDescriptor {public String fullName; public CharSequence sourceCode; }3738private static enum Inheritance {39CLASS_EXTENDS_CLASS, CLASS_IMPLEMENTS_INTERFACE, INTERFACE_EXTENDS_INTERFACE40}4142private static final int EDGE_IN_MIXED_CASE = 30;4344private static Random random = Utils.getRandomInstance();4546public static TreeDescriptor generateHierarchy(int depth, int minLevelSize, int maxLevelSize, Type type) {47TreeDescriptor tree = new TreeDescriptor();48Map<String, CharSequence> sourceMap = new HashMap<String, CharSequence>();49int numberOfNodesInPrevLevel = 1;5051// generate root52String packageName = composePackageName(0, 0);53String className = packageName + ".Dummy";54switch (type) {55case CLASSES:56sourceMap.put(className, "package " + packageName +";\n public class Dummy { " +57"public int calculate2() {return hashCode();} " +58"public double calculate() {return hashCode() + 0.1;} " +59"public String composeString() {return \"_root_\";}" +60"}");61break;62default:63sourceMap.put(className, "package " + packageName + ";\n public interface Dummy {}");64}65tree.addNode(0, 0, 0, className);6667for (int level = 1; level < depth; level++) {68int nodesInLevel = minLevelSize + random.nextInt(maxLevelSize - minLevelSize);69for (int nodeIndex = 0; nodeIndex < nodesInLevel; nodeIndex++) {70int parent = random.nextInt(numberOfNodesInPrevLevel);71Inheritance inheritance = null;72switch (type) {73case CLASSES:74inheritance = Inheritance.CLASS_EXTENDS_CLASS;75break;76case INTERFACES:77inheritance = Inheritance.INTERFACE_EXTENDS_INTERFACE;78break;79case MIXED:80inheritance = level < EDGE_IN_MIXED_CASE ? Inheritance.INTERFACE_EXTENDS_INTERFACE81: (level == EDGE_IN_MIXED_CASE ? Inheritance.CLASS_IMPLEMENTS_INTERFACE82: Inheritance.CLASS_EXTENDS_CLASS);83break;84}8586ClassDescriptor classDescriptor = generateClassCode(level, nodeIndex, parent, inheritance);87sourceMap.put(classDescriptor.fullName, classDescriptor.sourceCode);88tree.addNode(level, nodeIndex, parent, classDescriptor.fullName);89}90numberOfNodesInPrevLevel = nodesInLevel;91}92Map<String, byte[]> bytecodeMap = InMemoryJavaCompiler.compile(sourceMap);93for (NodeDescriptor nodeDescriptor : tree.nodeDescriptorList) {94nodeDescriptor.bytecode = bytecodeMap.get(nodeDescriptor.className);95}96return tree;97}9899private static String composePackageName(int level, int nodeIndex) {100return "package_level" + level + "_num" + nodeIndex;101}102103private static ClassDescriptor generateClassCode(int level, int nodeIndex, int parent, Inheritance inheritance) {104ClassDescriptor result = new ClassDescriptor();105String packageName = composePackageName(level, nodeIndex);106String parentPackage = composePackageName(level - 1, parent);107result.fullName = packageName + ".Dummy";108StringBuffer source = new StringBuffer("package ");109source.append(packageName + ";\n\n");110111switch (inheritance) {112case INTERFACE_EXTENDS_INTERFACE:113source.append(" public interface Dummy extends " + parentPackage + ".Dummy {}");114break;115case CLASS_EXTENDS_CLASS:116source.append(" public class Dummy extends " + parentPackage + ".Dummy { " +117"public int calculate2() {return (super.calculate2() + hashCode() % 1000);} " +118"public double calculate() {return (super.calculate() + hashCode() + 0.1);} " +119"public String composeString() {return super.composeString() + \"_" + packageName + "_\";}" +120"}");121break;122case CLASS_IMPLEMENTS_INTERFACE:123source.append(" public class Dummy implements " + parentPackage + ".Dummy { " +124"public int calculate2() {return hashCode();} " +125"public double calculate() {return hashCode() + 0.1;} " +126"public String composeString() {return \"_ancestor_class_\";}" +127"}");128break;129}130131result.sourceCode = source;132return result;133}134135}136137138