8155047: [JVMCI] findLeafConcreteSubtype should handle arrays of leaf concrete subtype

Reviewed-by: twisti
This commit is contained in:
Tom Rodriguez 2016-05-12 22:06:55 +00:00
parent 4c94cba880
commit 5405125902
3 changed files with 36 additions and 6 deletions

View File

@ -166,9 +166,25 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
@Override
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
if (isLeaf()) {
// No assumptions are required.
return new AssumptionResult<>(this);
}
HotSpotVMConfig config = config();
if (isArray()) {
return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
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();
/*
@ -191,8 +207,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
}
return null;
}
return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor));
return concreteSubtype(implementor);
} else {
HotSpotResolvedObjectTypeImpl type = this;
while (type.isAbstract()) {
@ -206,7 +221,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return null;
}
if (this.isAbstract()) {
return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
return concreteSubtype(type);
} else {
assert this.equals(type);
return new AssumptionResult<>(type, new LeafType(type));
@ -214,6 +229,14 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
}
}
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.

View File

@ -44,7 +44,10 @@ public final class Assumptions implements Iterable<Assumptions.Assumption> {
/**
* A class for providing information that is only valid in association with a set of
* {@link Assumption}s.
* {@link Assumption}s. It is permissible for AssumptionResults to have no assumptions at all.
* For instance, if {@link ResolvedJavaType#isLeaf()} returns true for a type
* {@link ResolvedJavaType#findLeafConcreteSubtype()} can return an AssumptionResult with no
* assumptions since the leaf information is statically true.
*
* @param <T>
*/
@ -187,6 +190,7 @@ public final class Assumptions implements Iterable<Assumptions.Assumption> {
public final ResolvedJavaType context;
public LeafType(ResolvedJavaType context) {
assert !context.isLeaf() : "assumption isn't required for leaf types";
this.context = context;
}

View File

@ -328,6 +328,7 @@ public class TestResolvedJavaType extends TypeUniverse {
} else {
assertTrue(leafConcreteSubtype.getResult().equals(expected));
}
assertTrue(!type.isLeaf() || leafConcreteSubtype.isAssumptionFree());
}
if (!type.isArray()) {
@ -372,8 +373,10 @@ public class TestResolvedJavaType extends TypeUniverse {
ResolvedJavaType a1a = metaAccess.lookupJavaType(Abstract1[].class);
checkConcreteSubtype(a1a, null);
ResolvedJavaType i1a = metaAccess.lookupJavaType(Interface1[].class);
checkConcreteSubtype(i1a, null);
ResolvedJavaType c1a = metaAccess.lookupJavaType(Concrete1[].class);
checkConcreteSubtype(c1a, null);
checkConcreteSubtype(c1a, c1a);
ResolvedJavaType f1a = metaAccess.lookupJavaType(Final1[].class);
checkConcreteSubtype(f1a, f1a);