changeset 3507:9bec39f205ed

Fix: abstract conditional methods are missing ACC_ABSTRACT Fix: Methodref emitted instead of InterfaceMethodref when receiver is type-var with interface bound Fix: String concatenation doesn't work on any type-variables
author mcimadamore
date Thu, 21 Apr 2016 17:51:53 +0100
parents 961eb443422f
children 162ea1f3dfd9
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 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java
diffstat 5 files changed, 103 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Mon Apr 18 17:33:12 2016 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu Apr 21 17:51:53 2016 +0100
@@ -3207,6 +3207,39 @@
         return false;
     }
 
+    public Symbol objectMethodsClass(Type site) {
+        ClassSymbol objectMethodClass = new ClassSymbol(PUBLIC, names.java_lang_Object, syms.unnamedPackage) {
+            @Override
+            public Symbol baseSymbol() {
+                return syms.objectType.tsym;
+            }
+        };
+        objectMethodClass.type = new ClassType(Type.noType, List.nil(), objectMethodClass);
+        WriteableScope objectMethodClassScope = objectMethodClass.members_field = WriteableScope.create(objectMethodClass);
+        for (Symbol s : syms.objectType.tsym.members().getSymbols(s -> s.kind == MTH)) {
+            Symbol translatedSym = anyObjectMethod(s, site, objectMethodClass);
+            if (translatedSym != null) {
+                objectMethodClassScope.enter(translatedSym);
+            }
+        }
+        return objectMethodClass;
+    }
+
+
+    private Symbol anyObjectMethod(Symbol baseMethod, Type site, ClassSymbol origin) {
+        switch (baseMethod.name.toString()) {
+            case "equals":
+                Symbol strictEquals = baseMethod.clone(origin);
+                strictEquals.type = createMethodTypeWithParameters(baseMethod.type, List.of(site));
+                return strictEquals;
+            case "toString":
+            case "hashCode":
+                return baseMethod.clone(origin);
+            default:
+                return null;
+        }
+    }
+
     // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
     class ImplementationCache {
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Apr 18 17:33:12 2016 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Apr 21 17:51:53 2016 +0100
@@ -3629,7 +3629,7 @@
                 Symbol sym = null;
                 if (site.getUpperBound() != null) {
                  sym = types.isSpecializableTypeVar(site) ?
-                         selectSym(tree, location, objectMethodsClass(site).type, env, resultInfo) :
+                         selectSym(tree, location, types.objectMethodsClass(site).type, env, resultInfo) :
                          selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo);
                 }
                 if (sym == null) {
@@ -3662,39 +3662,6 @@
                 }
             }
         }
-        //where
-            private Symbol objectMethodsClass(Type site) {
-                ClassSymbol objectMethodClass = new ClassSymbol(PUBLIC, names.java_lang_Object, syms.unnamedPackage) {
-                    @Override
-                    public Symbol baseSymbol() {
-                        return syms.objectType.tsym;
-                    }
-                };
-                objectMethodClass.type = new ClassType(Type.noType, List.nil(), objectMethodClass);
-                WriteableScope objectMethodClassScope = objectMethodClass.members_field = WriteableScope.create(objectMethodClass);
-                for (Symbol s : syms.objectType.tsym.members().getSymbols(s -> s.kind == MTH)) {
-                    Symbol translatedSym = anyObjectMethod(s, site, objectMethodClass);
-                    if (translatedSym != null) {
-                        objectMethodClassScope.enter(translatedSym);
-                    }
-                }
-                return objectMethodClass;
-            }
-
-
-            private Symbol anyObjectMethod(Symbol baseMethod, Type site, ClassSymbol origin) {
-                switch (baseMethod.name.toString()) {
-                    case "equals":
-                        Symbol strictEquals = baseMethod.clone(origin);
-                        strictEquals.type = types.createMethodTypeWithParameters(baseMethod.type, List.of(site));
-                        return strictEquals;
-                    case "toString":
-                    case "hashCode":
-                        return baseMethod.clone(origin);
-                    default:
-                        return null;
-                }
-            }
 
         /** Determine type of identifier or select expression and check that
          *  (1) the referenced symbol is not deprecated
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Mon Apr 18 17:33:12 2016 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Thu Apr 21 17:51:53 2016 +0100
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.comp;
 
 import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Flags.Flag;
 import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
@@ -471,6 +472,10 @@
         //create new method symbol
         MethodSymbol msym = md.sym;
         MethodSymbol dupMethod = msym.clone(msym.owner);
+        if ((body.flags & Flags.ABSTRACT) != 0) {
+            dupMethod.flags_field |= Flags.ABSTRACT;
+            dupMethod.flags_field &= ~Flags.DEFAULT;
+        }
         dupMethod.flags_field |= body.flags;
         dupMethod.whereClauses = whereClauses;
 
@@ -485,7 +490,7 @@
         //create new tree
         List<JCVariableDecl> paramTrees = dupParams.stream().map(p -> make.VarDef((VarSymbol)p, null)).collect(List.collector());
 
-        JCMethodDecl dupMd = make.MethodDef(make.Modifiers(md.mods.flags | body.flags),
+        JCMethodDecl dupMd = make.MethodDef(make.Modifiers(dupMethod.flags_field),
                 dupMethod.name, md.restype, md.typarams, null, paramTrees, md.thrown,
                 (body.flags & Flags.ABSTRACT) == 0 ? body : null, null, body.whereClauses);
         dupMd.sym = dupMethod;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Mon Apr 18 17:33:12 2016 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java	Thu Apr 21 17:51:53 2016 +0100
@@ -361,7 +361,7 @@
                 case VAR:
                     return ClassFile.CONSTANT_Fieldref;
                 case MTH:
-                    return site.tsym.isInterface() ?
+                    return types.skipTypeVars(site, false).tsym.isInterface() ?
                             ClassFile.CONSTANT_InterfaceMethodref : ClassFile.CONSTANT_Methodref;
                 default:
                     Assert.error("Invalid symbol: " + sym);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java	Mon Apr 18 17:33:12 2016 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/StringConcat.java	Thu Apr 21 17:51:53 2016 +0100
@@ -27,7 +27,9 @@
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol.BootstrapArgument;
+import com.sun.tools.javac.code.Type.MethodType;
 import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.jvm.Gen.Descriptor;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.tree.TreeMaker;
@@ -39,9 +41,11 @@
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.PLUS;
 import com.sun.tools.javac.jvm.Items.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /** This lowers the String concatenation to something that JVM can understand.
  *
@@ -143,6 +147,41 @@
         return res.append(tree);
     }
 
+    protected void makeIndy(DiagnosticPosition pos, MethodType indyType, List<? extends BootstrapArgument<?>> staticArgs, Type bsmClass, Name bsmName) {
+        int prevPos = make.pos;
+        try {
+            make.at(pos);
+
+            List<Type> constTypes = staticArgs.stream()
+                    .map(sa -> sa.kind.asType(syms))
+                    .collect(List.collector());
+
+            List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
+                    syms.stringType,
+                    syms.methodTypeType)
+                    .appendList(constTypes);
+
+            Symbol bsm = rs.resolveInternalMethod(pos,
+                    gen.getAttrEnv(),
+                    bsmClass,
+                    bsmName,
+                    bsm_staticArgs,
+                    null);
+
+            Symbol.DynamicMethodSymbol dynSym = new Symbol.DynamicMethodSymbol(bsmName,
+                    syms.noSymbol,
+                    ClassFile.REF_invokeStatic,
+                    (Symbol.MethodSymbol)bsm,
+                    indyType,
+                    staticArgs.stream().toArray(BootstrapArgument<?>[]::new));
+
+            Items.Item item = gen.getItems().makeDynamicItem(dynSym);
+            item.invoke();
+        } finally {
+            make.at(prevPos);
+        }
+    }
+
     /**
      * "Legacy" bytecode flavor: emit the StringBuilder.append chains for string
      * concatenation.
@@ -214,7 +253,13 @@
 
         private void appendString(JCTree tree) {
             Type t = tree.type.baseType();
-            if (!t.isPrimitive() && t.tsym != syms.stringType.tsym) {
+            Type unerasedType = TreeInfo.unerasedTypeOrType(tree);
+            if (types.isSpecializableTypeVar(unerasedType)) {
+                //this duplicates the logic in SpecializeTypes.makeObjectibleCall to covert anyfied vars into strings
+                MethodType indyType = new MethodType(List.of(unerasedType), syms.stringType, List.nil(), syms.methodClass);
+                makeIndy(tree, indyType, List.nil(), syms.objectibleDispatch, names.metafactory);
+                t = syms.stringType;
+            } else if (!t.isPrimitive() && t.tsym != syms.stringType.tsym) {
                 t = syms.objectType;
             }
 
@@ -311,13 +356,16 @@
                 ListBuffer<Type> dynamicArgs = new ListBuffer<>();
                 for (JCTree arg : t) {
                     Object constVal = arg.type.constValue();
+                    Type unerased = TreeInfo.unerasedTypeOrType(arg);
+                    Type dynamicArgType = types.isSpecializableTypeVar(unerased) ?
+                            unerased : arg.type;
                     if ("".equals(constVal)) continue;
                     if (arg.type == syms.botType) {
                         dynamicArgs.add(types.boxedClass(syms.voidType).type);
                     } else {
-                        dynamicArgs.add(arg.type);
+                        dynamicArgs.add(dynamicArgType);
                     }
-                    gen.genExpr(arg, arg.type).load();
+                    gen.genExpr(arg, dynamicArgType).load();
                 }
 
                 doCall(type, pos, dynamicArgs.toList());
@@ -339,34 +387,7 @@
                     type,
                     List.<Type>nil(),
                     syms.methodClass);
-
-            int prevPos = make.pos;
-            try {
-                make.at(pos);
-
-                List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
-                        syms.stringType,
-                        syms.methodTypeType);
-
-                Symbol bsm = rs.resolveInternalMethod(pos,
-                        gen.getAttrEnv(),
-                        syms.stringConcatFactory,
-                        names.makeConcat,
-                        bsm_staticArgs,
-                        null);
-
-                Symbol.DynamicMethodSymbol dynSym = new Symbol.DynamicMethodSymbol(names.makeConcat,
-                        syms.noSymbol,
-                        ClassFile.REF_invokeStatic,
-                        (Symbol.MethodSymbol)bsm,
-                        indyType,
-                        new BootstrapArgument<?>[0]);
-
-                Items.Item item = gen.getItems().makeDynamicItem(dynSym);
-                item.invoke();
-            } finally {
-                make.at(prevPos);
-            }
+            makeIndy(pos, indyType, List.nil(), syms.stringConcatFactory, names.makeConcat);
         }
     }
 
@@ -416,8 +437,11 @@
                     } else {
                         // Ordinary arguments come through the dynamic arguments.
                         recipe.append(TAG_ARG);
-                        dynamicArgs.add(arg.type);
-                        gen.genExpr(arg, arg.type).load();
+                        Type unerased = TreeInfo.unerasedTypeOrType(arg);
+                        Type dynamicArgType = types.isSpecializableTypeVar(unerased) ?
+                                unerased : arg.type;
+                        dynamicArgs.add(dynamicArgType);
+                        gen.genExpr(arg, dynamicArgType).load();
                     }
                 }
 
@@ -443,43 +467,12 @@
                     type,
                     List.<Type>nil(),
                     syms.methodClass);
-
-            int prevPos = make.pos;
-            try {
-                make.at(pos);
-
-                ListBuffer<Type> constTypes = new ListBuffer<>();
-                ListBuffer<BootstrapArgument<String>> constants = new ListBuffer<>();
-                for (Object t : staticArgs) {
-                    constants.add(BootstrapArgument.String((String)t));
-                    constTypes.add(syms.stringType);
-                }
-
-                List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
-                        syms.stringType,
-                        syms.methodTypeType)
-                        .append(syms.stringType)
-                        .appendList(constTypes);
-
-                Symbol bsm = rs.resolveInternalMethod(pos,
-                        gen.getAttrEnv(),
-                        syms.stringConcatFactory,
-                        names.makeConcatWithConstants,
-                        bsm_staticArgs,
-                        null);
-
-                Symbol.DynamicMethodSymbol dynSym = new Symbol.DynamicMethodSymbol(names.makeConcatWithConstants,
-                        syms.noSymbol,
-                        ClassFile.REF_invokeStatic,
-                        (Symbol.MethodSymbol)bsm,
-                        indyType,
-                        List.of(BootstrapArgument.String(recipe)).appendList(constants).stream().toArray(BootstrapArgument<?>[]::new));
-
-                Items.Item item = gen.getItems().makeDynamicItem(dynSym);
-                item.invoke();
-            } finally {
-                make.at(prevPos);
+            ListBuffer<BootstrapArgument<String>> constants = new ListBuffer<>();
+            constants.add(BootstrapArgument.String(recipe));
+            for (Object t : staticArgs) {
+                constants.add(BootstrapArgument.String((String)t));
             }
+            makeIndy(pos, indyType, constants.toList(), syms.stringConcatFactory, names.makeConcatWithConstants);
         }
     }