< prev index next >

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

Print this page

        

*** 165,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(); /* * If the implementor field contains itself that indicates that the interface has more * than one implementors (see: InstanceKlass::add_implementor). --- 165,193 ---- return javaComponentType == null ? null : runtime().fromClass(javaComponentType); } @Override public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() { + if (isLeaf()) { + // No assumptions are required. + return new AssumptionResult<>(this); + } HotSpotVMConfig config = config(); if (isArray()) { ! ResolvedJavaType elementalType = getElementalType(); ! AssumptionResult<ResolvedJavaType> elementType = elementalType.findLeafConcreteSubtype(); ! if (elementType != null && elementType.getResult().equals(elementalType)) { ! /* ! * If the elementType is leaf then the array is leaf under the same assumptions but ! * only if the element type is exactly the leaf type. The element type can be ! * abstract even if there is only one implementor of the abstract type. ! */ ! AssumptionResult<ResolvedJavaType> result = new AssumptionResult<>(this); ! result.add(elementType); ! return result; ! } ! return null; } else if (isInterface()) { HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor(); /* * If the implementor field contains itself that indicates that the interface has more * than one implementors (see: InstanceKlass::add_implementor).
*** 190,201 **** newResult.add(leafConcreteSubtype); return newResult; } return null; } ! ! return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor)); } else { HotSpotResolvedObjectTypeImpl type = this; while (type.isAbstract()) { HotSpotResolvedObjectTypeImpl subklass = type.getSubklass(); if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) { --- 206,216 ---- newResult.add(leafConcreteSubtype); return newResult; } return null; } ! return concreteSubtype(implementor); } else { HotSpotResolvedObjectTypeImpl type = this; while (type.isAbstract()) { HotSpotResolvedObjectTypeImpl subklass = type.getSubklass(); if (subklass == null || UNSAFE.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) {
*** 205,222 **** } if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { return null; } if (this.isAbstract()) { ! return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type)); } else { assert this.equals(type); return new AssumptionResult<>(type, new LeafType(type)); } } } /** * Returns if type {@code type} is a leaf class. This is the case if the * {@code Klass::_subklass} field of the underlying class is zero. * * @return true if the type is a leaf class --- 220,245 ---- } if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) { return null; } if (this.isAbstract()) { ! return concreteSubtype(type); } else { assert this.equals(type); return new AssumptionResult<>(type, new LeafType(type)); } } } + private AssumptionResult<ResolvedJavaType> concreteSubtype(HotSpotResolvedObjectTypeImpl type) { + if (type.isLeaf()) { + return new AssumptionResult<>(type, new ConcreteSubtype(this, type)); + } else { + return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type)); + } + } + /** * Returns if type {@code type} is a leaf class. This is the case if the * {@code Klass::_subklass} field of the underlying class is zero. * * @return true if the type is a leaf class
< prev index next >