< prev index next >
jdk/src/java.base/share/classes/valhalla/shady/MinimalValueTypes_1_0.java
Print this page
*** 27,45 ****
--- 27,47 ----
import jdk.experimental.bytecode.BasicClassBuilder;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
import sun.security.action.GetPropertyAction;
+ import java.lang.annotation.Annotation;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.ProtectionDomain;
import java.util.Properties;
+ import java.util.concurrent.ConcurrentHashMap;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
*** 48,58 ****
public static final int V53_1 = 1 << 16 | 53;
public static final int ACC_VALUE = ACC_NATIVE;
public static final String OBJECT_CLASS_DESC = "java/lang/Object";
public static final String VALUE_CLASS_DESC = "java/lang/__Value";
! public static final String DERIVE_VALUE_TYPE_DESC = "Ljvm/internal/value/ValueCapableClass;";
public static final String DERIVE_VT_CLASSNAME_POSTFIX = "$Value";
public static final int DERIVE_VT_CLASS_ACCESS = ACC_PUBLIC|ACC_SUPER|ACC_FINAL|ACC_VALUE|ACC_SYNTHETIC;
public static final boolean DUMP_CLASS_FILES;
private static final boolean VALUE_TYPE_ENABLED;
--- 50,60 ----
public static final int V53_1 = 1 << 16 | 53;
public static final int ACC_VALUE = ACC_NATIVE;
public static final String OBJECT_CLASS_DESC = "java/lang/Object";
public static final String VALUE_CLASS_DESC = "java/lang/__Value";
! public static final String DERIVE_VALUE_TYPE_DESC = "Ljdk/incubator/mvt/ValueCapableClass;";
public static final String DERIVE_VT_CLASSNAME_POSTFIX = "$Value";
public static final int DERIVE_VT_CLASS_ACCESS = ACC_PUBLIC|ACC_SUPER|ACC_FINAL|ACC_VALUE|ACC_SYNTHETIC;
public static final boolean DUMP_CLASS_FILES;
private static final boolean VALUE_TYPE_ENABLED;
*** 68,99 ****
props.getProperty("valhalla.enableValueType"));
JLA = SharedSecrets.getJavaLangAccess();
}
! public static boolean isValueTypeEnabled() {
! return VALUE_TYPE_ENABLED;
}
! public static String getValueTypeClassName(ValueTypeDesc valueTypeDesc) {
! return getValueTypeClassName(valueTypeDesc.getName());
}
! public static String getValueTypeClassName(String vccName) {
! return vccName + DERIVE_VT_CLASSNAME_POSTFIX;
}
! public static String getValueCapableClassName(String valName) {
! return valName.substring(0, valName.length() - DERIVE_VT_CLASSNAME_POSTFIX.length());
}
public static boolean isValueType(Class<?> dvt) {
return (dvt.getModifiers() & ACC_VALUE) != 0;
}
public static boolean isValueCapable(Class<?> vcc) {
! return vcc.getDeclaredAnnotation(jvm.internal.value.ValueCapableClass.class) != null;
}
public static Class<?> getValueCapableClass(Class<?> dvt) {
if (!isValueType(dvt)) {
throw new IllegalArgumentException(dvt + " is not a derived value type");
--- 70,149 ----
props.getProperty("valhalla.enableValueType"));
JLA = SharedSecrets.getJavaLangAccess();
}
! private static final ConcurrentHashMap<Class<?>, ValueTypeHolder<?>> BOX_TO_VT
! = new ConcurrentHashMap<>();
!
! /**
! * Returns the {@code ValueTypeHolder} representing the value type
! * for the given value capable type.
! *
! * @throws UnsupportedOperationException if MVT is not enabled
! * @throws IllegalArgumentException if the given class is not value capable class
! */
! @SuppressWarnings("unchecked")
! public static <T> ValueTypeHolder<T> getValueFor(Class<T> vcc) {
! if (!MinimalValueTypes_1_0.isValueTypeEnabled()) {
! throw new UnsupportedOperationException("MVT is not enabled");
}
! if (!MinimalValueTypes_1_0.isValueCapable(vcc)) {
! throw new IllegalArgumentException("Class " + vcc + " not a value capable class");
}
! ValueTypeHolder<T> vt = (ValueTypeHolder<T>) BOX_TO_VT.get(vcc);
! if (vt != null) {
! return vt;
}
! Class<T> valueClass = (Class<T>) MinimalValueTypes_1_0.getValueTypeClass(vcc);
! vt = new ValueTypeHolder<T>(vcc, valueClass);
! ValueTypeHolder<T> old = (ValueTypeHolder<T>) BOX_TO_VT.putIfAbsent(vcc, vt);
! if (old != null) {
! vt = old;
! }
! return vt;
! }
!
! /**
! * Returns the {@code ValueTypeHolder} representing the value type
! * for the given class is a derived value type; otherwise {@code null}.
! */
! @SuppressWarnings("unchecked")
! public static <T> ValueTypeHolder<T> findValueType(Class<T> c) {
! if (MinimalValueTypes_1_0.isValueType(c)) {
! return (ValueTypeHolder<T>) getValueFor(MinimalValueTypes_1_0.getValueCapableClass(c));
! } else {
! return null;
! }
! }
!
! /**
! * Returns true if MVT is enabled.
! *
! * jdk.incubator.mvt must be resolved in the boot layer.
! */
! public static boolean isValueTypeEnabled() {
! return VALUE_TYPE_ENABLED;
}
public static boolean isValueType(Class<?> dvt) {
return (dvt.getModifiers() & ACC_VALUE) != 0;
}
+ /**
+ * Returns true if the given class is a value-capable class, i.e.
+ * annotated with @ValueCapableClass.
+ */
public static boolean isValueCapable(Class<?> vcc) {
! if (!isValueTypeEnabled()) {
! return false;
! }
!
! return ValueClassHelper.hasValueCapableAnnotation(vcc);
}
public static Class<?> getValueCapableClass(Class<?> dvt) {
if (!isValueType(dvt)) {
throw new IllegalArgumentException(dvt + " is not a derived value type");
*** 200,221 ****
}
private final native Class<?> getDerivedValueType(Class<?> ofClass);
public static Class<?> getValueClass() {
! return VALUE_TYPE_ENABLED ? ValueClassHolder.CLASS_OBJECT : null;
}
public static String mangleValueClassName(String name) {
return ";Q" + name + ";";
}
/*
! * A holder class that references __Value to be loaded only when MVT is enabled.
! *
! * This holder class would fail verification if loaded if MVT is not enabled.
*/
! private static class ValueClassHolder {
! static final Class<?> CLASS_OBJECT =
(Class<?>)(Object)__Value.class; //hack around static type-system checks
}
}
--- 250,331 ----
}
private final native Class<?> getDerivedValueType(Class<?> ofClass);
public static Class<?> getValueClass() {
! return isValueTypeEnabled() ? ValueClassHelper.VALUE_CLASS : null;
! }
!
! public static String getValueTypeClassName(ValueTypeDesc valueTypeDesc) {
! return getValueTypeClassName(valueTypeDesc.getName());
! }
!
! public static String getValueTypeClassName(String vccName) {
! return vccName + DERIVE_VT_CLASSNAME_POSTFIX;
! }
!
! public static String getValueCapableClassName(String valName) {
! return valName.substring(0, valName.length() - DERIVE_VT_CLASSNAME_POSTFIX.length());
}
public static String mangleValueClassName(String name) {
return ";Q" + name + ";";
}
/*
! * This helper class should only be loaded when MVT is enabled.
! * Otherwise, it will load __Value but if MVT is not enabled and
! * that would fail verification.
*/
! private static class ValueClassHelper {
! static final Class<?> VALUE_CLASS =
(Class<?>)(Object)__Value.class; //hack around static type-system checks
+
+ static volatile Class<? extends Annotation> annotationClass;
+ static volatile Class<?> valueTypeClass;
+
+ static boolean hasValueCapableAnnotation(Class<?> c) {
+ if (!VM.isModuleSystemInited()) {
+ return false;
+ }
+ Class<? extends Annotation> annClass = annotationClass;
+ if (annClass == null) {
+ annotationClass = annClass = loadValueCapableAnnotation();
+ }
+ return annClass != null &&
+ c.getDeclaredAnnotation(annClass) != null;
+ }
+
+ static Class<? extends Annotation> loadValueCapableAnnotation() {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<? extends Annotation> c = (Class<? extends Annotation>)
+ Class.forName("jdk.incubator.mvt.ValueCapableClass", false,
+ ClassLoader.getPlatformClassLoader());
+ return c;
+
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ static Class<?> incubatorValueTypeClass() {
+ Class<?> c = valueTypeClass;
+ if (c == null) {
+ try {
+ valueTypeClass = c =
+ Class.forName("jdk.incubator.mvt.ValueType", false,
+ ClassLoader.getPlatformClassLoader());
+ } catch (ClassNotFoundException e) {
+ }
+ }
+ return valueTypeClass;
+ }
+ }
+
+ static Class<?> getIncubatorValueTypeClass() {
+ if (!isValueTypeEnabled()) {
+ throw new UnsupportedOperationException("MVT is not enabled");
+ }
+ return ValueClassHelper.incubatorValueTypeClass();
}
}
< prev index next >