36 import java.nio.file.Paths; 37 import java.security.ProtectionDomain; 38 import java.util.Properties; 39 40 import static jdk.internal.org.objectweb.asm.Opcodes.*; 41 42 import jdk.internal.misc.JavaLangAccess; 43 import jdk.internal.misc.SharedSecrets; 44 public class MinimalValueTypes_1_0 { 45 46 public static final int V53_1 = 1 << 16 | 53; 47 public static final int ACC_VALUE = ACC_NATIVE; 48 public static final String OBJECT_CLASS_DESC = "java/lang/Object"; 49 public static final String VALUE_CLASS_DESC = "java/lang/__Value"; 50 51 public static final String DERIVE_VALUE_TYPE_DESC = "Ljvm/internal/value/DeriveValueType;"; 52 public static final String DERIVE_VT_CLASSNAME_POSTFIX = "$Value"; 53 public static final int DERIVE_VT_CLASS_ACCESS = ACC_PUBLIC|ACC_SUPER|ACC_FINAL|ACC_VALUE|ACC_SYNTHETIC; 54 55 public static final boolean DUMP_CLASS_FILES; 56 private static final JavaLangAccess JLA; 57 58 static { 59 // Use same property as in j.l.invoke.MethodHandleStatics 60 Properties props = GetPropertyAction.privilegedGetProperties(); 61 DUMP_CLASS_FILES = Boolean.parseBoolean( 62 props.getProperty("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES")); 63 64 JLA = SharedSecrets.getJavaLangAccess(); 65 } 66 67 public static String getValueTypeClassName(ValueTypeDesc valueTypeDesc) { 68 return getValueTypeClassName(valueTypeDesc.getName()); 69 } 70 71 public static String getValueTypeClassName(String vccName) { 72 return vccName + DERIVE_VT_CLASSNAME_POSTFIX; 73 } 74 75 public static String getValueCapableClassName(String valName) { 76 return valName.substring(0, valName.length() - DERIVE_VT_CLASSNAME_POSTFIX.length()); 77 } 78 79 public static boolean isValueType(Class<?> dvt) { 80 return (dvt.getModifiers() & ACC_VALUE) != 0; 81 } 82 83 public static boolean isValueCapable(Class<?> vcc) { 84 return vcc.getDeclaredAnnotation(jvm.internal.value.DeriveValueType.class) != null; 115 * 116 * @param fds : name/sig pairs 117 * @param fmods : field modifiers 118 */ 119 public static String createDerivedValueType(String vccInternalClassName, 120 ClassLoader cl, 121 ProtectionDomain pd, 122 String[] fds, 123 int[] fmods) { 124 String vtInternalClassName = getValueTypeClassName(vccInternalClassName); 125 ValueTypeDesc valueTypeDesc = new ValueTypeDesc(vccInternalClassName, fds, fmods); 126 byte[] valueTypeBytes = createValueType(valueTypeDesc); 127 Class<?> vtClass = Unsafe.getUnsafe().defineClass(vtInternalClassName, valueTypeBytes, 0, valueTypeBytes.length, cl, pd); 128 return vtInternalClassName; 129 } 130 131 public static byte[] createValueType(ValueTypeDesc valueTypeDesc) { 132 133 String valueTypeClassName = getValueTypeClassName(valueTypeDesc); 134 135 BasicClassBuilder builder = new BasicClassBuilder(valueTypeClassName, 53, 1) 136 .withFlags(DERIVE_VT_CLASS_ACCESS) 137 .withSuperclass(VALUE_CLASS_DESC); 138 139 ValueTypeDesc.Field[] fields = valueTypeDesc.getFields(); 140 for (ValueTypeDesc.Field field : fields) { 141 builder.withField(field.name, field.type, F -> F.withFlags(field.modifiers)); 142 } 143 144 byte[] newBytes = builder.build(); 145 maybeDump(valueTypeClassName, newBytes); 146 return newBytes; 147 } 148 149 /** debugging flag for saving generated class files */ 150 private static final Path DUMP_CLASS_FILES_DIR; 151 152 static { 153 if (DUMP_CLASS_FILES) { 154 try { 155 Path dumpDir = Paths.get("DUMP_CLASS_FILES"); 156 Files.createDirectories(dumpDir); 157 DUMP_CLASS_FILES_DIR = dumpDir; 172 //dumpName = dumpName.replace('/', '-'); 173 Path dumpFile = DUMP_CLASS_FILES_DIR.resolve(dumpName + ".class"); 174 System.out.println("dump: " + dumpFile); 175 try (OutputStream os = Files.newOutputStream(dumpFile); 176 BufferedOutputStream bos = new BufferedOutputStream(os)) { 177 bos.write(classFile); 178 } catch (IOException ex) { 179 throw new InternalError(ex); 180 } 181 return null; 182 } 183 }); 184 185 } 186 } 187 188 private final native Class<?> getDerivedValueType(Class<?> ofClass); 189 190 public static Class<?> getValueClass() { 191 return (Class<?>)(Object)__Value.class; //hack around static type-system checks 192 } 193 } | 36 import java.nio.file.Paths; 37 import java.security.ProtectionDomain; 38 import java.util.Properties; 39 40 import static jdk.internal.org.objectweb.asm.Opcodes.*; 41 42 import jdk.internal.misc.JavaLangAccess; 43 import jdk.internal.misc.SharedSecrets; 44 public class MinimalValueTypes_1_0 { 45 46 public static final int V53_1 = 1 << 16 | 53; 47 public static final int ACC_VALUE = ACC_NATIVE; 48 public static final String OBJECT_CLASS_DESC = "java/lang/Object"; 49 public static final String VALUE_CLASS_DESC = "java/lang/__Value"; 50 51 public static final String DERIVE_VALUE_TYPE_DESC = "Ljvm/internal/value/DeriveValueType;"; 52 public static final String DERIVE_VT_CLASSNAME_POSTFIX = "$Value"; 53 public static final int DERIVE_VT_CLASS_ACCESS = ACC_PUBLIC|ACC_SUPER|ACC_FINAL|ACC_VALUE|ACC_SYNTHETIC; 54 55 public static final boolean DUMP_CLASS_FILES; 56 public static final boolean MANGLE_CLASS_INFO; 57 private static final JavaLangAccess JLA; 58 59 static { 60 // Use same property as in j.l.invoke.MethodHandleStatics 61 Properties props = GetPropertyAction.privilegedGetProperties(); 62 DUMP_CLASS_FILES = Boolean.parseBoolean( 63 props.getProperty("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES")); 64 65 JLA = SharedSecrets.getJavaLangAccess(); 66 MANGLE_CLASS_INFO = Boolean.parseBoolean( 67 props.getProperty("valhalla.mangleClassInfo")); 68 } 69 70 public static String getValueTypeClassName(ValueTypeDesc valueTypeDesc) { 71 return getValueTypeClassName(valueTypeDesc.getName()); 72 } 73 74 public static String getValueTypeClassName(String vccName) { 75 return vccName + DERIVE_VT_CLASSNAME_POSTFIX; 76 } 77 78 public static String getValueCapableClassName(String valName) { 79 return valName.substring(0, valName.length() - DERIVE_VT_CLASSNAME_POSTFIX.length()); 80 } 81 82 public static boolean isValueType(Class<?> dvt) { 83 return (dvt.getModifiers() & ACC_VALUE) != 0; 84 } 85 86 public static boolean isValueCapable(Class<?> vcc) { 87 return vcc.getDeclaredAnnotation(jvm.internal.value.DeriveValueType.class) != null; 118 * 119 * @param fds : name/sig pairs 120 * @param fmods : field modifiers 121 */ 122 public static String createDerivedValueType(String vccInternalClassName, 123 ClassLoader cl, 124 ProtectionDomain pd, 125 String[] fds, 126 int[] fmods) { 127 String vtInternalClassName = getValueTypeClassName(vccInternalClassName); 128 ValueTypeDesc valueTypeDesc = new ValueTypeDesc(vccInternalClassName, fds, fmods); 129 byte[] valueTypeBytes = createValueType(valueTypeDesc); 130 Class<?> vtClass = Unsafe.getUnsafe().defineClass(vtInternalClassName, valueTypeBytes, 0, valueTypeBytes.length, cl, pd); 131 return vtInternalClassName; 132 } 133 134 public static byte[] createValueType(ValueTypeDesc valueTypeDesc) { 135 136 String valueTypeClassName = getValueTypeClassName(valueTypeDesc); 137 138 BasicClassBuilder builder = new BasicClassBuilder(mangleValueClassName(valueTypeClassName), 53, 1) 139 .withFlags(DERIVE_VT_CLASS_ACCESS) 140 .withSuperclass(mangleValueClassName(VALUE_CLASS_DESC)); 141 142 ValueTypeDesc.Field[] fields = valueTypeDesc.getFields(); 143 for (ValueTypeDesc.Field field : fields) { 144 builder.withField(field.name, field.type, F -> F.withFlags(field.modifiers)); 145 } 146 147 byte[] newBytes = builder.build(); 148 maybeDump(valueTypeClassName, newBytes); 149 return newBytes; 150 } 151 152 /** debugging flag for saving generated class files */ 153 private static final Path DUMP_CLASS_FILES_DIR; 154 155 static { 156 if (DUMP_CLASS_FILES) { 157 try { 158 Path dumpDir = Paths.get("DUMP_CLASS_FILES"); 159 Files.createDirectories(dumpDir); 160 DUMP_CLASS_FILES_DIR = dumpDir; 175 //dumpName = dumpName.replace('/', '-'); 176 Path dumpFile = DUMP_CLASS_FILES_DIR.resolve(dumpName + ".class"); 177 System.out.println("dump: " + dumpFile); 178 try (OutputStream os = Files.newOutputStream(dumpFile); 179 BufferedOutputStream bos = new BufferedOutputStream(os)) { 180 bos.write(classFile); 181 } catch (IOException ex) { 182 throw new InternalError(ex); 183 } 184 return null; 185 } 186 }); 187 188 } 189 } 190 191 private final native Class<?> getDerivedValueType(Class<?> ofClass); 192 193 public static Class<?> getValueClass() { 194 return (Class<?>)(Object)__Value.class; //hack around static type-system checks 195 } 196 197 public static String mangleValueClassName(String name) { 198 return MANGLE_CLASS_INFO ? 199 ";Q" + name + ";" : 200 name; 201 } 202 } |