121 } else {
122 ResolvedJavaField field = type.findInstanceFieldWithOffset(displacement, JavaKind.Object);
123 if (field == null && object instanceof Class) {
124 // Read of a static field
125 MetaAccessProvider metaAccess = runtime.getHostJVMCIBackend().getMetaAccess();
126 HotSpotResolvedObjectTypeImpl staticFieldsHolder = (HotSpotResolvedObjectTypeImpl) metaAccess.lookupJavaType((Class<?>) object);
127 field = staticFieldsHolder.findStaticFieldWithOffset(displacement, JavaKind.Object);
128 }
129 if (field == null) {
130 throw new IllegalArgumentException("Unsafe object access: field not found for read of kind Object" +
131 " at offset " + displacement + " in " + type.toJavaName() + " object");
132 }
133 if (field.getJavaKind() != JavaKind.Object) {
134 throw new IllegalArgumentException("Unsafe object access: field " + field.format("%H.%n:%T") + " not of expected kind Object" +
135 " at offset " + displacement + " in " + type.toJavaName() + " object");
136 }
137 }
138 return true;
139 }
140
141 private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
142 if (base instanceof HotSpotMetaspaceConstant) {
143 MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
144 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
145 if (displacement == runtime.getConfig().classMirrorOffset) {
146 // Klass::_java_mirror is valid for all Klass* values
147 return true;
148 }
149 } else {
150 throw new IllegalArgumentException(String.valueOf(metaspaceObject));
151 }
152 }
153 return false;
154 }
155
156 private static long asRawPointer(Constant base) {
157 if (base instanceof HotSpotMetaspaceConstantImpl) {
158 MetaspaceWrapperObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
159 return meta.getMetaspacePointer();
160 } else if (base instanceof PrimitiveConstant) {
161 PrimitiveConstant prim = (PrimitiveConstant) base;
162 if (prim.getJavaKind().isNumericInteger()) {
163 return prim.asLong();
164 }
165 }
166 throw new IllegalArgumentException(String.valueOf(base));
167 }
168
169 private long readRawValue(Constant baseConstant, long displacement, JavaKind kind, int bits) {
170 Object base = asObject(baseConstant, kind, displacement);
171 if (base != null) {
172 switch (bits) {
173 case Byte.SIZE:
174 return UNSAFE.getByte(base, displacement);
175 case Short.SIZE:
185 long pointer = asRawPointer(baseConstant);
186 switch (bits) {
187 case Byte.SIZE:
188 return UNSAFE.getByte(pointer + displacement);
189 case Short.SIZE:
190 return UNSAFE.getShort(pointer + displacement);
191 case Integer.SIZE:
192 return UNSAFE.getInt(pointer + displacement);
193 case Long.SIZE:
194 return UNSAFE.getLong(pointer + displacement);
195 default:
196 throw new IllegalArgumentException(String.valueOf(bits));
197 }
198 }
199 }
200
201 private boolean verifyReadRawObject(Object expected, Constant base, long displacement) {
202 if (base instanceof HotSpotMetaspaceConstant) {
203 MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
204 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
205 if (displacement == runtime.getConfig().classMirrorOffset) {
206 assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
207 }
208 }
209 }
210 return true;
211 }
212
213 private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
214 long displacement = initialDisplacement;
215 Object ret;
216 Object base = asObject(baseConstant, JavaKind.Object, displacement);
217 if (base == null) {
218 assert !compressed;
219 displacement += asRawPointer(baseConstant);
220 ret = UNSAFE.getUncompressedObject(displacement);
221 assert verifyReadRawObject(ret, baseConstant, initialDisplacement);
222 } else {
223 assert runtime.getConfig().useCompressedOops == compressed;
224 ret = UNSAFE.getObject(base, displacement);
225 }
277 case Long:
278 return JavaConstant.forLong(rawValue);
279 case Float:
280 return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue));
281 case Double:
282 return JavaConstant.forDouble(Double.longBitsToDouble(rawValue));
283 default:
284 throw new IllegalArgumentException("Unsupported kind: " + kind);
285 }
286 } catch (NullPointerException e) {
287 return null;
288 }
289 }
290
291 @Override
292 public JavaConstant readObjectConstant(Constant base, long displacement) {
293 if (base instanceof HotSpotObjectConstantImpl) {
294 Object o = readRawObject(base, displacement, runtime.getConfig().useCompressedOops);
295 return HotSpotObjectConstantImpl.forObject(o);
296 }
297 if (!isValidObjectFieldDisplacement(base, displacement)) {
298 return null;
299 }
300 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
301 }
302
303 @Override
304 public JavaConstant readNarrowOopConstant(Constant base, long displacement) {
305 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
306 }
307
308 private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) {
309 assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass();
310 Object baseObject = (base instanceof HotSpotMetaspaceConstantImpl) ? ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType() : ((HotSpotObjectConstantImpl) base).object();
311 return runtime.getCompilerToVM().getResolvedJavaType(baseObject, displacement, compressed);
312 }
313
314 @Override
315 public Constant readKlassPointerConstant(Constant base, long displacement) {
316 HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false);
317 if (klass == null) {
318 return JavaConstant.NULL_POINTER;
319 }
320 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false);
|
121 } else {
122 ResolvedJavaField field = type.findInstanceFieldWithOffset(displacement, JavaKind.Object);
123 if (field == null && object instanceof Class) {
124 // Read of a static field
125 MetaAccessProvider metaAccess = runtime.getHostJVMCIBackend().getMetaAccess();
126 HotSpotResolvedObjectTypeImpl staticFieldsHolder = (HotSpotResolvedObjectTypeImpl) metaAccess.lookupJavaType((Class<?>) object);
127 field = staticFieldsHolder.findStaticFieldWithOffset(displacement, JavaKind.Object);
128 }
129 if (field == null) {
130 throw new IllegalArgumentException("Unsafe object access: field not found for read of kind Object" +
131 " at offset " + displacement + " in " + type.toJavaName() + " object");
132 }
133 if (field.getJavaKind() != JavaKind.Object) {
134 throw new IllegalArgumentException("Unsafe object access: field " + field.format("%H.%n:%T") + " not of expected kind Object" +
135 " at offset " + displacement + " in " + type.toJavaName() + " object");
136 }
137 }
138 return true;
139 }
140
141 private static long asRawPointer(Constant base) {
142 if (base instanceof HotSpotMetaspaceConstantImpl) {
143 MetaspaceWrapperObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
144 return meta.getMetaspacePointer();
145 } else if (base instanceof PrimitiveConstant) {
146 PrimitiveConstant prim = (PrimitiveConstant) base;
147 if (prim.getJavaKind().isNumericInteger()) {
148 return prim.asLong();
149 }
150 }
151 throw new IllegalArgumentException(String.valueOf(base));
152 }
153
154 private long readRawValue(Constant baseConstant, long displacement, JavaKind kind, int bits) {
155 Object base = asObject(baseConstant, kind, displacement);
156 if (base != null) {
157 switch (bits) {
158 case Byte.SIZE:
159 return UNSAFE.getByte(base, displacement);
160 case Short.SIZE:
170 long pointer = asRawPointer(baseConstant);
171 switch (bits) {
172 case Byte.SIZE:
173 return UNSAFE.getByte(pointer + displacement);
174 case Short.SIZE:
175 return UNSAFE.getShort(pointer + displacement);
176 case Integer.SIZE:
177 return UNSAFE.getInt(pointer + displacement);
178 case Long.SIZE:
179 return UNSAFE.getLong(pointer + displacement);
180 default:
181 throw new IllegalArgumentException(String.valueOf(bits));
182 }
183 }
184 }
185
186 private boolean verifyReadRawObject(Object expected, Constant base, long displacement) {
187 if (base instanceof HotSpotMetaspaceConstant) {
188 MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
189 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
190 if (displacement == runtime.getConfig().classMirrorHandleOffset) {
191 assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
192 }
193 }
194 }
195 return true;
196 }
197
198 private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
199 long displacement = initialDisplacement;
200 Object ret;
201 Object base = asObject(baseConstant, JavaKind.Object, displacement);
202 if (base == null) {
203 assert !compressed;
204 displacement += asRawPointer(baseConstant);
205 ret = UNSAFE.getUncompressedObject(displacement);
206 assert verifyReadRawObject(ret, baseConstant, initialDisplacement);
207 } else {
208 assert runtime.getConfig().useCompressedOops == compressed;
209 ret = UNSAFE.getObject(base, displacement);
210 }
262 case Long:
263 return JavaConstant.forLong(rawValue);
264 case Float:
265 return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue));
266 case Double:
267 return JavaConstant.forDouble(Double.longBitsToDouble(rawValue));
268 default:
269 throw new IllegalArgumentException("Unsupported kind: " + kind);
270 }
271 } catch (NullPointerException e) {
272 return null;
273 }
274 }
275
276 @Override
277 public JavaConstant readObjectConstant(Constant base, long displacement) {
278 if (base instanceof HotSpotObjectConstantImpl) {
279 Object o = readRawObject(base, displacement, runtime.getConfig().useCompressedOops);
280 return HotSpotObjectConstantImpl.forObject(o);
281 }
282 if (base instanceof HotSpotMetaspaceConstant) {
283 MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
284 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
285 if (displacement == runtime.getConfig().classMirrorHandleOffset) {
286 // Klass::_java_mirror is valid for all Klass* values
287 return HotSpotObjectConstantImpl.forObject(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror());
288 }
289 } else {
290 throw new IllegalArgumentException(String.valueOf(metaspaceObject));
291 }
292 }
293 return null;
294 }
295
296 @Override
297 public JavaConstant readNarrowOopConstant(Constant base, long displacement) {
298 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
299 }
300
301 private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) {
302 assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass();
303 Object baseObject = (base instanceof HotSpotMetaspaceConstantImpl) ? ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType() : ((HotSpotObjectConstantImpl) base).object();
304 return runtime.getCompilerToVM().getResolvedJavaType(baseObject, displacement, compressed);
305 }
306
307 @Override
308 public Constant readKlassPointerConstant(Constant base, long displacement) {
309 HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false);
310 if (klass == null) {
311 return JavaConstant.NULL_POINTER;
312 }
313 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false);
|