< prev index next >
src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
Print this page
*** 20,47 ****
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
! import static java.util.Objects.*;
! import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
! import java.lang.annotation.*;
! import java.lang.reflect.*;
! import java.net.*;
! import java.nio.*;
! import java.util.*;
!
! import jdk.vm.ci.common.*;
! import jdk.vm.ci.meta.*;
! import jdk.vm.ci.meta.Assumptions.*;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
! public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
/**
* The Java class this type represents.
*/
private final Class<?> javaClass;
--- 20,67 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
! import static java.util.Objects.requireNonNull;
! import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
! import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
! import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
! import java.lang.annotation.Annotation;
! import java.lang.reflect.Array;
! import java.lang.reflect.Constructor;
! import java.lang.reflect.Method;
! import java.lang.reflect.Modifier;
! import java.net.URL;
! import java.nio.ByteOrder;
! import java.util.ArrayList;
! import java.util.Arrays;
! import java.util.HashMap;
!
! import jdk.vm.ci.common.JVMCIError;
! import jdk.vm.ci.meta.Assumptions.AssumptionResult;
! import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
! import jdk.vm.ci.meta.Assumptions.ConcreteSubtype;
! import jdk.vm.ci.meta.Assumptions.LeafType;
! import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass;
! import jdk.vm.ci.meta.Constant;
! import jdk.vm.ci.meta.JavaConstant;
! import jdk.vm.ci.meta.JavaKind;
! import jdk.vm.ci.meta.JavaType;
! import jdk.vm.ci.meta.MetaUtil;
! import jdk.vm.ci.meta.ModifiersProvider;
! import jdk.vm.ci.meta.ResolvedJavaField;
! import jdk.vm.ci.meta.ResolvedJavaMethod;
! import jdk.vm.ci.meta.ResolvedJavaType;
! import jdk.vm.ci.meta.TrustedInterface;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
! final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
/**
* The Java class this type represents.
*/
private final Class<?> javaClass;
*** 56,66 ****
/**
* Gets the JVMCI mirror for a {@link Class} object.
*
* @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
*/
! public static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass);
}
/**
* Gets the JVMCI mirror from a HotSpot type. Since {@link Class} is already a proxy for the
--- 76,86 ----
/**
* Gets the JVMCI mirror for a {@link Class} object.
*
* @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
*/
! static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass);
}
/**
* Gets the JVMCI mirror from a HotSpot type. Since {@link Class} is already a proxy for the
*** 106,120 ****
}
/**
* Gets the metaspace Klass for this type.
*/
! public long getMetaspaceKlass() {
if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
! return UNSAFE.getLong(javaClass, (long) runtime().getConfig().klassOffset);
}
! return UNSAFE.getInt(javaClass, (long) runtime().getConfig().klassOffset) & 0xFFFFFFFFL;
}
public long getMetaspacePointer() {
return getMetaspaceKlass();
}
--- 126,140 ----
}
/**
* Gets the metaspace Klass for this type.
*/
! long getMetaspaceKlass() {
if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
! return UNSAFE.getLong(javaClass, (long) config().klassOffset);
}
! return UNSAFE.getInt(javaClass, (long) config().klassOffset) & 0xFFFFFFFFL;
}
public long getMetaspacePointer() {
return getMetaspaceKlass();
}
*** 127,137 ****
return getAccessFlags() & ModifiersProvider.jvmClassModifiers();
}
}
public int getAccessFlags() {
! HotSpotVMConfig config = runtime().getConfig();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
}
@Override
public HotSpotResolvedObjectType getArrayClass() {
--- 147,157 ----
return getAccessFlags() & ModifiersProvider.jvmClassModifiers();
}
}
public int getAccessFlags() {
! HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
}
@Override
public HotSpotResolvedObjectType getArrayClass() {
*** 147,157 ****
return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
}
@Override
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
! HotSpotVMConfig config = runtime().getConfig();
if (isArray()) {
return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
} else if (isInterface()) {
HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
/*
--- 167,177 ----
return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
}
@Override
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
! HotSpotVMConfig config = config();
if (isArray()) {
return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
} else if (isInterface()) {
HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
/*
*** 212,222 ****
* type {@code type}.
*
* @return value of the subklass field as metaspace klass pointer
*/
private HotSpotResolvedObjectTypeImpl getSubklass() {
! return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().subklassOffset, false);
}
@Override
public HotSpotResolvedObjectTypeImpl getSuperclass() {
Class<?> javaSuperclass = mirror().getSuperclass();
--- 232,242 ----
* type {@code type}.
*
* @return value of the subklass field as metaspace klass pointer
*/
private HotSpotResolvedObjectTypeImpl getSubklass() {
! return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false);
}
@Override
public HotSpotResolvedObjectTypeImpl getSuperclass() {
Class<?> javaSuperclass = mirror().getSuperclass();
*** 239,249 ****
@Override
public HotSpotResolvedObjectTypeImpl getSingleImplementor() {
if (!isInterface()) {
throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
}
! return runtime().getCompilerToVM().getImplementor(this);
}
public HotSpotResolvedObjectTypeImpl getSupertype() {
if (isArray()) {
ResolvedJavaType componentType = getComponentType();
--- 259,269 ----
@Override
public HotSpotResolvedObjectTypeImpl getSingleImplementor() {
if (!isInterface()) {
throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
}
! return compilerToVM().getImplementor(this);
}
public HotSpotResolvedObjectTypeImpl getSupertype() {
if (isArray()) {
ResolvedJavaType componentType = getComponentType();
*** 287,312 ****
public JavaConstant getJavaClass() {
return HotSpotObjectConstantImpl.forObject(mirror());
}
@Override
! public JavaConstant getObjectHub() {
return klass();
}
@Override
public AssumptionResult<Boolean> hasFinalizableSubclass() {
assert !isArray();
! if (!runtime().getCompilerToVM().hasFinalizableSubclass(this)) {
return new AssumptionResult<>(false, new NoFinalizableSubclass(this));
}
return new AssumptionResult<>(true);
}
@Override
public boolean hasFinalizer() {
! HotSpotVMConfig config = runtime().getConfig();
return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
}
@Override
public boolean isPrimitive() {
--- 307,332 ----
public JavaConstant getJavaClass() {
return HotSpotObjectConstantImpl.forObject(mirror());
}
@Override
! public Constant getObjectHub() {
return klass();
}
@Override
public AssumptionResult<Boolean> hasFinalizableSubclass() {
assert !isArray();
! if (!compilerToVM().hasFinalizableSubclass(this)) {
return new AssumptionResult<>(false, new NoFinalizableSubclass(this));
}
return new AssumptionResult<>(true);
}
@Override
public boolean hasFinalizer() {
! HotSpotVMConfig config = config();
return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
}
@Override
public boolean isPrimitive() {
*** 318,344 ****
return mirror().isArray();
}
@Override
public boolean isInitialized() {
! return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized;
}
@Override
public boolean isLinked() {
! return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked;
}
/**
* Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
* klass.
*
* @return state field value of this type
*/
private int getInitState() {
assert !isArray() : "_init_state only exists in InstanceKlass";
! return UNSAFE.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF;
}
@Override
public void initialize() {
if (!isInitialized()) {
--- 338,364 ----
return mirror().isArray();
}
@Override
public boolean isInitialized() {
! return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized;
}
@Override
public boolean isLinked() {
! return isArray() ? true : getInitState() >= config().instanceKlassStateLinked;
}
/**
* Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
* klass.
*
* @return state field value of this type
*/
private int getInitState() {
assert !isArray() : "_init_state only exists in InstanceKlass";
! return UNSAFE.getByte(getMetaspaceKlass() + config().instanceKlassInitStateOffset) & 0xFF;
}
@Override
public void initialize() {
if (!isInitialized()) {
*** 403,418 ****
if (!method.getDeclaringClass().isAssignableFrom(this)) {
return null;
}
HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
! return runtime().getCompilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
}
public HotSpotConstantPool getConstantPool() {
if (constantPool == null) {
! constantPool = runtime().getCompilerToVM().getConstantPool(this, runtime().getConfig().instanceKlassConstantsOffset);
}
return constantPool;
}
/**
--- 423,438 ----
if (!method.getDeclaringClass().isAssignableFrom(this)) {
return null;
}
HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
! return compilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
}
public HotSpotConstantPool getConstantPool() {
if (constantPool == null) {
! constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset);
}
return constantPool;
}
/**
*** 422,432 ****
*/
public int instanceSize() {
assert !isArray();
assert !isInterface();
! HotSpotVMConfig config = runtime().getConfig();
final int layoutHelper = layoutHelper();
assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
// See: Klass::layout_helper_size_in_bytes
int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit;
--- 442,452 ----
*/
public int instanceSize() {
assert !isArray();
assert !isInterface();
! HotSpotVMConfig config = config();
final int layoutHelper = layoutHelper();
assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
// See: Klass::layout_helper_size_in_bytes
int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit;
*** 436,446 ****
return needsSlowPath ? -size : size;
}
public int layoutHelper() {
! HotSpotVMConfig config = runtime().getConfig();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset);
}
synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
HotSpotResolvedJavaMethodImpl method = null;
--- 456,466 ----
return needsSlowPath ? -size : size;
}
public int layoutHelper() {
! HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset);
}
synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
HotSpotResolvedJavaMethodImpl method = null;
*** 456,466 ****
}
return method;
}
public int getVtableLength() {
! HotSpotVMConfig config = runtime().getConfig();
if (isInterface() || isArray()) {
/* Everything has the core vtable of java.lang.Object */
return config.baseVtableLength();
}
int result = UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
--- 476,486 ----
}
return method;
}
public int getVtableLength() {
! HotSpotVMConfig config = config();
if (isInterface() || isArray()) {
/* Everything has the core vtable of java.lang.Object */
return config.baseVtableLength();
}
int result = UNSAFE.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
*** 545,575 ****
* Creates a field info for the field in the fields array at index {@code index}.
*
* @param index index to the fields array
*/
public FieldInfo(int index) {
! HotSpotVMConfig config = runtime().getConfig();
// Get Klass::_fields
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index;
}
private int getAccessFlags() {
! return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
}
private int getNameIndex() {
! return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
}
private int getSignatureIndex() {
! return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
}
public int getOffset() {
! HotSpotVMConfig config = runtime().getConfig();
final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
return offset;
}
--- 565,595 ----
* Creates a field info for the field in the fields array at index {@code index}.
*
* @param index index to the fields array
*/
public FieldInfo(int index) {
! HotSpotVMConfig config = config();
// Get Klass::_fields
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index;
}
private int getAccessFlags() {
! return readFieldSlot(config().fieldInfoAccessFlagsOffset);
}
private int getNameIndex() {
! return readFieldSlot(config().fieldInfoNameIndexOffset);
}
private int getSignatureIndex() {
! return readFieldSlot(config().fieldInfoSignatureIndexOffset);
}
public int getOffset() {
! HotSpotVMConfig config = config();
final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
return offset;
}
*** 604,622 ****
String signature = getSignature();
return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false);
}
private boolean isInternal() {
! return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
}
public boolean isStatic() {
return Modifier.isStatic(getAccessFlags());
}
public boolean hasGenericSignature() {
! return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
}
}
private static class OffsetComparator implements java.util.Comparator<HotSpotResolvedJavaField> {
@Override
--- 624,642 ----
String signature = getSignature();
return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false);
}
private boolean isInternal() {
! return (getAccessFlags() & config().jvmAccFieldInternal) != 0;
}
public boolean isStatic() {
return Modifier.isStatic(getAccessFlags());
}
public boolean hasGenericSignature() {
! return (getAccessFlags() & config().jvmAccFieldHasGenericSignature) != 0;
}
}
private static class OffsetComparator implements java.util.Comparator<HotSpotResolvedJavaField> {
@Override
*** 705,715 ****
*
* <p>
* See {@code FieldStreamBase::init_generic_signature_start_slot}
*/
private int getFieldCount() {
! HotSpotVMConfig config = runtime().getConfig();
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset);
int fieldCount = 0;
for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) {
--- 725,735 ----
*
* <p>
* See {@code FieldStreamBase::init_generic_signature_start_slot}
*/
private int getFieldCount() {
! HotSpotVMConfig config = config();
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset);
int fieldCount = 0;
for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) {
*** 727,737 ****
return javaClass;
}
@Override
public String getSourceFileName() {
! HotSpotVMConfig config = runtime().getConfig();
final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
if (sourceFileNameIndex == 0) {
return null;
}
return getConstantPool().lookupUtf8(sourceFileNameIndex);
--- 747,757 ----
return javaClass;
}
@Override
public String getSourceFileName() {
! HotSpotVMConfig config = config();
final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
if (sourceFileNameIndex == 0) {
return null;
}
return getConstantPool().lookupUtf8(sourceFileNameIndex);
*** 782,806 ****
}
/**
* Gets the metaspace Klass boxed in a {@link JavaConstant}.
*/
! public JavaConstant klass() {
! return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime().getHostJVMCIBackend().getTarget().wordKind, getMetaspaceKlass(), this, false);
}
public boolean isPrimaryType() {
! return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
}
public int superCheckOffset() {
! HotSpotVMConfig config = runtime().getConfig();
return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
}
public long prototypeMarkWord() {
! HotSpotVMConfig config = runtime().getConfig();
if (isArray()) {
return config.arrayPrototypeMarkWord();
} else {
return UNSAFE.getAddress(getMetaspaceKlass() + config.prototypeMarkWordOffset);
}
--- 802,826 ----
}
/**
* Gets the metaspace Klass boxed in a {@link JavaConstant}.
*/
! public Constant klass() {
! return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
public boolean isPrimaryType() {
! return config().secondarySuperCacheOffset != superCheckOffset();
}
public int superCheckOffset() {
! HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
}
public long prototypeMarkWord() {
! HotSpotVMConfig config = config();
if (isArray()) {
return config.arrayPrototypeMarkWord();
} else {
return UNSAFE.getAddress(getMetaspaceKlass() + config.prototypeMarkWordOffset);
}
*** 872,882 ****
}
return result;
}
public ResolvedJavaMethod getClassInitializer() {
! return runtime().getCompilerToVM().getClassInitializer(this);
}
@Override
public String toString() {
return "HotSpotType<" + getName() + ", resolved>";
--- 892,902 ----
}
return result;
}
public ResolvedJavaMethod getClassInitializer() {
! return compilerToVM().getClassInitializer(this);
}
@Override
public String toString() {
return "HotSpotType<" + getName() + ", resolved>";
< prev index next >