< prev index next >

src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java

Print this page




 150         HotSpotVMConfig config = config();
 151         return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
 152     }
 153 
 154     @Override
 155     public HotSpotResolvedObjectType getArrayClass() {
 156         if (arrayOfType == null) {
 157             arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
 158         }
 159         return arrayOfType;
 160     }
 161 
 162     @Override
 163     public ResolvedJavaType getComponentType() {
 164         Class<?> javaComponentType = mirror().getComponentType();
 165         return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
 166     }
 167 
 168     @Override
 169     public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {




 170         HotSpotVMConfig config = config();
 171         if (isArray()) {
 172             return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;












 173         } else if (isInterface()) {
 174             HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
 175             /*
 176              * If the implementor field contains itself that indicates that the interface has more
 177              * than one implementors (see: InstanceKlass::add_implementor).
 178              */
 179             if (implementor == null || implementor.equals(this)) {
 180                 return null;
 181             }
 182 
 183             assert !implementor.isInterface();
 184             if (implementor.isAbstract() || !implementor.isLeafClass()) {
 185                 AssumptionResult<ResolvedJavaType> leafConcreteSubtype = implementor.findLeafConcreteSubtype();
 186                 if (leafConcreteSubtype != null) {
 187                     assert !leafConcreteSubtype.getResult().equals(implementor);
 188                     AssumptionResult<ResolvedJavaType> newResult = new AssumptionResult<>(leafConcreteSubtype.getResult(), new ConcreteSubtype(this, implementor));
 189                     // Accumulate leaf assumptions and return the combined result.
 190                     newResult.add(leafConcreteSubtype);
 191                     return newResult;
 192                 }
 193                 return null;
 194             }
 195 
 196             return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor));
 197         } else {
 198             HotSpotResolvedObjectTypeImpl type = this;
 199             while (type.isAbstract()) {
 200                 HotSpotResolvedObjectTypeImpl subklass = type.getSubklass();
 201                 if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) {
 202                     return null;
 203                 }
 204                 type = subklass;
 205             }
 206             if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
 207                 return null;
 208             }
 209             if (this.isAbstract()) {
 210                 return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
 211             } else {
 212                 assert this.equals(type);
 213                 return new AssumptionResult<>(type, new LeafType(type));
 214             }
 215         }
 216     }
 217 








 218     /**
 219      * Returns if type {@code type} is a leaf class. This is the case if the
 220      * {@code Klass::_subklass} field of the underlying class is zero.
 221      *
 222      * @return true if the type is a leaf class
 223      */
 224     private boolean isLeafClass() {
 225         return getSubklass() == null;
 226     }
 227 
 228     /**
 229      * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
 230      * type {@code type}.
 231      *
 232      * @return value of the subklass field as metaspace klass pointer
 233      */
 234     private HotSpotResolvedObjectTypeImpl getSubklass() {
 235         return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false);
 236     }
 237 




 150         HotSpotVMConfig config = config();
 151         return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
 152     }
 153 
 154     @Override
 155     public HotSpotResolvedObjectType getArrayClass() {
 156         if (arrayOfType == null) {
 157             arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
 158         }
 159         return arrayOfType;
 160     }
 161 
 162     @Override
 163     public ResolvedJavaType getComponentType() {
 164         Class<?> javaComponentType = mirror().getComponentType();
 165         return javaComponentType == null ? null : runtime().fromClass(javaComponentType);
 166     }
 167 
 168     @Override
 169     public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
 170         if (isLeaf()) {
 171             // No assumptions are required.
 172             return new AssumptionResult<>(this);
 173         }
 174         HotSpotVMConfig config = config();
 175         if (isArray()) {
 176             ResolvedJavaType elementalType = getElementalType();
 177             AssumptionResult<ResolvedJavaType> elementType = elementalType.findLeafConcreteSubtype();
 178             if (elementType != null && elementType.getResult().equals(elementalType)) {
 179                 /*
 180                  * If the elementType is leaf then the array is leaf under the same assumptions but
 181                  * only if the element type is exactly the leaf type. The element type can be
 182                  * abstract even if there is only one implementor of the abstract type.
 183                  */
 184                 AssumptionResult<ResolvedJavaType> result = new AssumptionResult<>(this);
 185                 result.add(elementType);
 186                 return result;
 187             }
 188             return null;
 189         } else if (isInterface()) {
 190             HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
 191             /*
 192              * If the implementor field contains itself that indicates that the interface has more
 193              * than one implementors (see: InstanceKlass::add_implementor).
 194              */
 195             if (implementor == null || implementor.equals(this)) {
 196                 return null;
 197             }
 198 
 199             assert !implementor.isInterface();
 200             if (implementor.isAbstract() || !implementor.isLeafClass()) {
 201                 AssumptionResult<ResolvedJavaType> leafConcreteSubtype = implementor.findLeafConcreteSubtype();
 202                 if (leafConcreteSubtype != null) {
 203                     assert !leafConcreteSubtype.getResult().equals(implementor);
 204                     AssumptionResult<ResolvedJavaType> newResult = new AssumptionResult<>(leafConcreteSubtype.getResult(), new ConcreteSubtype(this, implementor));
 205                     // Accumulate leaf assumptions and return the combined result.
 206                     newResult.add(leafConcreteSubtype);
 207                     return newResult;
 208                 }
 209                 return null;
 210             }
 211             return concreteSubtype(implementor);

 212         } else {
 213             HotSpotResolvedObjectTypeImpl type = this;
 214             while (type.isAbstract()) {
 215                 HotSpotResolvedObjectTypeImpl subklass = type.getSubklass();
 216                 if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) {
 217                     return null;
 218                 }
 219                 type = subklass;
 220             }
 221             if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
 222                 return null;
 223             }
 224             if (this.isAbstract()) {
 225                 return concreteSubtype(type);
 226             } else {
 227                 assert this.equals(type);
 228                 return new AssumptionResult<>(type, new LeafType(type));
 229             }
 230         }
 231     }
 232 
 233     private AssumptionResult<ResolvedJavaType> concreteSubtype(HotSpotResolvedObjectTypeImpl type) {
 234         if (type.isLeaf()) {
 235             return new AssumptionResult<>(type, new ConcreteSubtype(this, type));
 236         } else {
 237             return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
 238         }
 239     }
 240 
 241     /**
 242      * Returns if type {@code type} is a leaf class. This is the case if the
 243      * {@code Klass::_subklass} field of the underlying class is zero.
 244      *
 245      * @return true if the type is a leaf class
 246      */
 247     private boolean isLeafClass() {
 248         return getSubklass() == null;
 249     }
 250 
 251     /**
 252      * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
 253      * type {@code type}.
 254      *
 255      * @return value of the subklass field as metaspace klass pointer
 256      */
 257     private HotSpotResolvedObjectTypeImpl getSubklass() {
 258         return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false);
 259     }
 260 


< prev index next >