changeset 49051:07169fef7503 condy-folding

activating generation of local variable initializers when debug info is on
author vromero
date Tue, 06 Feb 2018 09:23:31 -0500
parents 64ab5b0ebb34
children c6df9d85827a
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstablesVisitor.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java test/langtools/tools/javac/specialConstantFolding/IndyCrashTest.out
diffstat 6 files changed, 127 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstablesVisitor.java	Thu Feb 01 21:29:03 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstablesVisitor.java	Tue Feb 06 09:23:31 2018 -0500
@@ -25,9 +25,12 @@
 
 package com.sun.tools.javac.comp;
 
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 
-import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.DynamicFieldSymbol;
 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
@@ -51,6 +54,7 @@
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
 import com.sun.tools.javac.tree.TreeTranslator;
 import com.sun.tools.javac.util.Constables;
 import com.sun.tools.javac.util.Context;
@@ -63,6 +67,8 @@
 
 import static com.sun.tools.javac.code.Kinds.Kind.VAR;
 import static com.sun.tools.javac.code.TypeTag.NONE;
+import static com.sun.tools.javac.main.Option.G;
+import static com.sun.tools.javac.main.Option.G_CUSTOM;
 
 /**
  *  <p><b>This is NOT part of any supported API.
@@ -70,7 +76,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public class ConstablesVisitor extends TreeTranslator {
+public class ConstablesVisitor extends TreeScanner {
     protected static final Context.Key<ConstablesVisitor> constablesVisitorKey = new Context.Key<>();
 
     public static ConstablesVisitor instance(Context context) {
@@ -86,6 +92,7 @@
     private final Log log;
     private final ConstFold cfolder;
     private final Constables constables;
+    private final boolean varDebugInfo;
     private final TreeMaker make;
 
     protected ConstablesVisitor(Context context) {
@@ -99,6 +106,11 @@
         cfolder = ConstFold.instance(context);
         make = TreeMaker.instance(context);
         constables = new Constables(context);
+        varDebugInfo =
+            options.isUnset(G_CUSTOM)
+            ? options.isSet(G)
+            : options.isSet(G_CUSTOM, "vars");
+        elementToConstantMap = new HashMap<>();
     }
 
     /**
@@ -108,47 +120,53 @@
 
     private Env<AttrContext> attrEnv;
 
+    public Map<Object, Object> elementToConstantMap;
+
     public JCTree analyzeTree(JCTree tree, Env<AttrContext> attrEnv) {
-        if (!doConstantFold) {
+        try {
+            if (!doConstantFold) {
+                return tree;
+            }
+            this.attrEnv = attrEnv;
+            scan(tree);
+            if (!varDebugInfo) {
+                tree = constablesSetter.translate(tree);
+            }
             return tree;
+        } finally {
+            elementToConstantMap.clear();
         }
-        this.attrEnv = attrEnv;
-        return translate(tree);
     }
 
     @Override
     public void visitVarDef(JCVariableDecl tree) {
         super.visitVarDef(tree);
-        tree = (JCVariableDecl)result;
         if (tree.init != null) {
             VarSymbol v = tree.sym;
-            Object constant = tree.init.type.constValue();
+            Object constant = getConstant(tree.init);
             if (constant != null &&
                     (v.isFinal() || v.isEffectivelyFinal())) {
-                v.setData(constant);
-            }
-            if (v.isLocal() &&
-                v.owner.kind == Kind.MTH &&
-                (v.isFinal() || v.isEffectivelyFinal())) {
-                tree.skip = true;
+                elementToConstantMap.remove(tree.init);
+                elementToConstantMap.put(v, constant);
             }
         }
     }
 
+    Object getConstant(JCTree tree) {
+        return tree.type.constValue() != null ?
+                tree.type.constValue() :
+                elementToConstantMap.get(tree);
+    }
+
     @Override
     public void visitBinary(JCBinary tree) {
         super.visitBinary(tree);
-        tree = (JCBinary)result;
         if (tree.type.constValue() == null &&
-                tree.lhs.type.constValue() != null &&
-                tree.rhs.type.constValue() != null) {
-
-            Object constant = cfolder.fold2(tree.operator, tree.lhs.type.constValue(), tree.rhs.type.constValue());
+                getConstant(tree.lhs) != null &&
+                getConstant(tree.rhs) != null) {
+            Object constant = cfolder.fold2(tree.operator, getConstant(tree.lhs), getConstant(tree.rhs));
             if (constant != null) {
-                Type foldType = cfolder.foldType(tree.operator);
-                if (foldType != null) {
-                    tree.type = foldType.constType(constant);
-                }
+                elementToConstantMap.put(tree, constant);
             }
         }
     }
@@ -156,17 +174,13 @@
     @Override
     public void visitUnary(JCUnary tree) {
         super.visitUnary(tree);
-        tree = (JCUnary)result;
         Object constant;
         if (tree.type.constValue() == null &&
-                (constant = tree.arg.type.constValue()) != null &&
+                (constant = getConstant(tree.arg)) != null &&
                 constant instanceof Number) {
             constant = cfolder.fold1(tree.operator, constant);
             if (constant != null) {
-                Type foldType = cfolder.foldType(tree.operator);
-                if (foldType != null) {
-                    tree.type = foldType.constType(constant);
-                }
+                elementToConstantMap.put(tree, constant);
             }
         }
     }
@@ -174,36 +188,31 @@
     @Override
     public void visitConditional(JCConditional tree) {
         super.visitConditional(tree);
-        tree = (JCConditional)result;
-        Object condConstant = tree.cond.type.constValue();
-        Object truePartConstant = tree.truepart.type.constValue();
-        Object falsePartConstant = tree.falsepart.type.constValue();
+        Object condConstant = getConstant(tree.cond);
+        Object truePartConstant = getConstant(tree.truepart);
+        Object falsePartConstant = getConstant(tree.falsepart);
         if (tree.type.constValue() == null &&
             condConstant != null &&
             truePartConstant != null &&
             falsePartConstant != null &&
             !tree.type.hasTag(NONE)) {
             Object constant = ConstFold.isTrue(tree.cond.type.getTag(), condConstant) ? truePartConstant : falsePartConstant;
-            tree.type = tree.type.constType(constant);
+            elementToConstantMap.put(tree, constant);
         }
-        result = rewriteCondy(tree);
     }
 
     @Override
     public void visitTypeCast(JCTypeCast tree) {
         super.visitTypeCast(tree);
-        tree = (JCTypeCast)result;
-        if (tree.type.constValue() == null && tree.expr.type.constValue() != null) {
-            tree.type = tree.type.constType(tree.expr.type.constValue());
+        if (tree.type.constValue() == null && getConstant(tree.expr) != null) {
+            elementToConstantMap.put(tree, getConstant(tree.expr));
         }
-        result = rewriteCondy(tree);
     }
 
     @Override
     public void visitIdent(JCIdent tree) {
         super.visitIdent(tree);
         checkForSymbolConstant(tree);
-        result = rewriteCondy(tree);
     }
 
     void checkForSymbolConstant(JCTree tree) {
@@ -217,11 +226,12 @@
                 // the right code for us
                 tree.type = tree.type.constType(constant);
             } else {
+                constant = elementToConstantMap.get(v);
                 constant = constant != null ?
                         constant :
                         constables.foldTrackableField(tree, attrEnv);
                 if (constant != null) {
-                    tree.type = tree.type.constType(constant);
+                    elementToConstantMap.put(tree, constant);
                 }
             }
         }
@@ -230,15 +240,12 @@
     @Override
     public void visitSelect(JCFieldAccess tree) {
         super.visitSelect(tree);
-        tree = (JCFieldAccess)result;
         checkForSymbolConstant(tree);
-        result = rewriteCondy(tree);
     }
 
     @Override
     public void visitApply(JCMethodInvocation tree) {
         super.visitApply(tree);
-        tree = (JCMethodInvocation)result;
         Name methName = TreeInfo.name(tree.meth);
         boolean isConstructorCall = methName == names._this || methName == names._super;
         if (!isConstructorCall) {
@@ -249,6 +256,9 @@
                 log.error(tree.pos(), Errors.IntrinsicsLdcMustHaveConstantArg);
             }
             if (constant != null) {
+                if (!isLDC) {
+                    elementToConstantMap.put(tree, constant);
+                }
                 if (isLDC) {
                     Type newType;
                     // if condy
@@ -270,8 +280,6 @@
                     TreeInfo.setSymbol(tree.meth, ldcSymbol);
                     tree.meth.type = newMT;
                     tree.type = newMT.restype;
-                } else {
-                    tree.type = tree.type.constType(constant);
                 }
             } else if (constables.isIntrinsicsIndy(tree.meth)) {
                 List<Object> constants = constables.extractAllConstansOrNone(List.of(tree.args.head));
@@ -325,19 +333,50 @@
                     tree.type = mType.restype;
                 }
             }
-            result = rewriteCondy(tree);
         }
     }
 
-    JCTree rewriteCondy(JCTree tree) {
-        Object constant = tree.type.constValue();
-        Optional<DynamicFieldSymbol> opDynSym = constables.getDynamicFieldSymbol(tree, tree.type.constValue(), attrEnv);
-        if (opDynSym.isPresent()) {
-            DynamicFieldSymbol dynSym = opDynSym.get();
-            JCIdent ident = make.at(tree.pos()).Ident(dynSym);
-            ident.type = dynSym.type.constType(constant);
-            return ident;
+    ConstablesSetter constablesSetter = new ConstablesSetter();
+    class ConstablesSetter extends TreeTranslator {
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            super.visitVarDef(tree);
+            tree = (JCVariableDecl)result;
+            if (tree.init != null) {
+                VarSymbol v = tree.sym;
+                Object constant = elementToConstantMap.get(v);
+                if (constant != null) {
+                    v.setData(constant);
+                }
+            }
+            result = tree;
         }
-        return tree;
+
+        Set<JCTree.Tag> treesToCheck = EnumSet.of(
+                JCTree.Tag.SELECT,
+                JCTree.Tag.APPLY,
+                JCTree.Tag.IDENT,
+                JCTree.Tag.CONDEXPR,
+                JCTree.Tag.TYPECAST
+        );
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public <T extends JCTree> T translate(T tree) {
+            tree = super.translate(tree);
+            Object constant = elementToConstantMap.get(tree);
+            if (tree != null &&
+                    treesToCheck.contains(tree.getTag()) &&
+                    constant != null) {
+                Optional<DynamicFieldSymbol> opDynSym = constables.getDynamicFieldSymbol(tree, constant, attrEnv);
+                if (opDynSym.isPresent()) {
+                    DynamicFieldSymbol dynSym = opDynSym.get();
+                    JCTree ident = make.at(tree.pos()).Ident(dynSym);
+                    ident.type = dynSym.type.constType(constant);
+                    return (T)ident;
+                }
+            }
+            return tree;
+        }
     }
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Feb 01 21:29:03 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Feb 06 09:23:31 2018 -0500
@@ -154,6 +154,8 @@
     /** Sole signature generator */
     private final CWSignatureGenerator signatureGen;
 
+    private final Constables constables;
+
     /** The tags and constants used in compressed stackmap. */
     static final int SAME_FRAME_SIZE = 64;
     static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;
@@ -183,6 +185,7 @@
         types = Types.instance(context);
         fileManager = context.get(JavaFileManager.class);
         signatureGen = new CWSignatureGenerator(types);
+        constables = new Constables(context);
 
         verbose        = options.isSet(VERBOSE);
         genCrt         = options.isSet(XJCOV);
@@ -1151,7 +1154,7 @@
         databuf.appendChar(pool.put(typeSig(v.erasure(types))));
         int acountIdx = beginAttrs();
         int acount = 0;
-        if (v.getConstValue() != null && canMakeItToConstantValue(v.type)) {
+        if (v.getConstValue() != null && constables.canMakeItToConstantValue(v.type)) {
             int alenIdx = writeAttr(names.ConstantValue);
             databuf.appendChar(pool.put(v.getConstValue()));
             endAttr(alenIdx);
@@ -1161,10 +1164,6 @@
         endAttrs(acountIdx, acount);
     }
 
-    private boolean canMakeItToConstantValue(Type t) {
-        return t.isPrimitive() || t.tsym == syms.stringType.tsym;
-    }
-
     /** Write method symbol, entering all references into constant pool.
      */
     void writeMethod(MethodSymbol m) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Feb 01 21:29:03 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Feb 06 09:23:31 2018 -0500
@@ -77,6 +77,7 @@
     private final Lower lower;
     private final Annotate annotate;
     private final StringConcat concat;
+    private final Constables constables;
 
     /** Format of stackmap tables to be generated. */
     private final Code.StackMapFormat stackMap;
@@ -113,6 +114,7 @@
         target = Target.instance(context);
         types = Types.instance(context);
         concat = StringConcat.instance(context);
+        constables = new Constables(context);
 
         methodType = new MethodType(null, null, null, syms.methodClass);
         accessDollar = names.
@@ -1021,8 +1023,8 @@
         if (tree.init != null) {
             checkStringConstant(tree.init.pos(), v.getConstValue());
             if (v.getConstValue() == null ||
-                    (!doConstantFold && varDebugInfo) ||
-                    (doConstantFold && !tree.skip)) {
+                    varDebugInfo ||
+                    (doConstantFold && !constables.skipCodeGeneration(tree))) {
                 Assert.check(letExprDepth != 0 || code.state.stacksize == 0);
                 genExpr(tree.init, v.erasure(types)).load();
                 items.makeLocalItem(v).store();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Feb 01 21:29:03 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Feb 06 09:23:31 2018 -0500
@@ -922,8 +922,6 @@
         public VarSymbol sym;
         /** explicit start pos */
         public int startPos = Position.NOPOS;
-        /** skip the generation of this variable declaration */
-        public boolean skip = false;
 
         protected JCVariableDecl(JCModifiers mods,
                          Name name,
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Thu Feb 01 21:29:03 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Tue Feb 06 09:23:31 2018 -0500
@@ -34,6 +34,7 @@
 import java.util.Optional;
 
 import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
@@ -50,6 +51,7 @@
 import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.ConstablesVisitor;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.comp.Resolve.*;
@@ -61,6 +63,7 @@
 import com.sun.tools.javac.tree.JCTree.JCExpression;
 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
@@ -85,6 +88,7 @@
         syms = Symtab.instance(context);
         rs = Resolve.instance(context);
         log = Log.instance(context);
+        constablesVisitor = ConstablesVisitor.instance(context);
         try {
             methodHandleRefClass = Class.forName("java.lang.sym.MethodHandleRef", false, null);
             methodTypeRefClass = Class.forName("java.lang.sym.MethodTypeRef", false, null);
@@ -112,6 +116,7 @@
     private final Resolve rs;
     private final Log log;
     private ModuleSymbol currentModule;
+    private final ConstablesVisitor constablesVisitor;
 
     /** The unread portion of the currently read type is
      *  signature[sigp..siglimit-1].
@@ -432,6 +437,16 @@
         return t.isPrimitive() || t.tsym == syms.stringType.tsym;
     }
 
+    public boolean skipCodeGeneration(JCVariableDecl tree) {
+        if (tree.init != null) {
+            VarSymbol v = tree.sym;
+            return (v.isLocal() &&
+                v.owner.kind == Kind.MTH &&
+                (v.isFinal() || v.isEffectivelyFinal()));
+        }
+        return false;
+    }
+
     boolean canHaveInterfaceOwner(int refKind) {
         switch (refKind) {
             case ClassFile.REF_invokeStatic:
@@ -724,7 +739,14 @@
             if (argConstant != null) {
                 constantArgumentValues.add(argConstant);
             } else {
-                return List.nil();
+                argConstant = constablesVisitor.elementToConstantMap.get(arg) != null ?
+                        constablesVisitor.elementToConstantMap.get(arg) :
+                        constablesVisitor.elementToConstantMap.get(TreeInfo.symbol(arg));
+                if (argConstant != null) {
+                    constantArgumentValues.add(argConstant);
+                } else {
+                    return List.nil();
+                }
             }
         }
         return constantArgumentValues.toList();
@@ -742,7 +764,7 @@
                 JCTree qualifierTree = (tree.meth.hasTag(SELECT))
                     ? ((JCFieldAccess) tree.meth).selected
                     : null;
-                Object instance = qualifierTree.type.constValue(); //constablesVisitor.elementToConstantMap.get(qualifierTree);
+                Object instance = constablesVisitor.elementToConstantMap.get(qualifierTree);
                 className = msym.owner.type.tsym.flatName().toString();
                 methodName = msym.name;
                 Class<?> constablesClass = Class.forName(className, false, null);
--- a/test/langtools/tools/javac/specialConstantFolding/IndyCrashTest.out	Thu Feb 01 21:29:03 2018 -0500
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyCrashTest.out	Tue Feb 06 09:23:31 2018 -0500
@@ -1,6 +1,4 @@
-IndyCrashTest.java:30:33: compiler.warn.member.not.found.at.class: foo, class, IndyCrashTest.IntrinsicTestHelper
-IndyCrashTest.java:31:58: compiler.warn.member.not.found.at.class: foo, class, IndyCrashTest.IntrinsicTestHelper
 IndyCrashTest.java:31:57: compiler.warn.member.not.found.at.class: foo, class, IndyCrashTest.IntrinsicTestHelper
 IndyCrashTest.java:31:58: compiler.err.method.handle.not.suitable.indy: ()java.lang.invoke.CallSite
 1 error
-3 warnings
+1 warning