1 /* 2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.hotspot; 24 25 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; 26 27 import java.lang.annotation.Annotation; 28 import java.lang.reflect.Array; 29 import java.lang.reflect.Type; 30 31 import jdk.vm.ci.meta.JavaConstant; 32 import jdk.vm.ci.meta.JavaKind; 33 import jdk.vm.ci.meta.ResolvedJavaMethod; 34 import jdk.vm.ci.meta.ResolvedJavaType; 35 36 /** 37 * Implementation of {@link HotSpotJVMCIReflection} when running in a JVMCI shared library. 38 */ 39 class SharedLibraryJVMCIReflection extends HotSpotJVMCIReflection { 40 41 @Override 42 Object resolveObject(HotSpotObjectConstantImpl objectHandle) { 43 throw new HotSpotJVMCIUnsupportedOperationError("cannot resolve handle in a JVMCI shared library to a raw object: " + objectHandle); 44 } 45 46 @Override 47 boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl obj) { 48 if (obj instanceof DirectHotSpotObjectConstantImpl) { 49 ResolvedJavaType type = getType(obj); 50 return holder.isAssignableFrom(type); 51 } 52 return runtime().compilerToVm.isInstance(holder, obj); 53 } 54 55 @Override 56 boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType) { 57 return runtime().compilerToVm.isAssignableFrom(holder, otherType); 58 } 59 60 @Override 61 boolean isLocalClass(HotSpotResolvedObjectTypeImpl holder) { 62 throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.isLocalClass()"); 63 } 64 65 @Override 66 boolean isMemberClass(HotSpotResolvedObjectTypeImpl holder) { 67 throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.isMemberClass()"); 68 } 69 70 @Override 71 HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder) { 72 throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.getEnclosingClass()"); 73 } 74 75 @Override 76 JavaConstant readFieldValue(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedJavaField field, boolean isVolatile) { 77 JavaConstant javaConstant = runtime().compilerToVm.readFieldValue(holder, field, isVolatile); 78 if (javaConstant == null) { 79 return JavaConstant.NULL_POINTER; 80 } 81 return javaConstant; 82 } 83 84 @Override 85 JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedJavaField field, boolean isVolatile) { 86 if (object instanceof DirectHotSpotObjectConstantImpl) { 87 // cannot read fields from objects due to lack of 88 // general reflection support in native image 89 return null; 90 } 91 JavaConstant javaConstant = runtime().compilerToVm.readFieldValue(object, field, isVolatile); 92 if (javaConstant == null) { 93 return JavaConstant.NULL_POINTER; 94 } 95 return javaConstant; 96 } 97 98 @Override 99 boolean equals(HotSpotObjectConstantImpl x, HotSpotObjectConstantImpl y) { 100 if (x == y) { 101 return true; 102 } 103 if (x.compressed != y.compressed) { 104 return false; 105 } 106 if (x instanceof DirectHotSpotObjectConstantImpl && y instanceof DirectHotSpotObjectConstantImpl) { 107 DirectHotSpotObjectConstantImpl xd = (DirectHotSpotObjectConstantImpl) x; 108 DirectHotSpotObjectConstantImpl yd = (DirectHotSpotObjectConstantImpl) y; 109 return (xd.object == yd.object); 110 } 111 if (x instanceof DirectHotSpotObjectConstantImpl || y instanceof DirectHotSpotObjectConstantImpl) { 112 // Mixing of constant types is always inequal 113 return false; 114 } 115 IndirectHotSpotObjectConstantImpl indirectX = (IndirectHotSpotObjectConstantImpl) x; 116 IndirectHotSpotObjectConstantImpl indirectY = (IndirectHotSpotObjectConstantImpl) y; 117 return runtime().compilerToVm.equals(x, indirectX.objectHandle, y, indirectY.objectHandle); 118 } 119 120 @Override 121 JavaConstant getJavaMirror(HotSpotResolvedPrimitiveType hotSpotResolvedPrimitiveType) { 122 return runtime().compilerToVm.getJavaMirror(hotSpotResolvedPrimitiveType); 123 } 124 125 @Override 126 ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod) { 127 // ResolvedJavaMethod.getParameters allows a return value of null 128 return null; 129 } 130 131 // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection 132 static Annotation[] getClassAnnotations(String className) { 133 throw new InternalError("missing substitution: " + className); 134 } 135 136 // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection 137 static Annotation[][] getParameterAnnotations(String className, String methodName) { 138 throw new InternalError("missing substitution: " + className + " " + methodName); 139 } 140 141 @Override 142 Annotation[] getAnnotations(HotSpotResolvedObjectTypeImpl holder) { 143 return getClassAnnotations(holder.getName()); 144 } 145 146 @Override 147 Annotation[] getDeclaredAnnotations(HotSpotResolvedObjectTypeImpl holder) { 148 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 149 } 150 151 @Override 152 <T extends Annotation> T getAnnotation(HotSpotResolvedObjectTypeImpl holder, Class<T> annotationClass) { 153 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 154 } 155 156 @Override 157 Annotation[][] getParameterAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { 158 return getParameterAnnotations(javaMethod.getDeclaringClass().getName(), javaMethod.getName()); 159 } 160 161 @Override 162 Type[] getGenericParameterTypes(HotSpotResolvedJavaMethodImpl javaMethod) { 163 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 164 } 165 166 @Override 167 Annotation[] getFieldAnnotations(HotSpotResolvedJavaFieldImpl javaField) { 168 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 169 } 170 171 @Override 172 Annotation[] getMethodAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { 173 return getMethodAnnotationsInternal(javaMethod); 174 } 175 176 @Override 177 <T extends Annotation> T getMethodAnnotation(HotSpotResolvedJavaMethodImpl javaMethod, Class<T> annotationClass) { 178 Annotation[] methodAnnotations = getMethodAnnotations(javaMethod); 179 if (methodAnnotations != null) { 180 for (Annotation ann : methodAnnotations) { 181 if (annotationClass.isInstance(ann)) { 182 return annotationClass.cast(ann); 183 } 184 } 185 } 186 return null; 187 } 188 189 // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection 190 @SuppressWarnings("unused") 191 private static Annotation[] getMethodAnnotationsInternal(ResolvedJavaMethod javaMethod) { 192 throw new InternalError("missing substitution"); 193 } 194 195 @Override 196 Annotation[] getMethodDeclaredAnnotations(HotSpotResolvedJavaMethodImpl javaMethod) { 197 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 198 } 199 200 @Override 201 Annotation[] getFieldDeclaredAnnotations(HotSpotResolvedJavaFieldImpl javaMethod) { 202 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 203 } 204 205 @Override 206 <T extends Annotation> T getFieldAnnotation(HotSpotResolvedJavaFieldImpl javaField, Class<T> annotationClass) { 207 throw new HotSpotJVMCIUnsupportedOperationError("unimplemented"); 208 } 209 210 @Override 211 HotSpotResolvedObjectTypeImpl getType(HotSpotObjectConstantImpl object) { 212 if (object instanceof DirectHotSpotObjectConstantImpl) { 213 Class<?> theClass = ((DirectHotSpotObjectConstantImpl) object).object.getClass(); 214 try { 215 String name = theClass.getName().replace('.', '/'); 216 HotSpotResolvedObjectTypeImpl type = (HotSpotResolvedObjectTypeImpl) runtime().compilerToVm.lookupType(name, null, true); 217 if (type == null) { 218 throw new InternalError(name); 219 } 220 return type; 221 } catch (ClassNotFoundException e) { 222 throw new InternalError(e); 223 } 224 } 225 return runtime().compilerToVm.getResolvedJavaType(object, runtime().getConfig().hubOffset, false); 226 } 227 228 @Override 229 String asString(HotSpotObjectConstantImpl object) { 230 if (object instanceof IndirectHotSpotObjectConstantImpl) { 231 return runtime().compilerToVm.asString(object); 232 } 233 Object value = ((DirectHotSpotObjectConstantImpl) object).object; 234 if (value instanceof String) { 235 return (String) value; 236 } 237 return null; 238 } 239 240 @Override 241 ResolvedJavaType asJavaType(HotSpotObjectConstantImpl object) { 242 if (object instanceof DirectHotSpotObjectConstantImpl) { 243 DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; 244 if (direct.object instanceof Class) { 245 Class<?> javaClass = (Class<?>) direct.object; 246 return runtime().fromClass(javaClass); 247 } 248 if (direct.object instanceof ResolvedJavaType) { 249 return (ResolvedJavaType) convertUnknownValue(direct.object); 250 } 251 return null; 252 } 253 return runtime().compilerToVm.asJavaType(object); 254 } 255 256 // Substituted by Target_jdk_vm_ci_hotspot_SharedLibraryJVMCIReflection 257 static Object convertUnknownValue(Object object) { 258 return object; 259 } 260 261 @SuppressWarnings("unchecked") 262 @Override 263 <T> T asObject(HotSpotObjectConstantImpl object, Class<T> type) { 264 if (object instanceof DirectHotSpotObjectConstantImpl) { 265 Object theObject = ((DirectHotSpotObjectConstantImpl) object).object; 266 if (type.isInstance(theObject)) { 267 return (T) convertUnknownValue(type.cast(theObject)); 268 } 269 } 270 return null; 271 } 272 273 @Override 274 Object asObject(HotSpotObjectConstantImpl object, HotSpotResolvedJavaType type) { 275 throw new HotSpotJVMCIUnsupportedOperationError("cannot resolve a shared library JVMCI object handle to a " + 276 "raw object as it may be in another runtime"); 277 } 278 279 @Override 280 String formatString(HotSpotObjectConstantImpl object) { 281 if (object instanceof DirectHotSpotObjectConstantImpl) { 282 DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; 283 return "CompilerObject<" + direct.object.getClass().getName() + ">"; 284 } 285 return "Instance<" + object.getType().toJavaName() + ">"; 286 } 287 288 @Override 289 Integer getLength(HotSpotObjectConstantImpl object) { 290 if (object instanceof DirectHotSpotObjectConstantImpl) { 291 DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object; 292 if (direct.object.getClass().isArray()) { 293 return Array.getLength(direct.object); 294 } 295 return null; 296 } 297 int length = runtime().compilerToVm.getArrayLength(object); 298 if (length >= 0) { 299 return length; 300 } 301 return null; 302 } 303 304 @Override 305 JavaConstant readArrayElement(HotSpotObjectConstantImpl arrayObject, int index) { 306 Object result = runtime().compilerToVm.readArrayElement(arrayObject, index); 307 if (result == null) { 308 return null; 309 } 310 if (result instanceof JavaConstant) { 311 return (JavaConstant) result; 312 } 313 JavaConstant constant = JavaConstant.forBoxedPrimitive(result); 314 if (constant == null) { 315 throw new InternalError("Unexpected value " + result); 316 } 317 return constant; 318 } 319 320 @Override 321 JavaConstant forObject(Object value) { 322 return DirectHotSpotObjectConstantImpl.forObject(value, false); 323 } 324 325 @Override 326 JavaConstant unboxPrimitive(HotSpotObjectConstantImpl source) { 327 Object box = runtime().compilerToVm.unboxPrimitive(source); 328 return JavaConstant.forBoxedPrimitive(box); 329 } 330 331 @Override 332 JavaConstant boxPrimitive(JavaConstant source) { 333 return runtime().compilerToVm.boxPrimitive(source.asBoxedPrimitive()); 334 } 335 336 @Override 337 int getInt(HotSpotObjectConstantImpl object, long displacement) { 338 return runtime().compilerToVm.getInt(object, displacement); 339 } 340 341 @Override 342 byte getByte(HotSpotObjectConstantImpl object, long displacement) { 343 return runtime().compilerToVm.getByte(object, displacement); 344 } 345 346 @Override 347 short getShort(HotSpotObjectConstantImpl object, long displacement) { 348 return runtime().compilerToVm.getShort(object, displacement); 349 } 350 351 @Override 352 long getLong(HotSpotObjectConstantImpl object, long displacement) { 353 return runtime().compilerToVm.getLong(object, displacement); 354 } 355 356 @Override 357 void checkRead(HotSpotObjectConstantImpl constant, JavaKind kind, long displacement, HotSpotResolvedObjectType type) { 358 359 } 360 }