8064857: javac generates LVT entry with length 0 for local variable

Tue, 20 Jan 2015 14:14:33 -0800

author
vromero
date
Tue, 20 Jan 2015 14:14:33 -0800
changeset 2709
dca7f60e618d
parent 2708
385488f3737c
child 2710
584566b6d5e4

8064857: javac generates LVT entry with length 0 for local variable
Reviewed-by: mcimadamore, jjg

src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Code.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/Gen.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/LVTHarness.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/tests/TestCaseFor.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/tests/TestCaseForEach.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/tests/TestCaseIfElse.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/tests/TestCaseSwitch.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/tests/TestCaseTry.java file | annotate | diff | comparison | revisions
test/tools/javac/flow/tests/TestCaseWhile.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Jan 13 12:41:16 2015 -0800
     1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Jan 20 14:14:33 2015 -0800
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -1186,7 +1186,7 @@
    1.11                      Assert.check(r.start_pc >= 0
    1.12                              && r.start_pc <= code.cp);
    1.13                      databuf.appendChar(r.start_pc);
    1.14 -                    Assert.check(r.length >= 0
    1.15 +                    Assert.check(r.length > 0
    1.16                              && (r.start_pc + r.length) <= code.cp);
    1.17                      databuf.appendChar(r.length);
    1.18                      VarSymbol sym = var.sym;
     2.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Tue Jan 13 12:41:16 2015 -0800
     2.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Tue Jan 20 14:14:33 2015 -0800
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -182,8 +182,6 @@
    2.11  
    2.12      final MethodSymbol meth;
    2.13  
    2.14 -    final LVTRanges lvtRanges;
    2.15 -
    2.16      /** Construct a code object, given the settings of the fatcode,
    2.17       *  debugging info switches and the CharacterRangeTable.
    2.18       */
    2.19 @@ -196,8 +194,7 @@
    2.20                  CRTable crt,
    2.21                  Symtab syms,
    2.22                  Types types,
    2.23 -                Pool pool,
    2.24 -                LVTRanges lvtRanges) {
    2.25 +                Pool pool) {
    2.26          this.meth = meth;
    2.27          this.fatcode = fatcode;
    2.28          this.lineMap = lineMap;
    2.29 @@ -219,7 +216,6 @@
    2.30          state = new State();
    2.31          lvar = new LocalVar[20];
    2.32          this.pool = pool;
    2.33 -        this.lvtRanges = lvtRanges;
    2.34      }
    2.35  
    2.36  
    2.37 @@ -1193,7 +1189,9 @@
    2.38      public int entryPoint(State state) {
    2.39          int pc = curCP();
    2.40          alive = true;
    2.41 -        this.state = state.dup();
    2.42 +        State newState = state.dup();
    2.43 +        setDefined(newState.defined);
    2.44 +        this.state = newState;
    2.45          Assert.check(state.stacksize <= max_stack);
    2.46          if (debugCode) System.err.println("entry point " + state);
    2.47          pendingStackMap = needStackMap;
    2.48 @@ -1206,7 +1204,9 @@
    2.49      public int entryPoint(State state, Type pushed) {
    2.50          int pc = curCP();
    2.51          alive = true;
    2.52 -        this.state = state.dup();
    2.53 +        State newState = state.dup();
    2.54 +        setDefined(newState.defined);
    2.55 +        this.state = newState;
    2.56          Assert.check(state.stacksize <= max_stack);
    2.57          this.state.push(pushed);
    2.58          if (debugCode) System.err.println("entry point " + state);
    2.59 @@ -2008,27 +2008,6 @@
    2.60          state.defined.excl(adr);
    2.61      }
    2.62  
    2.63 -
    2.64 -    public void closeAliveRanges(JCTree tree) {
    2.65 -        closeAliveRanges(tree, cp);
    2.66 -    }
    2.67 -
    2.68 -    public void closeAliveRanges(JCTree tree, int closingCP) {
    2.69 -        List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
    2.70 -        for (LocalVar localVar: lvar) {
    2.71 -            for (VarSymbol aliveLocal : locals) {
    2.72 -                if (localVar != null) {
    2.73 -                    if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
    2.74 -                        char length = (char)(closingCP - localVar.lastRange().start_pc);
    2.75 -                        if (length < Character.MAX_VALUE) {
    2.76 -                            localVar.closeRange(length);
    2.77 -                        }
    2.78 -                    }
    2.79 -                }
    2.80 -            }
    2.81 -        }
    2.82 -    }
    2.83 -
    2.84      void adjustAliveRanges(int oldCP, int delta) {
    2.85          for (LocalVar localVar: lvar) {
    2.86              if (localVar != null) {
     3.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Jan 13 12:41:16 2015 -0800
     3.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Jan 20 14:14:33 2015 -0800
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -101,10 +101,6 @@
    3.11       */
    3.12      private Pool pool;
    3.13  
    3.14 -    /** LVTRanges info.
    3.15 -     */
    3.16 -    private LVTRanges lvtRanges;
    3.17 -
    3.18      private final boolean typeAnnoAsserts;
    3.19  
    3.20      protected Gen(Context context) {
    3.21 @@ -137,9 +133,6 @@
    3.22              options.isUnset(G_CUSTOM)
    3.23              ? options.isSet(G)
    3.24              : options.isSet(G_CUSTOM, "vars");
    3.25 -        if (varDebugInfo) {
    3.26 -            lvtRanges = LVTRanges.instance(context);
    3.27 -        }
    3.28          genCrt = options.isSet(XJCOV);
    3.29          debugCode = options.isSet("debugcode");
    3.30          allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
    3.31 @@ -1103,8 +1096,7 @@
    3.32                                                 : null,
    3.33                                          syms,
    3.34                                          types,
    3.35 -                                        pool,
    3.36 -                                        varDebugInfo ? lvtRanges : null);
    3.37 +                                        pool);
    3.38              items = new Items(pool, code, syms, types);
    3.39              if (code.debugCode) {
    3.40                  System.err.println(meth + " for body " + tree);
    3.41 @@ -1207,30 +1199,14 @@
    3.42                  Chain loopDone = c.jumpFalse();
    3.43                  code.resolve(c.trueJumps);
    3.44                  genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
    3.45 -                if (varDebugInfo) {
    3.46 -                    checkLoopLocalVarRangeEnding(loop, body,
    3.47 -                            LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
    3.48 -                }
    3.49                  code.resolve(loopEnv.info.cont);
    3.50                  genStats(step, loopEnv);
    3.51 -                if (varDebugInfo) {
    3.52 -                    checkLoopLocalVarRangeEnding(loop, body,
    3.53 -                            LoopLocalVarRangeEndingPoint.AFTER_STEPS);
    3.54 -                }
    3.55                  code.resolve(code.branch(goto_), startpc);
    3.56                  code.resolve(loopDone);
    3.57              } else {
    3.58                  genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
    3.59 -                if (varDebugInfo) {
    3.60 -                    checkLoopLocalVarRangeEnding(loop, body,
    3.61 -                            LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
    3.62 -                }
    3.63                  code.resolve(loopEnv.info.cont);
    3.64                  genStats(step, loopEnv);
    3.65 -                if (varDebugInfo) {
    3.66 -                    checkLoopLocalVarRangeEnding(loop, body,
    3.67 -                            LoopLocalVarRangeEndingPoint.AFTER_STEPS);
    3.68 -                }
    3.69                  CondItem c;
    3.70                  if (cond != null) {
    3.71                      code.statBegin(cond.pos);
    3.72 @@ -1247,44 +1223,6 @@
    3.73              }
    3.74          }
    3.75  
    3.76 -        private enum LoopLocalVarRangeEndingPoint {
    3.77 -            BEFORE_STEPS,
    3.78 -            AFTER_STEPS,
    3.79 -        }
    3.80 -
    3.81 -        /**
    3.82 -         *  Checks whether we have reached an alive range ending point for local
    3.83 -         *  variables after a loop.
    3.84 -         *
    3.85 -         *  Local variables alive range ending point for loops varies depending
    3.86 -         *  on the loop type. The range can be closed before or after the code
    3.87 -         *  for the steps sentences has been generated.
    3.88 -         *
    3.89 -         *  - While loops has no steps so in that case the range is closed just
    3.90 -         *  after the body of the loop.
    3.91 -         *
    3.92 -         *  - For-like loops may have steps so as long as the steps sentences
    3.93 -         *  can possibly contain non-synthetic local variables, the alive range
    3.94 -         *  for local variables must be closed after the steps in this case.
    3.95 -        */
    3.96 -        private void checkLoopLocalVarRangeEnding(JCTree loop, JCTree body,
    3.97 -                LoopLocalVarRangeEndingPoint endingPoint) {
    3.98 -            if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
    3.99 -                switch (endingPoint) {
   3.100 -                    case BEFORE_STEPS:
   3.101 -                        if (!loop.hasTag(FORLOOP)) {
   3.102 -                            code.closeAliveRanges(body);
   3.103 -                        }
   3.104 -                        break;
   3.105 -                    case AFTER_STEPS:
   3.106 -                        if (loop.hasTag(FORLOOP)) {
   3.107 -                            code.closeAliveRanges(body);
   3.108 -                        }
   3.109 -                        break;
   3.110 -                }
   3.111 -            }
   3.112 -        }
   3.113 -
   3.114      public void visitForeachLoop(JCEnhancedForLoop tree) {
   3.115          throw new AssertionError(); // should have been removed by Lower.
   3.116      }
   3.117 @@ -1398,9 +1336,6 @@
   3.118  
   3.119                  // Generate code for the statements in this case.
   3.120                  genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
   3.121 -                if (varDebugInfo && lvtRanges.containsKey(code.meth, c.stats.last())) {
   3.122 -                    code.closeAliveRanges(c.stats.last());
   3.123 -                }
   3.124              }
   3.125  
   3.126              // Resolve all breaks.
   3.127 @@ -1557,9 +1492,6 @@
   3.128              genFinalizer(env);
   3.129              code.statBegin(TreeInfo.endPos(env.tree));
   3.130              Chain exitChain = code.branch(goto_);
   3.131 -            if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
   3.132 -                code.closeAliveRanges(body);
   3.133 -            }
   3.134              endFinalizerGap(env);
   3.135              if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) {
   3.136                  // start off with exception on stack
   3.137 @@ -1815,17 +1747,11 @@
   3.138              code.resolve(c.trueJumps);
   3.139              genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
   3.140              thenExit = code.branch(goto_);
   3.141 -            if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) {
   3.142 -                code.closeAliveRanges(tree.thenpart, code.cp);
   3.143 -            }
   3.144          }
   3.145          if (elseChain != null) {
   3.146              code.resolve(elseChain);
   3.147              if (tree.elsepart != null) {
   3.148                  genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET);
   3.149 -                if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.elsepart)) {
   3.150 -                    code.closeAliveRanges(tree.elsepart);
   3.151 -                }
   3.152              }
   3.153          }
   3.154          code.resolve(thenExit);
   3.155 @@ -2514,16 +2440,6 @@
   3.156              localEnv.toplevel = env.toplevel;
   3.157              localEnv.enclClass = cdef;
   3.158  
   3.159 -            /*  We must not analyze synthetic methods
   3.160 -             */
   3.161 -            if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
   3.162 -                try {
   3.163 -                    new LVTAssignAnalyzer().analyzeTree(localEnv);
   3.164 -                } catch (Throwable e) {
   3.165 -                    throw e;
   3.166 -                }
   3.167 -            }
   3.168 -
   3.169              for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) {
   3.170                  genDef(l.head, localEnv);
   3.171              }
   3.172 @@ -2609,282 +2525,4 @@
   3.173          }
   3.174      }
   3.175  
   3.176 -    class LVTAssignAnalyzer
   3.177 -        extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
   3.178 -
   3.179 -        final LVTBits lvtInits;
   3.180 -
   3.181 -        /*  This class is anchored to a context dependent tree. The tree can
   3.182 -         *  vary inside the same instruction for example in the switch instruction
   3.183 -         *  the same FlowBits instance can be anchored to the whole tree, or
   3.184 -         *  to a given case. The aim is to always anchor the bits to the tree
   3.185 -         *  capable of closing a DA range.
   3.186 -         */
   3.187 -        class LVTBits extends Bits {
   3.188 -
   3.189 -            JCTree currentTree;
   3.190 -            private int[] oldBits = null;
   3.191 -            BitsState stateBeforeOp;
   3.192 -
   3.193 -            @Override
   3.194 -            public void clear() {
   3.195 -                generalOp(null, -1, BitsOpKind.CLEAR);
   3.196 -            }
   3.197 -
   3.198 -            @Override
   3.199 -            protected void internalReset() {
   3.200 -                super.internalReset();
   3.201 -                oldBits = null;
   3.202 -            }
   3.203 -
   3.204 -            @Override
   3.205 -            public Bits assign(Bits someBits) {
   3.206 -                // bits can be null
   3.207 -                oldBits = bits;
   3.208 -                stateBeforeOp = currentState;
   3.209 -                super.assign(someBits);
   3.210 -                changed();
   3.211 -                return this;
   3.212 -            }
   3.213 -
   3.214 -            @Override
   3.215 -            public void excludeFrom(int start) {
   3.216 -                generalOp(null, start, BitsOpKind.EXCL_RANGE);
   3.217 -            }
   3.218 -
   3.219 -            @Override
   3.220 -            public void excl(int x) {
   3.221 -                Assert.check(x >= 0);
   3.222 -                generalOp(null, x, BitsOpKind.EXCL_BIT);
   3.223 -            }
   3.224 -
   3.225 -            @Override
   3.226 -            public Bits andSet(Bits xs) {
   3.227 -               return generalOp(xs, -1, BitsOpKind.AND_SET);
   3.228 -            }
   3.229 -
   3.230 -            @Override
   3.231 -            public Bits orSet(Bits xs) {
   3.232 -                return generalOp(xs, -1, BitsOpKind.OR_SET);
   3.233 -            }
   3.234 -
   3.235 -            @Override
   3.236 -            public Bits diffSet(Bits xs) {
   3.237 -                return generalOp(xs, -1, BitsOpKind.DIFF_SET);
   3.238 -            }
   3.239 -
   3.240 -            @Override
   3.241 -            public Bits xorSet(Bits xs) {
   3.242 -                return generalOp(xs, -1, BitsOpKind.XOR_SET);
   3.243 -            }
   3.244 -
   3.245 -            private Bits generalOp(Bits xs, int i, BitsOpKind opKind) {
   3.246 -                Assert.check(currentState != BitsState.UNKNOWN);
   3.247 -                oldBits = dupBits();
   3.248 -                stateBeforeOp = currentState;
   3.249 -                switch (opKind) {
   3.250 -                    case AND_SET:
   3.251 -                        super.andSet(xs);
   3.252 -                        break;
   3.253 -                    case OR_SET:
   3.254 -                        super.orSet(xs);
   3.255 -                        break;
   3.256 -                    case XOR_SET:
   3.257 -                        super.xorSet(xs);
   3.258 -                        break;
   3.259 -                    case DIFF_SET:
   3.260 -                        super.diffSet(xs);
   3.261 -                        break;
   3.262 -                    case CLEAR:
   3.263 -                        super.clear();
   3.264 -                        break;
   3.265 -                    case EXCL_BIT:
   3.266 -                        super.excl(i);
   3.267 -                        break;
   3.268 -                    case EXCL_RANGE:
   3.269 -                        super.excludeFrom(i);
   3.270 -                        break;
   3.271 -                }
   3.272 -                changed();
   3.273 -                return this;
   3.274 -            }
   3.275 -
   3.276 -            /*  The tree we need to anchor the bits instance to.
   3.277 -             */
   3.278 -            LVTBits at(JCTree tree) {
   3.279 -                this.currentTree = tree;
   3.280 -                return this;
   3.281 -            }
   3.282 -
   3.283 -            /*  If the instance should be changed but the tree is not a closing
   3.284 -             *  tree then a reset is needed or the former tree can mistakingly be
   3.285 -             *  used.
   3.286 -             */
   3.287 -            LVTBits resetTree() {
   3.288 -                this.currentTree = null;
   3.289 -                return this;
   3.290 -            }
   3.291 -
   3.292 -            /** This method will be called after any operation that causes a change to
   3.293 -             *  the bits. Subclasses can thus override it in order to extract information
   3.294 -             *  from the changes produced to the bits by the given operation.
   3.295 -             */
   3.296 -            public void changed() {
   3.297 -                if (currentTree != null &&
   3.298 -                        stateBeforeOp != BitsState.UNKNOWN &&
   3.299 -                        trackTree(currentTree)) {
   3.300 -                    List<VarSymbol> locals = lvtRanges
   3.301 -                            .getVars(currentMethod, currentTree);
   3.302 -                    locals = locals != null ?
   3.303 -                            locals : List.<VarSymbol>nil();
   3.304 -                    for (JCVariableDecl vardecl : vardecls) {
   3.305 -                        //once the first is null, the rest will be so.
   3.306 -                        if (vardecl == null) {
   3.307 -                            break;
   3.308 -                        }
   3.309 -                        if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) {
   3.310 -                            locals = locals.prepend(vardecl.sym);
   3.311 -                        }
   3.312 -                    }
   3.313 -                    if (!locals.isEmpty()) {
   3.314 -                        lvtRanges.setEntry(currentMethod,
   3.315 -                                currentTree, locals);
   3.316 -                    }
   3.317 -                }
   3.318 -            }
   3.319 -
   3.320 -            boolean bitChanged(int x) {
   3.321 -                boolean isMemberOfBits = isMember(x);
   3.322 -                int[] tmp = bits;
   3.323 -                bits = oldBits;
   3.324 -                boolean isMemberOfOldBits = isMember(x);
   3.325 -                bits = tmp;
   3.326 -                return (!isMemberOfBits && isMemberOfOldBits);
   3.327 -            }
   3.328 -
   3.329 -            boolean trackVar(VarSymbol var) {
   3.330 -                return (var.owner.kind == MTH &&
   3.331 -                        (var.flags() & PARAMETER) == 0 &&
   3.332 -                        trackable(var));
   3.333 -            }
   3.334 -
   3.335 -            boolean trackTree(JCTree tree) {
   3.336 -                switch (tree.getTag()) {
   3.337 -                    // of course a method closes the alive range of a local variable.
   3.338 -                    case METHODDEF:
   3.339 -                    // for while loops we want only the body
   3.340 -                    case WHILELOOP:
   3.341 -                        return false;
   3.342 -                }
   3.343 -                return true;
   3.344 -            }
   3.345 -
   3.346 -        }
   3.347 -
   3.348 -        public class LVTAssignPendingExit extends
   3.349 -                                    Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit {
   3.350 -
   3.351 -            LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
   3.352 -                super(tree, inits, uninits);
   3.353 -            }
   3.354 -
   3.355 -            @Override
   3.356 -            public void resolveJump(JCTree tree) {
   3.357 -                lvtInits.at(tree);
   3.358 -                super.resolveJump(tree);
   3.359 -            }
   3.360 -        }
   3.361 -
   3.362 -        private LVTAssignAnalyzer() {
   3.363 -            flow.super();
   3.364 -            lvtInits = new LVTBits();
   3.365 -            inits = lvtInits;
   3.366 -        }
   3.367 -
   3.368 -        @Override
   3.369 -        protected void markDead(JCTree tree) {
   3.370 -            lvtInits.at(tree).inclRange(returnadr, nextadr);
   3.371 -            super.markDead(tree);
   3.372 -        }
   3.373 -
   3.374 -        @Override
   3.375 -        protected void merge(JCTree tree) {
   3.376 -            lvtInits.at(tree);
   3.377 -            super.merge(tree);
   3.378 -        }
   3.379 -
   3.380 -        boolean isSyntheticOrMandated(Symbol sym) {
   3.381 -            return (sym.flags() & (SYNTHETIC | MANDATED)) != 0;
   3.382 -        }
   3.383 -
   3.384 -        @Override
   3.385 -        protected boolean trackable(VarSymbol sym) {
   3.386 -            if (isSyntheticOrMandated(sym)) {
   3.387 -                //fast check to avoid tracking synthetic or mandated variables
   3.388 -                return false;
   3.389 -            }
   3.390 -            return super.trackable(sym);
   3.391 -        }
   3.392 -
   3.393 -        @Override
   3.394 -        protected void initParam(JCVariableDecl def) {
   3.395 -            if (!isSyntheticOrMandated(def.sym)) {
   3.396 -                super.initParam(def);
   3.397 -            }
   3.398 -        }
   3.399 -
   3.400 -        @Override
   3.401 -        protected void assignToInits(JCTree tree, Bits bits) {
   3.402 -            lvtInits.at(tree);
   3.403 -            lvtInits.assign(bits);
   3.404 -        }
   3.405 -
   3.406 -        @Override
   3.407 -        protected void andSetInits(JCTree tree, Bits bits) {
   3.408 -            lvtInits.at(tree);
   3.409 -            lvtInits.andSet(bits);
   3.410 -        }
   3.411 -
   3.412 -        @Override
   3.413 -        protected void orSetInits(JCTree tree, Bits bits) {
   3.414 -            lvtInits.at(tree);
   3.415 -            lvtInits.orSet(bits);
   3.416 -        }
   3.417 -
   3.418 -        @Override
   3.419 -        protected void exclVarFromInits(JCTree tree, int adr) {
   3.420 -            lvtInits.at(tree);
   3.421 -            lvtInits.excl(adr);
   3.422 -        }
   3.423 -
   3.424 -        @Override
   3.425 -        protected LVTAssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
   3.426 -            return new LVTAssignPendingExit(tree, inits, uninits);
   3.427 -        }
   3.428 -
   3.429 -        MethodSymbol currentMethod;
   3.430 -
   3.431 -        @Override
   3.432 -        public void visitMethodDef(JCMethodDecl tree) {
   3.433 -            if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0
   3.434 -                    && (tree.sym.flags() & LAMBDA_METHOD) == 0) {
   3.435 -                return;
   3.436 -            }
   3.437 -            if (tree.name.equals(names.clinit)) {
   3.438 -                return;
   3.439 -            }
   3.440 -            boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
   3.441 -            if (enumClass &&
   3.442 -                    (tree.name.equals(names.valueOf) ||
   3.443 -                    tree.name.equals(names.values) ||
   3.444 -                    tree.name.equals(names.init))) {
   3.445 -                return;
   3.446 -            }
   3.447 -            currentMethod = tree.sym;
   3.448 -
   3.449 -            super.visitMethodDef(tree);
   3.450 -        }
   3.451 -
   3.452 -    }
   3.453 -
   3.454  }
     4.1 --- a/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java	Tue Jan 13 12:41:16 2015 -0800
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,129 +0,0 @@
     4.4 -/*
     4.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 - *
     4.8 - * This code is free software; you can redistribute it and/or modify it
     4.9 - * under the terms of the GNU General Public License version 2 only, as
    4.10 - * published by the Free Software Foundation.  Oracle designates this
    4.11 - * particular file as subject to the "Classpath" exception as provided
    4.12 - * by Oracle in the LICENSE file that accompanied this code.
    4.13 - *
    4.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 - * version 2 for more details (a copy is included in the LICENSE file that
    4.18 - * accompanied this code).
    4.19 - *
    4.20 - * You should have received a copy of the GNU General Public License version
    4.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 - *
    4.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 - * or visit www.oracle.com if you need additional information or have any
    4.26 - * questions.
    4.27 - */
    4.28 -
    4.29 -package com.sun.tools.javac.jvm;
    4.30 -
    4.31 -import java.util.Map;
    4.32 -import java.util.Map.Entry;
    4.33 -import java.util.WeakHashMap;
    4.34 -
    4.35 -import com.sun.tools.javac.code.Symbol.MethodSymbol;
    4.36 -import com.sun.tools.javac.code.Symbol.VarSymbol;
    4.37 -import com.sun.tools.javac.tree.JCTree;
    4.38 -import com.sun.tools.javac.util.Context;
    4.39 -import com.sun.tools.javac.util.List;
    4.40 -
    4.41 -/** This class contains a one to many relation between a tree and a set of variables.
    4.42 - *  The relation implies that the given tree closes the DA (definite assignment)
    4.43 - *  range for the set of variables.
    4.44 - *
    4.45 - *  <p><b>This is NOT part of any supported API.
    4.46 - *  If you write code that depends on this, you do so at your own risk.
    4.47 - *  This code and its internal interfaces are subject to change or
    4.48 - *  deletion without notice.</b>
    4.49 - */
    4.50 -public class LVTRanges {
    4.51 -    /** The context key for the LVT ranges. */
    4.52 -    protected static final Context.Key<LVTRanges> lvtRangesKey = new Context.Key<>();
    4.53 -
    4.54 -    /** Get the LVTRanges instance for this context. */
    4.55 -    public static LVTRanges instance(Context context) {
    4.56 -        LVTRanges instance = context.get(lvtRangesKey);
    4.57 -        if (instance == null) {
    4.58 -            instance = new LVTRanges(context);
    4.59 -        }
    4.60 -        return instance;
    4.61 -    }
    4.62 -
    4.63 -    private static final long serialVersionUID = 1812267524140424433L;
    4.64 -
    4.65 -    protected Context context;
    4.66 -
    4.67 -    protected Map<MethodSymbol, Map<JCTree, List<VarSymbol>>>
    4.68 -            aliveRangeClosingTrees = new WeakHashMap<>();
    4.69 -
    4.70 -    public LVTRanges(Context context) {
    4.71 -        this.context = context;
    4.72 -        context.put(lvtRangesKey, this);
    4.73 -    }
    4.74 -
    4.75 -    public List<VarSymbol> getVars(MethodSymbol method, JCTree tree) {
    4.76 -        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
    4.77 -        return (varMap != null) ? varMap.get(tree) : null;
    4.78 -    }
    4.79 -
    4.80 -    public boolean containsKey(MethodSymbol method, JCTree tree) {
    4.81 -        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
    4.82 -        if (varMap == null) {
    4.83 -            return false;
    4.84 -        }
    4.85 -        return varMap.containsKey(tree);
    4.86 -    }
    4.87 -
    4.88 -    public void setEntry(MethodSymbol method, JCTree tree, List<VarSymbol> vars) {
    4.89 -        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
    4.90 -        if (varMap != null) {
    4.91 -            varMap.put(tree, vars);
    4.92 -        } else {
    4.93 -            varMap = new WeakHashMap<>();
    4.94 -            varMap.put(tree, vars);
    4.95 -            aliveRangeClosingTrees.put(method, varMap);
    4.96 -        }
    4.97 -    }
    4.98 -
    4.99 -    public List<VarSymbol> removeEntry(MethodSymbol method, JCTree tree) {
   4.100 -        Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
   4.101 -        if (varMap != null) {
   4.102 -            List<VarSymbol> result = varMap.remove(tree);
   4.103 -            if (varMap.isEmpty()) {
   4.104 -                aliveRangeClosingTrees.remove(method);
   4.105 -            }
   4.106 -            return result;
   4.107 -        }
   4.108 -        return null;
   4.109 -    }
   4.110 -
   4.111 -    /* This method should be used for debugging LVT related issues.
   4.112 -     */
   4.113 -    @Override
   4.114 -    public String toString() {
   4.115 -        String result = "";
   4.116 -        for (Entry<MethodSymbol, Map<JCTree, List<VarSymbol>>> mainEntry: aliveRangeClosingTrees.entrySet()) {
   4.117 -            result += "Method: \n" + mainEntry.getKey().flatName() + "\n";
   4.118 -            int i = 1;
   4.119 -            for (Entry<JCTree, List<VarSymbol>> treeEntry: mainEntry.getValue().entrySet()) {
   4.120 -                result += "    Tree " + i + ": \n" + treeEntry.getKey().toString() + "\n";
   4.121 -                result += "        Variables closed:\n";
   4.122 -                for (VarSymbol var: treeEntry.getValue()) {
   4.123 -                    result += "            " + var.toString();
   4.124 -                }
   4.125 -                result += "\n";
   4.126 -                i++;
   4.127 -            }
   4.128 -        }
   4.129 -        return result;
   4.130 -    }
   4.131 -
   4.132 -}
     5.1 --- a/test/tools/javac/flow/LVTHarness.java	Tue Jan 13 12:41:16 2015 -0800
     5.2 +++ b/test/tools/javac/flow/LVTHarness.java	Tue Jan 20 14:14:33 2015 -0800
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -23,7 +23,7 @@
    5.11  
    5.12  /*
    5.13   * @test
    5.14 - * @bug 7047734 8027660 8037937 8047719 8058708
    5.15 + * @bug 7047734 8027660 8037937 8047719 8058708 8064857
    5.16   * @summary The LVT is not generated correctly during some try/catch scenarios
    5.17   *          javac crash while creating LVT entry for a local variable defined in
    5.18   *          an inner block
    5.19 @@ -144,7 +144,7 @@
    5.20      }
    5.21  
    5.22      void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges)
    5.23 -            throws InvalidIndex, UnexpectedEntry {
    5.24 +            throws InvalidIndex, UnexpectedEntry, ConstantPoolException {
    5.25          Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);
    5.26          LocalVariableTable_attribute lvt =
    5.27              (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable));
    5.28 @@ -166,7 +166,7 @@
    5.29          }
    5.30  
    5.31          if (i < infoFromRanges.size()) {
    5.32 -            error(infoFromLVT, infoFromRanges);
    5.33 +            error(infoFromLVT, infoFromRanges, method.getName(constantPool).toString());
    5.34          }
    5.35      }
    5.36  
    5.37 @@ -202,9 +202,10 @@
    5.38          return sb.toString();
    5.39      }
    5.40  
    5.41 -    protected void error(List<String> infoFromLVT, List<String> infoFromRanges) {
    5.42 +    protected void error(List<String> infoFromLVT, List<String> infoFromRanges, String methodName) {
    5.43          nerrors++;
    5.44          System.err.printf("Error occurred while checking file: %s\n", jfo.getName());
    5.45 +        System.err.printf("at method: %s\n", methodName);
    5.46          System.err.println("The range info from the annotations is");
    5.47          printStringListToErrOutput(infoFromRanges);
    5.48          System.err.println();
     6.1 --- a/test/tools/javac/flow/tests/TestCaseFor.java	Tue Jan 13 12:41:16 2015 -0800
     6.2 +++ b/test/tools/javac/flow/tests/TestCaseFor.java	Tue Jan 20 14:14:33 2015 -0800
     6.3 @@ -2,7 +2,7 @@
     6.4  
     6.5  public class TestCaseFor {
     6.6  
     6.7 -    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
     6.8 +    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=11)
     6.9      @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
    6.10      void m1(String[] args) {
    6.11          Object o;
    6.12 @@ -13,7 +13,7 @@
    6.13          o = "";
    6.14      }
    6.15  
    6.16 -    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
    6.17 +    @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=11)
    6.18      @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
    6.19      void m2(String[] args) {
    6.20          Object o;
     7.1 --- a/test/tools/javac/flow/tests/TestCaseForEach.java	Tue Jan 13 12:41:16 2015 -0800
     7.2 +++ b/test/tools/javac/flow/tests/TestCaseForEach.java	Tue Jan 20 14:14:33 2015 -0800
     7.3 @@ -2,7 +2,7 @@
     7.4  
     7.5  public class TestCaseForEach {
     7.6  
     7.7 -    @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=8)
     7.8 +    @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=11)
     7.9      @AliveRange(varName="o", bytecodeStart=39, bytecodeLength=1)
    7.10      void m(String[] args) {
    7.11          Object o;
     8.1 --- a/test/tools/javac/flow/tests/TestCaseIfElse.java	Tue Jan 13 12:41:16 2015 -0800
     8.2 +++ b/test/tools/javac/flow/tests/TestCaseIfElse.java	Tue Jan 20 14:14:33 2015 -0800
     8.3 @@ -60,4 +60,19 @@
     8.4          }
     8.5          return null;
     8.6      }
     8.7 +
     8.8 +    @AliveRange(varName="i", bytecodeStart=6, bytecodeLength=2)
     8.9 +    int m4(boolean flag) {
    8.10 +        int i;
    8.11 +        label:
    8.12 +        {
    8.13 +            if (flag) {
    8.14 +                i = 1;
    8.15 +            } else {
    8.16 +                break label;
    8.17 +            }
    8.18 +            return i;
    8.19 +        }
    8.20 +        return -1;
    8.21 +    }
    8.22  }
     9.1 --- a/test/tools/javac/flow/tests/TestCaseSwitch.java	Tue Jan 13 12:41:16 2015 -0800
     9.2 +++ b/test/tools/javac/flow/tests/TestCaseSwitch.java	Tue Jan 20 14:14:33 2015 -0800
     9.3 @@ -81,4 +81,26 @@
     9.4          o = "finish";
     9.5      }
     9.6  
     9.7 +    @AliveRange(varName="oCache", bytecodeStart=30, bytecodeLength=6)
     9.8 +    @AliveRange(varName="cache", bytecodeStart=41, bytecodeLength=3)
     9.9 +    @AliveRange(varName="cache", bytecodeStart=54, bytecodeLength=2)
    9.10 +    @AliveRange(varName="service", bytecodeStart=39, bytecodeLength=5)
    9.11 +    Object m4(int i) {
    9.12 +        Object cache;
    9.13 +        switch (i) {
    9.14 +            case 0:
    9.15 +                Object oCache = null;
    9.16 +                if (oCache != null) {
    9.17 +                    return oCache;
    9.18 +                }
    9.19 +            case 1:
    9.20 +                Object service = null;
    9.21 +                cache = null;
    9.22 +                break;
    9.23 +            default:
    9.24 +                throw new AssertionError("");
    9.25 +            }
    9.26 +        return cache;
    9.27 +    }
    9.28 +
    9.29  }
    10.1 --- a/test/tools/javac/flow/tests/TestCaseTry.java	Tue Jan 13 12:41:16 2015 -0800
    10.2 +++ b/test/tools/javac/flow/tests/TestCaseTry.java	Tue Jan 20 14:14:33 2015 -0800
    10.3 @@ -17,7 +17,8 @@
    10.4      }
    10.5  
    10.6      @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
    10.7 -    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=23)
    10.8 +    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=8)
    10.9 +    @AliveRange(varName="o", bytecodeStart=35, bytecodeLength=11)
   10.10      void m1() {
   10.11          Object o;
   10.12          try {
   10.13 @@ -33,7 +34,8 @@
   10.14      }
   10.15  
   10.16      @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
   10.17 -    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=31)
   10.18 +    @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=16)
   10.19 +    @AliveRange(varName="o", bytecodeStart=43, bytecodeLength=11)
   10.20      void m2() {
   10.21          Object o;
   10.22          try {
   10.23 @@ -51,7 +53,8 @@
   10.24      }
   10.25  
   10.26      @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38)
   10.27 -    @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=8)
   10.28 +    @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=3)
   10.29 +    @AliveRange(varName="o", bytecodeStart=110, bytecodeLength=1)
   10.30      void m3() {
   10.31          Object o;
   10.32          try (BufferedReader br =
    11.1 --- a/test/tools/javac/flow/tests/TestCaseWhile.java	Tue Jan 13 12:41:16 2015 -0800
    11.2 +++ b/test/tools/javac/flow/tests/TestCaseWhile.java	Tue Jan 20 14:14:33 2015 -0800
    11.3 @@ -2,7 +2,7 @@
    11.4  
    11.5  public class TestCaseWhile {
    11.6  
    11.7 -    @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5)
    11.8 +    @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=8)
    11.9      @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=1)
   11.10      void m(String[] args) {
   11.11          Object o;

mercurial