115 return Objects.hashCode(kind) * 31 + Objects.hashCode(optArg); 116 } 117 } 118 } 119 120 private static final Lookup IMPL_LOOKUP; 121 122 static { 123 try { 124 Field f = Lookup.class.getDeclaredField("IMPL_LOOKUP"); 125 f.setAccessible(true); 126 IMPL_LOOKUP = (Lookup)f.get(null); 127 } catch (ReflectiveOperationException ex) { 128 throw new AssertionError(ex); 129 } 130 } 131 132 private static final ConcurrentHashMap<Class<?>, ValueType<?>> BOX_TO_VT = new ConcurrentHashMap<>(); 133 134 public static boolean classHasValueType(Class<?> x) { 135 return MinimalValueTypes_1_0.classHasValueType(x); 136 } 137 138 @SuppressWarnings("unchecked") 139 public static <T> ValueType<T> forClass(Class<T> x) { 140 ValueType<T> vt = (ValueType<T>) BOX_TO_VT.get(x); 141 if (vt != null) { 142 return vt; 143 } 144 145 try { 146 Class<T> valueClass = (Class<T>) MinimalValueTypes_1_0.getValueTypeClass(x); 147 vt = new ValueType<T>(x, valueClass); 148 ValueType<T> old = (ValueType<T>) BOX_TO_VT.putIfAbsent(x, vt); 149 if (old != null) { 150 vt = old; 151 } 152 return vt; 153 } 154 catch (ClassNotFoundException cne) { 155 throw new IllegalArgumentException("Class " + x + " not bound to ValueType", cne); 156 } 157 } 158 159 private Lookup boxLookup; 160 private Lookup valueLookup; 161 private Map<ValueHandleKind.ValueHandleKey, MethodHandle> handleMap = new ConcurrentHashMap<>(); 162 163 private ValueType(Class<T> boxClass, Class<T> valueClass) { 164 this.boxLookup = IMPL_LOOKUP.in(boxClass); 165 this.valueLookup = IMPL_LOOKUP.in(valueClass); 166 } 167 168 @SuppressWarnings("unchecked") 169 public Class<T> boxClass() { 170 return (Class<T>)boxLookup.lookupClass(); 171 } 172 173 public Class<?> sourceClass() { 174 return boxClass(); 175 } 176 177 public Class<?> valueClass() { 178 return valueLookup.lookupClass(); 179 } 180 181 public Class<?> arrayValueClass() { 182 return arrayValueClass(1); 183 } 184 185 public Class<?> arrayValueClass(int dims) { 186 try { 187 String dimsStr = "[[[[[[[[[[[[[[[["; 188 if (dims < 1 || dims > 16) { 189 throw new IllegalArgumentException("cannot create array class for dimension > 16"); 190 } 191 return Class.forName(dimsStr.substring(0, dims) + "Q" + valueClass().getName() + ";", false, boxLookup.lookupClass().getClassLoader()); 192 } catch (ClassNotFoundException ex) { 193 throw new IllegalStateException(ex); 194 } 195 } 196 197 public String toString() { 198 return "ValueType boxClass=" + boxClass() + " valueClass=" + valueClass(); 199 } 200 201 String mhName(String opName) { 202 return sourceClass().getName() + "_" + opName; 203 } 204 205 public MethodHandle defaultValueConstant() { 206 ValueHandleKey key = ValueHandleKind.DEFAULT.key(); 207 MethodHandle result = handleMap.get(key); 208 if (result == null) { 209 result = MethodHandleBuilder.loadCode(boxLookup, mhName("default"), MethodType.methodType(valueClass()), 210 C -> { 211 C.vdefault(valueClass()).vreturn(); 212 }); 213 handleMap.put(key, result); 214 } | 115 return Objects.hashCode(kind) * 31 + Objects.hashCode(optArg); 116 } 117 } 118 } 119 120 private static final Lookup IMPL_LOOKUP; 121 122 static { 123 try { 124 Field f = Lookup.class.getDeclaredField("IMPL_LOOKUP"); 125 f.setAccessible(true); 126 IMPL_LOOKUP = (Lookup)f.get(null); 127 } catch (ReflectiveOperationException ex) { 128 throw new AssertionError(ex); 129 } 130 } 131 132 private static final ConcurrentHashMap<Class<?>, ValueType<?>> BOX_TO_VT = new ConcurrentHashMap<>(); 133 134 public static boolean classHasValueType(Class<?> x) { 135 if (!MinimalValueTypes_1_0.isValueCapable(x)) { 136 return false; 137 } 138 return MinimalValueTypes_1_0.getValueTypeClass(x) != null; 139 } 140 141 @SuppressWarnings("unchecked") 142 public static <T> ValueType<T> forClass(Class<T> x) { 143 if (!MinimalValueTypes_1_0.isValueCapable(x)) { 144 throw new IllegalArgumentException("Class " + x + " not a value capable class"); 145 } 146 147 ValueType<T> vt = (ValueType<T>) BOX_TO_VT.get(x); 148 if (vt != null) { 149 return vt; 150 } 151 152 Class<T> valueClass = (Class<T>) MinimalValueTypes_1_0.getValueTypeClass(x); 153 vt = new ValueType<T>(x, valueClass); 154 ValueType<T> old = (ValueType<T>) BOX_TO_VT.putIfAbsent(x, vt); 155 if (old != null) { 156 vt = old; 157 } 158 return vt; 159 } 160 161 private Lookup boxLookup; 162 private Lookup valueLookup; 163 private Map<ValueHandleKind.ValueHandleKey, MethodHandle> handleMap = new ConcurrentHashMap<>(); 164 165 private ValueType(Class<T> boxClass, Class<T> valueClass) { 166 this.boxLookup = IMPL_LOOKUP.in(boxClass); 167 this.valueLookup = IMPL_LOOKUP.in(valueClass); 168 } 169 170 @SuppressWarnings("unchecked") 171 public Class<T> boxClass() { 172 return (Class<T>)boxLookup.lookupClass(); 173 } 174 175 public Class<?> sourceClass() { 176 return boxClass(); 177 } 178 179 public Class<?> valueClass() { 180 return valueLookup.lookupClass(); 181 } 182 183 public Class<?> arrayValueClass() { 184 return arrayValueClass(1); 185 } 186 187 public Class<?> arrayValueClass(int dims) { 188 String dimsStr = "[[[[[[[[[[[[[[[["; 189 if (dims < 1 || dims > 16) { 190 throw new IllegalArgumentException("cannot create array class for dimension > 16"); 191 } 192 String cn = dimsStr.substring(0, dims) + "Q" + valueClass().getName() + ";"; 193 return MinimalValueTypes_1_0.loadValueTypeClass(boxLookup.lookupClass(), cn); 194 } 195 196 public String toString() { 197 return "ValueType boxClass=" + boxClass() + " valueClass=" + valueClass(); 198 } 199 200 String mhName(String opName) { 201 return sourceClass().getName() + "_" + opName; 202 } 203 204 public MethodHandle defaultValueConstant() { 205 ValueHandleKey key = ValueHandleKind.DEFAULT.key(); 206 MethodHandle result = handleMap.get(key); 207 if (result == null) { 208 result = MethodHandleBuilder.loadCode(boxLookup, mhName("default"), MethodType.methodType(valueClass()), 209 C -> { 210 C.vdefault(valueClass()).vreturn(); 211 }); 212 handleMap.put(key, result); 213 } |