< prev index next >
jdk/src/java.base/share/classes/valhalla/shady/ValueTypeHolder.java
Print this page
*** 21,31 ****
* 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.
*/
! package jdk.experimental.value;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
--- 21,31 ----
* 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.
*/
! package valhalla.shady;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
*** 45,64 ****
import jdk.experimental.bytecode.AnnotationsBuilder.Kind;
import jdk.experimental.bytecode.Flag;
import jdk.experimental.bytecode.Opcode;
import jdk.experimental.value.MethodHandleBuilder.IsolatedMethodBuilder;
import jdk.experimental.value.MethodHandleBuilder.MethodHandleCodeBuilder;
! import jdk.experimental.value.ValueType.ValueHandleKind.ValueHandleKey;
import jdk.experimental.bytecode.MacroCodeBuilder.CondKind;
import jdk.experimental.bytecode.TypeTag;
- import jdk.internal.misc.Unsafe;
import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.Wrapper;
! import valhalla.shady.MinimalValueTypes_1_0;
// Rough place holder just now...
! public class ValueType<T> {
enum ValueHandleKind {
BOX("box"),
UNBOX("unbox"),
DEFAULT("defaultValueConstant"),
--- 45,63 ----
import jdk.experimental.bytecode.AnnotationsBuilder.Kind;
import jdk.experimental.bytecode.Flag;
import jdk.experimental.bytecode.Opcode;
import jdk.experimental.value.MethodHandleBuilder.IsolatedMethodBuilder;
import jdk.experimental.value.MethodHandleBuilder.MethodHandleCodeBuilder;
! import jdk.experimental.value.MethodHandleBuilder;
import jdk.experimental.bytecode.MacroCodeBuilder.CondKind;
import jdk.experimental.bytecode.TypeTag;
import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.Wrapper;
! import valhalla.shady.ValueTypeHolder.ValueHandleKind.ValueHandleKey;
// Rough place holder just now...
! public class ValueTypeHolder<T> {
enum ValueHandleKind {
BOX("box"),
UNBOX("unbox"),
DEFAULT("defaultValueConstant"),
*** 96,106 ****
final MethodHandle handle;
ValueHandleKind(String handleName, Class<?>... argtypes) {
try {
! this.handle = MethodHandles.lookup().findVirtual(ValueType.class, handleName, MethodType.methodType(MethodHandle.class, argtypes));
} catch (ReflectiveOperationException ex) {
throw new IllegalArgumentException("Cannot initialize value handle key for: " + handleName);
}
}
--- 95,105 ----
final MethodHandle handle;
ValueHandleKind(String handleName, Class<?>... argtypes) {
try {
! this.handle = MethodHandles.lookup().findVirtual(ValueTypeHolder.class, handleName, MethodType.methodType(MethodHandle.class, argtypes));
} catch (ReflectiveOperationException ex) {
throw new IllegalArgumentException("Cannot initialize value handle key for: " + handleName);
}
}
*** 157,196 ****
} catch (ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
! private static final ConcurrentHashMap<Class<?>, ValueType<?>> BOX_TO_VT = new ConcurrentHashMap<>();
!
! public static boolean classHasValueType(Class<?> x) {
! if (!MinimalValueTypes_1_0.isValueCapable(x)) {
! return false;
! }
! return MinimalValueTypes_1_0.getValueTypeClass(x) != null;
! }
!
! @SuppressWarnings("unchecked")
! public static <T> ValueType<T> forClass(Class<T> x) {
! if (!MinimalValueTypes_1_0.isValueCapable(x)) {
! throw new IllegalArgumentException("Class " + x + " not a value capable class");
! }
!
! ValueType<T> vt = (ValueType<T>) BOX_TO_VT.get(x);
! if (vt != null) {
! return vt;
! }
!
! Class<T> valueClass = (Class<T>) MinimalValueTypes_1_0.getValueTypeClass(x);
! vt = new ValueType<T>(x, valueClass);
! ValueType<T> old = (ValueType<T>) BOX_TO_VT.putIfAbsent(x, vt);
! if (old != null) {
! vt = old;
! }
! return vt;
! }
!
! public static <T> ValueType<T> make(Lookup lookup, String name, String[] fieldNames, Class<?>... fieldTypes) throws ReflectiveOperationException {
if (fieldNames.length != fieldTypes.length) {
throw new IllegalArgumentException("Field names length and field types length must match");
}
if (!(fieldNames.length > 0)) {
throw new IllegalArgumentException("Field length must be greater than zero");
--- 156,166 ----
} catch (ReflectiveOperationException ex) {
throw new AssertionError(ex);
}
}
! public static <T> Class<T> makeValueTypeClass(Lookup lookup, String name, String[] fieldNames, Class<?>... fieldTypes) throws ReflectiveOperationException {
if (fieldNames.length != fieldTypes.length) {
throw new IllegalArgumentException("Field names length and field types length must match");
}
if (!(fieldNames.length > 0)) {
throw new IllegalArgumentException("Field length must be greater than zero");
*** 198,208 ****
IsolatedMethodBuilder builder = new IsolatedMethodBuilder(name, lookup);
builder.withMajorVersion(53)
.withMinorVersion(0)
.withSuperclass(Object.class)
.withFlags(Flag.ACC_FINAL)
! .withAnnotation(Kind.RUNTIME_VISIBLE, "Ljvm/internal/value/ValueCapableClass;");
//add fields
for (int i = 0 ; i < fieldNames.length ; i++) {
builder.withField(fieldNames[i], BytecodeDescriptor.unparse(fieldTypes[i]), F -> F.withFlags(Flag.ACC_FINAL));
}
//add constructor
--- 168,178 ----
IsolatedMethodBuilder builder = new IsolatedMethodBuilder(name, lookup);
builder.withMajorVersion(53)
.withMinorVersion(0)
.withSuperclass(Object.class)
.withFlags(Flag.ACC_FINAL)
! .withAnnotation(Kind.RUNTIME_VISIBLE, MinimalValueTypes_1_0.DERIVE_VALUE_TYPE_DESC);
//add fields
for (int i = 0 ; i < fieldNames.length ; i++) {
builder.withField(fieldNames[i], BytecodeDescriptor.unparse(fieldTypes[i]), F -> F.withFlags(Flag.ACC_FINAL));
}
//add constructor
*** 226,243 ****
C -> substitutabilityHashCodeBuilder(builder.thisClass(), FieldInfo.stream(fieldNames, fieldTypes), C)));
byte[] barr = builder.build();
MinimalValueTypes_1_0.maybeDump(name, barr);
@SuppressWarnings("unchecked")
Class<T> vtClass = (Class<T>)lookup.defineClass(barr);
! return forClass(vtClass);
}
private Lookup boxLookup;
private Lookup valueLookup;
private Map<ValueHandleKind.ValueHandleKey, MethodHandle> handleMap = new ConcurrentHashMap<>();
! private ValueType(Class<T> boxClass, Class<T> valueClass) {
this.boxLookup = IMPL_LOOKUP.in(boxClass);
this.valueLookup = IMPL_LOOKUP.in(valueClass);
}
@SuppressWarnings("unchecked")
--- 196,213 ----
C -> substitutabilityHashCodeBuilder(builder.thisClass(), FieldInfo.stream(fieldNames, fieldTypes), C)));
byte[] barr = builder.build();
MinimalValueTypes_1_0.maybeDump(name, barr);
@SuppressWarnings("unchecked")
Class<T> vtClass = (Class<T>)lookup.defineClass(barr);
! return vtClass;
}
private Lookup boxLookup;
private Lookup valueLookup;
private Map<ValueHandleKind.ValueHandleKey, MethodHandle> handleMap = new ConcurrentHashMap<>();
! ValueTypeHolder(Class<T> boxClass, Class<T> valueClass) {
this.boxLookup = IMPL_LOOKUP.in(boxClass);
this.valueLookup = IMPL_LOOKUP.in(valueClass);
}
@SuppressWarnings("unchecked")
*** 512,526 ****
private static <T extends MethodHandleCodeBuilder<T>> T valueHandleBuilder(Class<?> dvt, ValueHandleKey key, MethodHandleCodeBuilder<T> C) {
MethodType mt = key.kind.handleType();
if (mt.parameterCount() > 0) {
throw new AssertionError("Non-nilary handle builders not supported yet");
}
return C.vbox(MinimalValueTypes_1_0.getValueCapableClass(dvt))
.invokevirtual(Object.class, "getClass", "()Ljava/lang/Class;", false)
! .invokestatic(ValueType.class, "forClass",
! MethodType.methodType(ValueType.class, Class.class).toMethodDescriptorString(), false)
! .invokevirtual(ValueType.class, key.kind.handleName(), key.kind.handleType().toMethodDescriptorString(), false);
}
private MethodHandle getOrLoad(Lookup lookup, ValueHandleKey key, Supplier<MethodType> typeSupplier, Consumer<? super MethodHandleCodeBuilder<?>> codeBuilder) {
MethodHandle result = handleMap.get(key);
if (result == null) {
--- 482,497 ----
private static <T extends MethodHandleCodeBuilder<T>> T valueHandleBuilder(Class<?> dvt, ValueHandleKey key, MethodHandleCodeBuilder<T> C) {
MethodType mt = key.kind.handleType();
if (mt.parameterCount() > 0) {
throw new AssertionError("Non-nilary handle builders not supported yet");
}
+ Class<?> vtSupportClass = MinimalValueTypes_1_0.getIncubatorValueTypeClass();
return C.vbox(MinimalValueTypes_1_0.getValueCapableClass(dvt))
.invokevirtual(Object.class, "getClass", "()Ljava/lang/Class;", false)
! .invokestatic(vtSupportClass, "forClass",
! MethodType.methodType(vtSupportClass, Class.class).toMethodDescriptorString(), false)
! .invokevirtual(vtSupportClass, key.kind.handleName(), key.kind.handleType().toMethodDescriptorString(), false);
}
private MethodHandle getOrLoad(Lookup lookup, ValueHandleKey key, Supplier<MethodType> typeSupplier, Consumer<? super MethodHandleCodeBuilder<?>> codeBuilder) {
MethodHandle result = handleMap.get(key);
if (result == null) {
< prev index next >