8155047: [JVMCI] findLeafConcreteSubtype should handle arrays of leaf concrete subtype
authornever
Thu, 12 May 2016 22:06:55 +0000
changeset 38681 6e98a76ddaa1
parent 38680 d88f2ffa89fa
child 38682 f4750b9b2ff9
8155047: [JVMCI] findLeafConcreteSubtype should handle arrays of leaf concrete subtype Reviewed-by: twisti
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java
hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu May 12 18:11:14 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Thu May 12 22:06:55 2016 +0000
@@ -166,9 +166,25 @@
 
     @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 @@
                 }
                 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 @@
                 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 @@
         }
     }
 
+    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.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java	Thu May 12 18:11:14 2016 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java	Thu May 12 22:06:55 2016 +0000
@@ -44,7 +44,10 @@
 
     /**
      * 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 ResolvedJavaType context;
 
         public LeafType(ResolvedJavaType context) {
+            assert !context.isLeaf() : "assumption isn't required for leaf types";
             this.context = context;
         }
 
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Thu May 12 18:11:14 2016 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Thu May 12 22:06:55 2016 +0000
@@ -328,6 +328,7 @@
             } else {
                 assertTrue(leafConcreteSubtype.getResult().equals(expected));
             }
+            assertTrue(!type.isLeaf() || leafConcreteSubtype.isAssumptionFree());
         }
 
         if (!type.isArray()) {
@@ -372,8 +373,10 @@
 
         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);