--- /dev/null 2017-03-31 09:06:27.183526083 -0400 +++ new/test/runtime/valhalla/valuetypes/ValueTypeGenerator.java 2017-06-20 16:29:17.122470883 -0400 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2017, 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. + * + * 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. + */ + +import java.lang.reflect.Type; +import java.util.Random; + +public class ValueTypeGenerator { + + static class FieldDescriptor { + + final public String name; + final public Type type; + + public FieldDescriptor(String name, Type type) { + this.name = name; + this.type = type; + } + } + + static Type[] typeArray; + static String[] defaultArray; + static int NB_TYPES = 9; + + static { + typeArray = new Type[NB_TYPES]; + typeArray[0] = byte.class; + typeArray[1] = short.class; + typeArray[2] = int.class; + typeArray[3] = long.class; + typeArray[4] = char.class; + typeArray[5] = float.class; + typeArray[6] = double.class; + typeArray[7] = boolean.class; + typeArray[8] = Object.class; + + } + + static String defaultValue(Type t) { + switch(t.getTypeName()) { + case "byte": return "(byte)123"; + case "short": return "(short)32056"; + case "int": return "483647"; + case "long": return "922337203685477L"; + case "char": return "(char)65456"; + case "float": return "2.71828f"; + case "double": return "3.14159d"; + case "boolean": return "true"; + case "java.lang.Object": return "null"; + default: + throw new RuntimeException(); + } + } + static private String generateValueTypeInternal(Random random, String name, int nfields, int typeLimit) { + // generate the fields + FieldDescriptor[] fieldDescArray = new FieldDescriptor[nfields]; + for (int i = 0; i < nfields; i++) { + int idx = random.nextInt(typeLimit); + String fieldName = typeArray[idx].getTypeName()+"Field"+i; + fieldDescArray[i] = new FieldDescriptor(fieldName, typeArray[idx]); + } + + String source = generateSource(name, fieldDescArray); + return source; + } + + static public String generateValueType(Random random, String name, int nfields) { + return generateValueTypeInternal(random, name, nfields, NB_TYPES); + } + + static public String generateValueTypeNoObjectRef(Random random, String name, int nfields) { + return generateValueTypeInternal(random, name, nfields, NB_TYPES - 1); + } + + static String fieldsAsArgs(FieldDescriptor[] fields) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < fields.length; i++) { + sb.append(fields[i].type).append(" ").append(fields[i].name); + if (i != fields.length - 1) { + sb.append(", "); + } + } + return sb.toString(); + } + + static String generateSource(String name, FieldDescriptor[] fields) { + StringBuilder sb = new StringBuilder(); + + // imports + sb.append("import java.io.PrintStream;\n\n"); + + // class declaration + sb.append("public __ByValue final class ").append(name).append(" {\n"); + + // field declarations + for (FieldDescriptor f : fields) { + sb.append("\tfinal public ").append(f.type).append(" "); + sb.append(f.name).append(";\n"); + } + sb.append("\n"); + + // private constructor + sb.append("\tprivate ").append(name).append("() {\n"); + for (int i = 0 ; i < fields.length; i++) { + sb.append("\t\tthis.").append(fields[i].name).append(" = ").append(defaultValue(fields[i].type)).append(";\n"); + } + sb.append("\t}\n"); + sb.append("\n"); + + // factory + sb.append("\t__ValueFactory static public ").append(name).append(" ").append("make").append(name).append("("); + sb.append(fieldsAsArgs(fields)); + sb.append(") {\n"); + sb.append("\t\t").append(name).append(" v = ").append("__MakeDefault ").append(name).append("();\n"); + for (int i = 0 ; i < fields.length; i++) { + sb.append("\t\tv.").append(fields[i].name).append(" = ").append(fields[i].name).append(";\n"); + } + sb.append("\t\treturn v;\n"); + sb.append("\t};\n"); + sb.append("\n"); + + // default factory + sb.append("\t__ValueFactory static public ").append(name).append(" ").append("make").append(name).append("() {\n"); + sb.append("\t\t").append(name).append(" v = ").append("__MakeDefault ").append(name).append("();\n"); + for (int i = 0 ; i < fields.length; i++) { + sb.append("\t\tv.").append(fields[i].name).append(" = ").append(defaultValue(fields[i].type)).append(";\n"); + } + sb.append("\t\treturn v;\n"); + sb.append("\t}\n"); + sb.append("\n"); + + // verify method + sb.append("\tstatic public boolean verify(").append(name).append(" value) {\n"); + for (FieldDescriptor f : fields) { + sb.append("\t\tif (value.").append(f.name).append(" != ").append(defaultValue(f.type)).append(") return false;\n"); + } + sb.append("\t\treturn true;\n"); + sb.append("\t}\n"); + + // printLayout method + sb.append("\tstatic public void printLayout(PrintStream out) {\n"); + sb.append("\t\tout.println(\"").append(name).append(" fields: "); + for (int i = 0; i < fields.length; i++) { + sb.append(fields[i].type); + if (i != fields.length - 1) { + sb.append(", "); + } + } + sb.append("\");\n"); + sb.append("\t}\n"); + + sb.append("}\n"); + + return sb.toString(); + } +}