changeset 2989:1e4495ade29c

Fix: certain symbols are not specialized. If a class is non-specializable but one of its superclasses/superinterfaces is, the specialization machinery should produce a specialized symbol for such a class.
author mcimadamore
date Fri, 08 May 2015 12:58:36 +0100
parents 58e78a090947
children 4f7c56237d8c
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
diffstat 2 files changed, 38 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Tue Apr 28 12:15:23 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Fri May 08 12:58:36 2015 +0100
@@ -2353,7 +2353,7 @@
                         if (ownerParams.nonEmpty()) {
                             if (baseParams.isEmpty()) {
                                 // then base is a raw type
-                                return erasure(sym.type);
+                                return erasure(sym.type, ErasureKind.SOURCE);
                             } else {
                                 return subst(sym.type, ownerParams, baseParams);
                             }
@@ -2477,7 +2477,7 @@
 
             @Override
             public Type visitClassType(ClassType t, ErasureKind erasureKind) {
-                Type classToErase = t.tsym.completer == null ?
+                Type classToErase = t.tsym.completer == null && erasureKind.shouldSpecialize() ?
                         specialize(t) : t; // we cannot force completion at this stage!
                 Type erased = classToErase.tsym.erasure(Types.this);
                 if (erasureKind.shouldRecurse()) {
@@ -2542,7 +2542,7 @@
          * Specialized erasure behavior. Class types are specialized before erasure is applied.
          * Otherwise, behavior is same as with {@link com.sun.tools.javac.code.Types.ErasureKind##NORMAL}.
          */
-        SPECIALIZED;
+        SOURCE;
 
         boolean shouldRecurse() {
             return this == RECURSIVE;
@@ -2553,7 +2553,7 @@
         }
 
         boolean shouldSpecialize() {
-            return this == SPECIALIZED;
+            return this != SOURCE;
         }
     }
     // </editor-fold>
@@ -2574,8 +2574,7 @@
             //compute specialization of enclosing type
             Type specializedEncl = specialize(ct.getEnclosingType());
 
-            if (specializedEncl == ct.getEnclosingType() &&
-                    ct.getTypeArguments().stream().noneMatch(Type::isPrimitiveOrValue)) {
+            if (specializedEncl == ct.getEnclosingType() && !specializableClosureTypeArgs(ct)) {
                 //nothing to specialize - return
                 return ct;
             } else {
@@ -2638,6 +2637,38 @@
     };
 
     /**
+     * Does given type 't', or any of its declared supertypes contain any specializable type argument?
+     */
+    boolean specializableClosureTypeArgs(Type t) {
+        return specializableClosureTypeArgsInternal(t, new HashSet<>());
+    }
+    //where
+        private boolean specializableClosureTypeArgsInternal(Type t, Set<TypeSymbol> seen) {
+            if (!t.hasTag(CLASS) || !seen.add(t.tsym)) {
+                return false;
+            }
+            ClassType ctype = (ClassType)t;
+            if (ctype.typarams_field != null &&
+                    ctype.typarams_field.stream().anyMatch(Type::isPrimitiveOrValue)) {
+                return true;
+            }
+            ClassType symType = (ClassType)t.tsym.type;
+            if (symType.supertype_field != null) {
+                if (specializableClosureTypeArgsInternal(symType.supertype_field, seen)) {
+                    return true;
+                }
+            }
+            if (symType.interfaces_field != null) {
+                for (Type i : symType.interfaces_field) {
+                    if (specializableClosureTypeArgsInternal(i, seen)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+    /**
      * Main entry-point for type-specialization.
      */
     public Type specialize(Type t) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Apr 28 12:15:23 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 08 12:58:36 2015 +0100
@@ -3648,7 +3648,7 @@
                     // because no type parameters were given.
                     // We recover generic outer type later in visitTypeApply.
                     if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
-                        owntype = types.erasure(owntype);
+                        owntype = owntype.tsym.erasure(types);
                     }
 
                     // (b) If the symbol's type is an inner class, then