changeset 2768:dca7f60e618d

8064857: javac generates LVT entry with length 0 for local variable Reviewed-by: mcimadamore, jjg
author vromero
date Tue, 20 Jan 2015 14:14:33 -0800
parents 385488f3737c
children 584566b6d5e4
files src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/share/classes/com/sun/tools/javac/jvm/Code.java src/share/classes/com/sun/tools/javac/jvm/Gen.java src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java test/tools/javac/flow/LVTHarness.java test/tools/javac/flow/tests/TestCaseFor.java test/tools/javac/flow/tests/TestCaseForEach.java test/tools/javac/flow/tests/TestCaseIfElse.java test/tools/javac/flow/tests/TestCaseSwitch.java test/tools/javac/flow/tests/TestCaseTry.java test/tools/javac/flow/tests/TestCaseWhile.java
diffstat 11 files changed, 65 insertions(+), 536 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Jan 20 14:14:33 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1186,7 +1186,7 @@
                     Assert.check(r.start_pc >= 0
                             && r.start_pc <= code.cp);
                     databuf.appendChar(r.start_pc);
-                    Assert.check(r.length >= 0
+                    Assert.check(r.length > 0
                             && (r.start_pc + r.length) <= code.cp);
                     databuf.appendChar(r.length);
                     VarSymbol sym = var.sym;
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Tue Jan 20 14:14:33 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -182,8 +182,6 @@
 
     final MethodSymbol meth;
 
-    final LVTRanges lvtRanges;
-
     /** Construct a code object, given the settings of the fatcode,
      *  debugging info switches and the CharacterRangeTable.
      */
@@ -196,8 +194,7 @@
                 CRTable crt,
                 Symtab syms,
                 Types types,
-                Pool pool,
-                LVTRanges lvtRanges) {
+                Pool pool) {
         this.meth = meth;
         this.fatcode = fatcode;
         this.lineMap = lineMap;
@@ -219,7 +216,6 @@
         state = new State();
         lvar = new LocalVar[20];
         this.pool = pool;
-        this.lvtRanges = lvtRanges;
     }
 
 
@@ -1193,7 +1189,9 @@
     public int entryPoint(State state) {
         int pc = curCP();
         alive = true;
-        this.state = state.dup();
+        State newState = state.dup();
+        setDefined(newState.defined);
+        this.state = newState;
         Assert.check(state.stacksize <= max_stack);
         if (debugCode) System.err.println("entry point " + state);
         pendingStackMap = needStackMap;
@@ -1206,7 +1204,9 @@
     public int entryPoint(State state, Type pushed) {
         int pc = curCP();
         alive = true;
-        this.state = state.dup();
+        State newState = state.dup();
+        setDefined(newState.defined);
+        this.state = newState;
         Assert.check(state.stacksize <= max_stack);
         this.state.push(pushed);
         if (debugCode) System.err.println("entry point " + state);
@@ -2008,27 +2008,6 @@
         state.defined.excl(adr);
     }
 
-
-    public void closeAliveRanges(JCTree tree) {
-        closeAliveRanges(tree, cp);
-    }
-
-    public void closeAliveRanges(JCTree tree, int closingCP) {
-        List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
-        for (LocalVar localVar: lvar) {
-            for (VarSymbol aliveLocal : locals) {
-                if (localVar != null) {
-                    if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
-                        char length = (char)(closingCP - localVar.lastRange().start_pc);
-                        if (length < Character.MAX_VALUE) {
-                            localVar.closeRange(length);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
     void adjustAliveRanges(int oldCP, int delta) {
         for (LocalVar localVar: lvar) {
             if (localVar != null) {
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Jan 20 14:14:33 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -101,10 +101,6 @@
      */
     private Pool pool;
 
-    /** LVTRanges info.
-     */
-    private LVTRanges lvtRanges;
-
     private final boolean typeAnnoAsserts;
 
     protected Gen(Context context) {
@@ -137,9 +133,6 @@
             options.isUnset(G_CUSTOM)
             ? options.isSet(G)
             : options.isSet(G_CUSTOM, "vars");
-        if (varDebugInfo) {
-            lvtRanges = LVTRanges.instance(context);
-        }
         genCrt = options.isSet(XJCOV);
         debugCode = options.isSet("debugcode");
         allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
@@ -1103,8 +1096,7 @@
                                                : null,
                                         syms,
                                         types,
-                                        pool,
-                                        varDebugInfo ? lvtRanges : null);
+                                        pool);
             items = new Items(pool, code, syms, types);
             if (code.debugCode) {
                 System.err.println(meth + " for body " + tree);
@@ -1207,30 +1199,14 @@
                 Chain loopDone = c.jumpFalse();
                 code.resolve(c.trueJumps);
                 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
-                if (varDebugInfo) {
-                    checkLoopLocalVarRangeEnding(loop, body,
-                            LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
-                }
                 code.resolve(loopEnv.info.cont);
                 genStats(step, loopEnv);
-                if (varDebugInfo) {
-                    checkLoopLocalVarRangeEnding(loop, body,
-                            LoopLocalVarRangeEndingPoint.AFTER_STEPS);
-                }
                 code.resolve(code.branch(goto_), startpc);
                 code.resolve(loopDone);
             } else {
                 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
-                if (varDebugInfo) {
-                    checkLoopLocalVarRangeEnding(loop, body,
-                            LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
-                }
                 code.resolve(loopEnv.info.cont);
                 genStats(step, loopEnv);
-                if (varDebugInfo) {
-                    checkLoopLocalVarRangeEnding(loop, body,
-                            LoopLocalVarRangeEndingPoint.AFTER_STEPS);
-                }
                 CondItem c;
                 if (cond != null) {
                     code.statBegin(cond.pos);
@@ -1247,44 +1223,6 @@
             }
         }
 
-        private enum LoopLocalVarRangeEndingPoint {
-            BEFORE_STEPS,
-            AFTER_STEPS,
-        }
-
-        /**
-         *  Checks whether we have reached an alive range ending point for local
-         *  variables after a loop.
-         *
-         *  Local variables alive range ending point for loops varies depending
-         *  on the loop type. The range can be closed before or after the code
-         *  for the steps sentences has been generated.
-         *
-         *  - While loops has no steps so in that case the range is closed just
-         *  after the body of the loop.
-         *
-         *  - For-like loops may have steps so as long as the steps sentences
-         *  can possibly contain non-synthetic local variables, the alive range
-         *  for local variables must be closed after the steps in this case.
-        */
-        private void checkLoopLocalVarRangeEnding(JCTree loop, JCTree body,
-                LoopLocalVarRangeEndingPoint endingPoint) {
-            if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
-                switch (endingPoint) {
-                    case BEFORE_STEPS:
-                        if (!loop.hasTag(FORLOOP)) {
-                            code.closeAliveRanges(body);
-                        }
-                        break;
-                    case AFTER_STEPS:
-                        if (loop.hasTag(FORLOOP)) {
-                            code.closeAliveRanges(body);
-                        }
-                        break;
-                }
-            }
-        }
-
     public void visitForeachLoop(JCEnhancedForLoop tree) {
         throw new AssertionError(); // should have been removed by Lower.
     }
@@ -1398,9 +1336,6 @@
 
                 // Generate code for the statements in this case.
                 genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
-                if (varDebugInfo && lvtRanges.containsKey(code.meth, c.stats.last())) {
-                    code.closeAliveRanges(c.stats.last());
-                }
             }
 
             // Resolve all breaks.
@@ -1557,9 +1492,6 @@
             genFinalizer(env);
             code.statBegin(TreeInfo.endPos(env.tree));
             Chain exitChain = code.branch(goto_);
-            if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
-                code.closeAliveRanges(body);
-            }
             endFinalizerGap(env);
             if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) {
                 // start off with exception on stack
@@ -1815,17 +1747,11 @@
             code.resolve(c.trueJumps);
             genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
             thenExit = code.branch(goto_);
-            if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) {
-                code.closeAliveRanges(tree.thenpart, code.cp);
-            }
         }
         if (elseChain != null) {
             code.resolve(elseChain);
             if (tree.elsepart != null) {
                 genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET);
-                if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.elsepart)) {
-                    code.closeAliveRanges(tree.elsepart);
-                }
             }
         }
         code.resolve(thenExit);
@@ -2514,16 +2440,6 @@
             localEnv.toplevel = env.toplevel;
             localEnv.enclClass = cdef;
 
-            /*  We must not analyze synthetic methods
-             */
-            if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
-                try {
-                    new LVTAssignAnalyzer().analyzeTree(localEnv);
-                } catch (Throwable e) {
-                    throw e;
-                }
-            }
-
             for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) {
                 genDef(l.head, localEnv);
             }
@@ -2609,282 +2525,4 @@
         }
     }
 
-    class LVTAssignAnalyzer
-        extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
-
-        final LVTBits lvtInits;
-
-        /*  This class is anchored to a context dependent tree. The tree can
-         *  vary inside the same instruction for example in the switch instruction
-         *  the same FlowBits instance can be anchored to the whole tree, or
-         *  to a given case. The aim is to always anchor the bits to the tree
-         *  capable of closing a DA range.
-         */
-        class LVTBits extends Bits {
-
-            JCTree currentTree;
-            private int[] oldBits = null;
-            BitsState stateBeforeOp;
-
-            @Override
-            public void clear() {
-                generalOp(null, -1, BitsOpKind.CLEAR);
-            }
-
-            @Override
-            protected void internalReset() {
-                super.internalReset();
-                oldBits = null;
-            }
-
-            @Override
-            public Bits assign(Bits someBits) {
-                // bits can be null
-                oldBits = bits;
-                stateBeforeOp = currentState;
-                super.assign(someBits);
-                changed();
-                return this;
-            }
-
-            @Override
-            public void excludeFrom(int start) {
-                generalOp(null, start, BitsOpKind.EXCL_RANGE);
-            }
-
-            @Override
-            public void excl(int x) {
-                Assert.check(x >= 0);
-                generalOp(null, x, BitsOpKind.EXCL_BIT);
-            }
-
-            @Override
-            public Bits andSet(Bits xs) {
-               return generalOp(xs, -1, BitsOpKind.AND_SET);
-            }
-
-            @Override
-            public Bits orSet(Bits xs) {
-                return generalOp(xs, -1, BitsOpKind.OR_SET);
-            }
-
-            @Override
-            public Bits diffSet(Bits xs) {
-                return generalOp(xs, -1, BitsOpKind.DIFF_SET);
-            }
-
-            @Override
-            public Bits xorSet(Bits xs) {
-                return generalOp(xs, -1, BitsOpKind.XOR_SET);
-            }
-
-            private Bits generalOp(Bits xs, int i, BitsOpKind opKind) {
-                Assert.check(currentState != BitsState.UNKNOWN);
-                oldBits = dupBits();
-                stateBeforeOp = currentState;
-                switch (opKind) {
-                    case AND_SET:
-                        super.andSet(xs);
-                        break;
-                    case OR_SET:
-                        super.orSet(xs);
-                        break;
-                    case XOR_SET:
-                        super.xorSet(xs);
-                        break;
-                    case DIFF_SET:
-                        super.diffSet(xs);
-                        break;
-                    case CLEAR:
-                        super.clear();
-                        break;
-                    case EXCL_BIT:
-                        super.excl(i);
-                        break;
-                    case EXCL_RANGE:
-                        super.excludeFrom(i);
-                        break;
-                }
-                changed();
-                return this;
-            }
-
-            /*  The tree we need to anchor the bits instance to.
-             */
-            LVTBits at(JCTree tree) {
-                this.currentTree = tree;
-                return this;
-            }
-
-            /*  If the instance should be changed but the tree is not a closing
-             *  tree then a reset is needed or the former tree can mistakingly be
-             *  used.
-             */
-            LVTBits resetTree() {
-                this.currentTree = null;
-                return this;
-            }
-
-            /** This method will be called after any operation that causes a change to
-             *  the bits. Subclasses can thus override it in order to extract information
-             *  from the changes produced to the bits by the given operation.
-             */
-            public void changed() {
-                if (currentTree != null &&
-                        stateBeforeOp != BitsState.UNKNOWN &&
-                        trackTree(currentTree)) {
-                    List<VarSymbol> locals = lvtRanges
-                            .getVars(currentMethod, currentTree);
-                    locals = locals != null ?
-                            locals : List.<VarSymbol>nil();
-                    for (JCVariableDecl vardecl : vardecls) {
-                        //once the first is null, the rest will be so.
-                        if (vardecl == null) {
-                            break;
-                        }
-                        if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) {
-                            locals = locals.prepend(vardecl.sym);
-                        }
-                    }
-                    if (!locals.isEmpty()) {
-                        lvtRanges.setEntry(currentMethod,
-                                currentTree, locals);
-                    }
-                }
-            }
-
-            boolean bitChanged(int x) {
-                boolean isMemberOfBits = isMember(x);
-                int[] tmp = bits;
-                bits = oldBits;
-                boolean isMemberOfOldBits = isMember(x);
-                bits = tmp;
-                return (!isMemberOfBits && isMemberOfOldBits);
-            }
-
-            boolean trackVar(VarSymbol var) {
-                return (var.owner.kind == MTH &&
-                        (var.flags() & PARAMETER) == 0 &&
-                        trackable(var));
-            }
-
-            boolean trackTree(JCTree tree) {
-                switch (tree.getTag()) {
-                    // of course a method closes the alive range of a local variable.
-                    case METHODDEF:
-                    // for while loops we want only the body
-                    case WHILELOOP:
-                        return false;
-                }
-                return true;
-            }
-
-        }
-
-        public class LVTAssignPendingExit extends
-                                    Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit {
-
-            LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
-                super(tree, inits, uninits);
-            }
-
-            @Override
-            public void resolveJump(JCTree tree) {
-                lvtInits.at(tree);
-                super.resolveJump(tree);
-            }
-        }
-
-        private LVTAssignAnalyzer() {
-            flow.super();
-            lvtInits = new LVTBits();
-            inits = lvtInits;
-        }
-
-        @Override
-        protected void markDead(JCTree tree) {
-            lvtInits.at(tree).inclRange(returnadr, nextadr);
-            super.markDead(tree);
-        }
-
-        @Override
-        protected void merge(JCTree tree) {
-            lvtInits.at(tree);
-            super.merge(tree);
-        }
-
-        boolean isSyntheticOrMandated(Symbol sym) {
-            return (sym.flags() & (SYNTHETIC | MANDATED)) != 0;
-        }
-
-        @Override
-        protected boolean trackable(VarSymbol sym) {
-            if (isSyntheticOrMandated(sym)) {
-                //fast check to avoid tracking synthetic or mandated variables
-                return false;
-            }
-            return super.trackable(sym);
-        }
-
-        @Override
-        protected void initParam(JCVariableDecl def) {
-            if (!isSyntheticOrMandated(def.sym)) {
-                super.initParam(def);
-            }
-        }
-
-        @Override
-        protected void assignToInits(JCTree tree, Bits bits) {
-            lvtInits.at(tree);
-            lvtInits.assign(bits);
-        }
-
-        @Override
-        protected void andSetInits(JCTree tree, Bits bits) {
-            lvtInits.at(tree);
-            lvtInits.andSet(bits);
-        }
-
-        @Override
-        protected void orSetInits(JCTree tree, Bits bits) {
-            lvtInits.at(tree);
-            lvtInits.orSet(bits);
-        }
-
-        @Override
-        protected void exclVarFromInits(JCTree tree, int adr) {
-            lvtInits.at(tree);
-            lvtInits.excl(adr);
-        }
-
-        @Override
-        protected LVTAssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
-            return new LVTAssignPendingExit(tree, inits, uninits);
-        }
-
-        MethodSymbol currentMethod;
-
-        @Override
-        public void visitMethodDef(JCMethodDecl tree) {
-            if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0
-                    && (tree.sym.flags() & LAMBDA_METHOD) == 0) {
-                return;
-            }
-            if (tree.name.equals(names.clinit)) {
-                return;
-            }
-            boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
-            if (enumClass &&
-                    (tree.name.equals(names.valueOf) ||
-                    tree.name.equals(names.values) ||
-                    tree.name.equals(names.init))) {
-                return;
-            }
-            currentMethod = tree.sym;
-
-            super.visitMethodDef(tree);
-        }
-
-    }
-
 }
--- a/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java	Tue Jan 13 12:41:16 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.javac.jvm;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.WeakHashMap;
-
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-
-/** This class contains a one to many relation between a tree and a set of variables.
- *  The relation implies that the given tree closes the DA (definite assignment)
- *  range for the set of variables.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
- */
-public class LVTRanges {
-    /** The context key for the LVT ranges. */
-    protected static final Context.Key<LVTRanges> lvtRangesKey = new Context.Key<>();
-
-    /** Get the LVTRanges instance for this context. */
-    public static LVTRanges instance(Context context) {
-        LVTRanges instance = context.get(lvtRangesKey);
-        if (instance == null) {
-            instance = new LVTRanges(context);
-        }
-        return instance;
-    }
-
-    private static final long serialVersionUID = 1812267524140424433L;
-
-    protected Context context;
-
-    protected Map<MethodSymbol, Map<JCTree, List<VarSymbol>>>
-            aliveRangeClosingTrees = new WeakHashMap<>();
-
-    public LVTRanges(Context context) {
-        this.context = context;
-        context.put(lvtRangesKey, this);
-    }
-
-    public List<VarSymbol> getVars(MethodSymbol method, JCTree tree) {
-        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
-        return (varMap != null) ? varMap.get(tree) : null;
-    }
-
-    public boolean containsKey(MethodSymbol method, JCTree tree) {
-        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
-        if (varMap == null) {
-            return false;
-        }
-        return varMap.containsKey(tree);
-    }
-
-    public void setEntry(MethodSymbol method, JCTree tree, List<VarSymbol> vars) {
-        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
-        if (varMap != null) {
-            varMap.put(tree, vars);
-        } else {
-            varMap = new WeakHashMap<>();
-            varMap.put(tree, vars);
-            aliveRangeClosingTrees.put(method, varMap);
-        }
-    }
-
-    public List<VarSymbol> removeEntry(MethodSymbol method, JCTree tree) {
-        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
-        if (varMap != null) {
-            List<VarSymbol> result = varMap.remove(tree);
-            if (varMap.isEmpty()) {
-                aliveRangeClosingTrees.remove(method);
-            }
-            return result;
-        }
-        return null;
-    }
-
-    /* This method should be used for debugging LVT related issues.
-     */
-    @Override
-    public String toString() {
-        String result = "";
-        for (Entry<MethodSymbol, Map<JCTree, List<VarSymbol>>> mainEntry: aliveRangeClosingTrees.entrySet()) {
-            result += "Method: \n" + mainEntry.getKey().flatName() + "\n";
-            int i = 1;
-            for (Entry<JCTree, List<VarSymbol>> treeEntry: mainEntry.getValue().entrySet()) {
-                result += "    Tree " + i + ": \n" + treeEntry.getKey().toString() + "\n";
-                result += "        Variables closed:\n";
-                for (VarSymbol var: treeEntry.getValue()) {
-                    result += "            " + var.toString();
-                }
-                result += "\n";
-                i++;
-            }
-        }
-        return result;
-    }
-
-}
--- a/test/tools/javac/flow/LVTHarness.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/LVTHarness.java	Tue Jan 20 14:14:33 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7047734 8027660 8037937 8047719 8058708
+ * @bug 7047734 8027660 8037937 8047719 8058708 8064857
  * @summary The LVT is not generated correctly during some try/catch scenarios
  *          javac crash while creating LVT entry for a local variable defined in
  *          an inner block
@@ -144,7 +144,7 @@
     }
 
     void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges)
-            throws InvalidIndex, UnexpectedEntry {
+            throws InvalidIndex, UnexpectedEntry, ConstantPoolException {
         Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);
         LocalVariableTable_attribute lvt =
             (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable));
@@ -166,7 +166,7 @@
         }
 
         if (i < infoFromRanges.size()) {
-            error(infoFromLVT, infoFromRanges);
+            error(infoFromLVT, infoFromRanges, method.getName(constantPool).toString());
         }
     }
 
@@ -202,9 +202,10 @@
         return sb.toString();
     }
 
-    protected void error(List<String> infoFromLVT, List<String> infoFromRanges) {
+    protected void error(List<String> infoFromLVT, List<String> infoFromRanges, String methodName) {
         nerrors++;
         System.err.printf("Error occurred while checking file: %s\n", jfo.getName());
+        System.err.printf("at method: %s\n", methodName);
         System.err.println("The range info from the annotations is");
         printStringListToErrOutput(infoFromRanges);
         System.err.println();
--- a/test/tools/javac/flow/tests/TestCaseFor.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/tests/TestCaseFor.java	Tue Jan 20 14:14:33 2015 -0800
@@ -2,7 +2,7 @@
 
 public class TestCaseFor {
 
-    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=11)
     @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
     void m1(String[] args) {
         Object o;
@@ -13,7 +13,7 @@
         o = "";
     }
 
-    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=11)
     @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
     void m2(String[] args) {
         Object o;
--- a/test/tools/javac/flow/tests/TestCaseForEach.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/tests/TestCaseForEach.java	Tue Jan 20 14:14:33 2015 -0800
@@ -2,7 +2,7 @@
 
 public class TestCaseForEach {
 
-    @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=8)
+    @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=11)
     @AliveRange(varName="o", bytecodeStart=39, bytecodeLength=1)
     void m(String[] args) {
         Object o;
--- a/test/tools/javac/flow/tests/TestCaseIfElse.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/tests/TestCaseIfElse.java	Tue Jan 20 14:14:33 2015 -0800
@@ -60,4 +60,19 @@
         }
         return null;
     }
+
+    @AliveRange(varName="i", bytecodeStart=6, bytecodeLength=2)
+    int m4(boolean flag) {
+        int i;
+        label:
+        {
+            if (flag) {
+                i = 1;
+            } else {
+                break label;
+            }
+            return i;
+        }
+        return -1;
+    }
 }
--- a/test/tools/javac/flow/tests/TestCaseSwitch.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/tests/TestCaseSwitch.java	Tue Jan 20 14:14:33 2015 -0800
@@ -81,4 +81,26 @@
         o = "finish";
     }
 
+    @AliveRange(varName="oCache", bytecodeStart=30, bytecodeLength=6)
+    @AliveRange(varName="cache", bytecodeStart=41, bytecodeLength=3)
+    @AliveRange(varName="cache", bytecodeStart=54, bytecodeLength=2)
+    @AliveRange(varName="service", bytecodeStart=39, bytecodeLength=5)
+    Object m4(int i) {
+        Object cache;
+        switch (i) {
+            case 0:
+                Object oCache = null;
+                if (oCache != null) {
+                    return oCache;
+                }
+            case 1:
+                Object service = null;
+                cache = null;
+                break;
+            default:
+                throw new AssertionError("");
+            }
+        return cache;
+    }
+
 }
--- a/test/tools/javac/flow/tests/TestCaseTry.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/tests/TestCaseTry.java	Tue Jan 20 14:14:33 2015 -0800
@@ -17,7 +17,8 @@
     }
 
     @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
-    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=23)
+    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=8)
+    @AliveRange(varName="o", bytecodeStart=35, bytecodeLength=11)
     void m1() {
         Object o;
         try {
@@ -33,7 +34,8 @@
     }
 
     @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
-    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=31)
+    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=16)
+    @AliveRange(varName="o", bytecodeStart=43, bytecodeLength=11)
     void m2() {
         Object o;
         try {
@@ -51,7 +53,8 @@
     }
 
     @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38)
-    @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=8)
+    @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=3)
+    @AliveRange(varName="o", bytecodeStart=110, bytecodeLength=1)
     void m3() {
         Object o;
         try (BufferedReader br =
--- a/test/tools/javac/flow/tests/TestCaseWhile.java	Tue Jan 13 12:41:16 2015 -0800
+++ b/test/tools/javac/flow/tests/TestCaseWhile.java	Tue Jan 20 14:14:33 2015 -0800
@@ -2,7 +2,7 @@
 
 public class TestCaseWhile {
 
-    @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5)
+    @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=8)
     @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=1)
     void m(String[] args) {
         Object o;