1187 c = items.makeCondItem(goto_); |
1196 c = items.makeCondItem(goto_); |
1188 } |
1197 } |
1189 Chain loopDone = c.jumpFalse(); |
1198 Chain loopDone = c.jumpFalse(); |
1190 code.resolve(c.trueJumps); |
1199 code.resolve(c.trueJumps); |
1191 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET); |
1200 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET); |
|
1201 if (varDebugInfo) { |
|
1202 checkLoopLocalVarRangeEnding(loop, body, |
|
1203 LoopLocalVarRangeEndingPoint.BEFORE_STEPS); |
|
1204 } |
1192 code.resolve(loopEnv.info.cont); |
1205 code.resolve(loopEnv.info.cont); |
1193 genStats(step, loopEnv); |
1206 genStats(step, loopEnv); |
|
1207 if (varDebugInfo) { |
|
1208 checkLoopLocalVarRangeEnding(loop, body, |
|
1209 LoopLocalVarRangeEndingPoint.AFTER_STEPS); |
|
1210 } |
1194 code.resolve(code.branch(goto_), startpc); |
1211 code.resolve(code.branch(goto_), startpc); |
1195 code.resolve(loopDone); |
1212 code.resolve(loopDone); |
1196 } else { |
1213 } else { |
1197 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET); |
1214 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET); |
|
1215 if (varDebugInfo) { |
|
1216 checkLoopLocalVarRangeEnding(loop, body, |
|
1217 LoopLocalVarRangeEndingPoint.BEFORE_STEPS); |
|
1218 } |
1198 code.resolve(loopEnv.info.cont); |
1219 code.resolve(loopEnv.info.cont); |
1199 genStats(step, loopEnv); |
1220 genStats(step, loopEnv); |
|
1221 if (varDebugInfo) { |
|
1222 checkLoopLocalVarRangeEnding(loop, body, |
|
1223 LoopLocalVarRangeEndingPoint.AFTER_STEPS); |
|
1224 } |
1200 CondItem c; |
1225 CondItem c; |
1201 if (cond != null) { |
1226 if (cond != null) { |
1202 code.statBegin(cond.pos); |
1227 code.statBegin(cond.pos); |
1203 c = genCond(TreeInfo.skipParens(cond), CRT_FLOW_CONTROLLER); |
1228 c = genCond(TreeInfo.skipParens(cond), CRT_FLOW_CONTROLLER); |
1204 } else { |
1229 } else { |
1208 code.resolve(c.falseJumps); |
1233 code.resolve(c.falseJumps); |
1209 } |
1234 } |
1210 code.resolve(loopEnv.info.exit); |
1235 code.resolve(loopEnv.info.exit); |
1211 } |
1236 } |
1212 |
1237 |
|
1238 private enum LoopLocalVarRangeEndingPoint { |
|
1239 BEFORE_STEPS, |
|
1240 AFTER_STEPS, |
|
1241 } |
|
1242 |
|
1243 /** |
|
1244 * Checks whether we have reached an alive range ending point for local |
|
1245 * variables after a loop. |
|
1246 * |
|
1247 * Local variables alive range ending point for loops varies depending |
|
1248 * on the loop type. The range can be closed before or after the code |
|
1249 * for the steps sentences has been generated. |
|
1250 * |
|
1251 * - While loops has no steps so in that case the range is closed just |
|
1252 * after the body of the loop. |
|
1253 * |
|
1254 * - For-like loops may have steps so as long as the steps sentences |
|
1255 * can possibly contain non-synthetic local variables, the alive range |
|
1256 * for local variables must be closed after the steps in this case. |
|
1257 */ |
|
1258 private void checkLoopLocalVarRangeEnding(JCTree loop, JCTree body, |
|
1259 LoopLocalVarRangeEndingPoint endingPoint) { |
|
1260 if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) { |
|
1261 switch (endingPoint) { |
|
1262 case BEFORE_STEPS: |
|
1263 if (!loop.hasTag(FORLOOP)) { |
|
1264 code.closeAliveRanges(body); |
|
1265 } |
|
1266 break; |
|
1267 case AFTER_STEPS: |
|
1268 if (loop.hasTag(FORLOOP)) { |
|
1269 code.closeAliveRanges(body); |
|
1270 } |
|
1271 break; |
|
1272 } |
|
1273 } |
|
1274 } |
|
1275 |
1213 public void visitForeachLoop(JCEnhancedForLoop tree) { |
1276 public void visitForeachLoop(JCEnhancedForLoop tree) { |
1214 throw new AssertionError(); // should have been removed by Lower. |
1277 throw new AssertionError(); // should have been removed by Lower. |
1215 } |
1278 } |
1216 |
1279 |
1217 public void visitLabelled(JCLabeledStatement tree) { |
1280 public void visitLabelled(JCLabeledStatement tree) { |
1221 } |
1284 } |
1222 |
1285 |
1223 public void visitSwitch(JCSwitch tree) { |
1286 public void visitSwitch(JCSwitch tree) { |
1224 int limit = code.nextreg; |
1287 int limit = code.nextreg; |
1225 Assert.check(!tree.selector.type.hasTag(CLASS)); |
1288 Assert.check(!tree.selector.type.hasTag(CLASS)); |
1226 int startpcCrt = genCrt ? code.curPc() : 0; |
1289 int startpcCrt = genCrt ? code.curCP() : 0; |
1227 Item sel = genExpr(tree.selector, syms.intType); |
1290 Item sel = genExpr(tree.selector, syms.intType); |
1228 List<JCCase> cases = tree.cases; |
1291 List<JCCase> cases = tree.cases; |
1229 if (cases.isEmpty()) { |
1292 if (cases.isEmpty()) { |
1230 // We are seeing: switch <sel> {} |
1293 // We are seeing: switch <sel> {} |
1231 sel.load().drop(); |
1294 sel.load().drop(); |
1232 if (genCrt) |
1295 if (genCrt) |
1233 code.crt.put(TreeInfo.skipParens(tree.selector), |
1296 code.crt.put(TreeInfo.skipParens(tree.selector), |
1234 CRT_FLOW_CONTROLLER, startpcCrt, code.curPc()); |
1297 CRT_FLOW_CONTROLLER, startpcCrt, code.curCP()); |
1235 } else { |
1298 } else { |
1236 // We are seeing a nonempty switch. |
1299 // We are seeing a nonempty switch. |
1237 sel.load(); |
1300 sel.load(); |
1238 if (genCrt) |
1301 if (genCrt) |
1239 code.crt.put(TreeInfo.skipParens(tree.selector), |
1302 code.crt.put(TreeInfo.skipParens(tree.selector), |
1240 CRT_FLOW_CONTROLLER, startpcCrt, code.curPc()); |
1303 CRT_FLOW_CONTROLLER, startpcCrt, code.curCP()); |
1241 Env<GenContext> switchEnv = env.dup(tree, new GenContext()); |
1304 Env<GenContext> switchEnv = env.dup(tree, new GenContext()); |
1242 switchEnv.info.isSwitch = true; |
1305 switchEnv.info.isSwitch = true; |
1243 |
1306 |
1244 // Compute number of labels and minimum and maximum label values. |
1307 // Compute number of labels and minimum and maximum label values. |
1245 // For each case, store its label in an array. |
1308 // For each case, store its label in an array. |
1465 * @param catchers The lis of catch clauses. |
1531 * @param catchers The lis of catch clauses. |
1466 * @param env the environment current for the body. |
1532 * @param env the environment current for the body. |
1467 */ |
1533 */ |
1468 void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) { |
1534 void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) { |
1469 int limit = code.nextreg; |
1535 int limit = code.nextreg; |
1470 int startpc = code.curPc(); |
1536 int startpc = code.curCP(); |
1471 Code.State stateTry = code.state.dup(); |
1537 Code.State stateTry = code.state.dup(); |
1472 genStat(body, env, CRT_BLOCK); |
1538 genStat(body, env, CRT_BLOCK); |
1473 int endpc = code.curPc(); |
1539 int endpc = code.curCP(); |
1474 boolean hasFinalizer = |
1540 boolean hasFinalizer = |
1475 env.info.finalize != null && |
1541 env.info.finalize != null && |
1476 env.info.finalize.hasFinalizer(); |
1542 env.info.finalize.hasFinalizer(); |
1477 List<Integer> gaps = env.info.gaps.toList(); |
1543 List<Integer> gaps = env.info.gaps.toList(); |
1478 code.statBegin(TreeInfo.endPos(body)); |
1544 code.statBegin(TreeInfo.endPos(body)); |
1479 genFinalizer(env); |
1545 genFinalizer(env); |
1480 code.statBegin(TreeInfo.endPos(env.tree)); |
1546 code.statBegin(TreeInfo.endPos(env.tree)); |
1481 Chain exitChain = code.branch(goto_); |
1547 Chain exitChain = code.branch(goto_); |
|
1548 if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) { |
|
1549 code.closeAliveRanges(body); |
|
1550 } |
1482 endFinalizerGap(env); |
1551 endFinalizerGap(env); |
1483 if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) { |
1552 if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) { |
1484 // start off with exception on stack |
1553 // start off with exception on stack |
1485 code.entryPoint(stateTry, l.head.param.sym.type); |
1554 code.entryPoint(stateTry, l.head.param.sym.type); |
1486 genCatch(l.head, env, startpc, endpc, gaps); |
1555 genCatch(l.head, env, startpc, endpc, gaps); |
1730 Chain elseChain = c.jumpFalse(); |
1799 Chain elseChain = c.jumpFalse(); |
1731 if (!c.isFalse()) { |
1800 if (!c.isFalse()) { |
1732 code.resolve(c.trueJumps); |
1801 code.resolve(c.trueJumps); |
1733 genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); |
1802 genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); |
1734 thenExit = code.branch(goto_); |
1803 thenExit = code.branch(goto_); |
|
1804 if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) { |
|
1805 code.closeAliveRanges(tree.thenpart, |
|
1806 thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp); |
|
1807 } |
1735 } |
1808 } |
1736 if (elseChain != null) { |
1809 if (elseChain != null) { |
1737 code.resolve(elseChain); |
1810 code.resolve(elseChain); |
1738 if (tree.elsepart != null) |
1811 if (tree.elsepart != null) { |
1739 genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET); |
1812 genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET); |
|
1813 if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.elsepart)) { |
|
1814 code.closeAliveRanges(tree.elsepart); |
|
1815 } |
|
1816 } |
1740 } |
1817 } |
1741 code.resolve(thenExit); |
1818 code.resolve(thenExit); |
1742 code.endScopes(limit); |
1819 code.endScopes(limit); |
1743 } |
1820 } |
1744 |
1821 |
1828 Chain thenExit = null; |
1905 Chain thenExit = null; |
1829 CondItem c = genCond(tree.cond, CRT_FLOW_CONTROLLER); |
1906 CondItem c = genCond(tree.cond, CRT_FLOW_CONTROLLER); |
1830 Chain elseChain = c.jumpFalse(); |
1907 Chain elseChain = c.jumpFalse(); |
1831 if (!c.isFalse()) { |
1908 if (!c.isFalse()) { |
1832 code.resolve(c.trueJumps); |
1909 code.resolve(c.trueJumps); |
1833 int startpc = genCrt ? code.curPc() : 0; |
1910 int startpc = genCrt ? code.curCP() : 0; |
1834 genExpr(tree.truepart, pt).load(); |
1911 genExpr(tree.truepart, pt).load(); |
1835 code.state.forceStackTop(tree.type); |
1912 code.state.forceStackTop(tree.type); |
1836 if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET, |
1913 if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET, |
1837 startpc, code.curPc()); |
1914 startpc, code.curCP()); |
1838 thenExit = code.branch(goto_); |
1915 thenExit = code.branch(goto_); |
1839 } |
1916 } |
1840 if (elseChain != null) { |
1917 if (elseChain != null) { |
1841 code.resolve(elseChain); |
1918 code.resolve(elseChain); |
1842 int startpc = genCrt ? code.curPc() : 0; |
1919 int startpc = genCrt ? code.curCP() : 0; |
1843 genExpr(tree.falsepart, pt).load(); |
1920 genExpr(tree.falsepart, pt).load(); |
1844 code.state.forceStackTop(tree.type); |
1921 code.state.forceStackTop(tree.type); |
1845 if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET, |
1922 if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET, |
1846 startpc, code.curPc()); |
1923 startpc, code.curCP()); |
1847 } |
1924 } |
1848 code.resolve(thenExit); |
1925 code.resolve(thenExit); |
1849 result = items.makeStackItem(pt); |
1926 result = items.makeStackItem(pt); |
1850 } |
1927 } |
1851 |
1928 |
2421 generateReferencesToPrunedTree(c, pool); |
2498 generateReferencesToPrunedTree(c, pool); |
2422 Env<GenContext> localEnv = |
2499 Env<GenContext> localEnv = |
2423 new Env<GenContext>(cdef, new GenContext()); |
2500 new Env<GenContext>(cdef, new GenContext()); |
2424 localEnv.toplevel = env.toplevel; |
2501 localEnv.toplevel = env.toplevel; |
2425 localEnv.enclClass = cdef; |
2502 localEnv.enclClass = cdef; |
|
2503 |
|
2504 /* We must not analyze synthetic methods |
|
2505 */ |
|
2506 if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) { |
|
2507 try { |
|
2508 LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make( |
|
2509 lvtRanges, syms, names); |
|
2510 lvtAssignAnalyzer.analyzeTree(localEnv); |
|
2511 } catch (Throwable e) { |
|
2512 throw e; |
|
2513 } |
|
2514 } |
|
2515 |
2426 for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) { |
2516 for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) { |
2427 genDef(l.head, localEnv); |
2517 genDef(l.head, localEnv); |
2428 } |
2518 } |
2429 if (pool.numEntries() > Pool.MAX_ENTRIES) { |
2519 if (pool.numEntries() > Pool.MAX_ENTRIES) { |
2430 log.error(cdef.pos(), "limit.pool"); |
2520 log.error(cdef.pos(), "limit.pool"); |
2505 */ |
2595 */ |
2506 void addCont(Chain c) { |
2596 void addCont(Chain c) { |
2507 cont = Code.mergeChains(c, cont); |
2597 cont = Code.mergeChains(c, cont); |
2508 } |
2598 } |
2509 } |
2599 } |
|
2600 |
|
2601 static class LVTAssignAnalyzer |
|
2602 extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> { |
|
2603 |
|
2604 final LVTBits lvtInits; |
|
2605 final LVTRanges lvtRanges; |
|
2606 |
|
2607 /* This class is anchored to a context dependent tree. The tree can |
|
2608 * vary inside the same instruction for example in the switch instruction |
|
2609 * the same FlowBits instance can be anchored to the whole tree, or |
|
2610 * to a given case. The aim is to always anchor the bits to the tree |
|
2611 * capable of closing a DA range. |
|
2612 */ |
|
2613 static class LVTBits extends Bits { |
|
2614 |
|
2615 enum BitsOpKind { |
|
2616 INIT, |
|
2617 CLEAR, |
|
2618 INCL_BIT, |
|
2619 EXCL_BIT, |
|
2620 ASSIGN, |
|
2621 AND_SET, |
|
2622 OR_SET, |
|
2623 DIFF_SET, |
|
2624 XOR_SET, |
|
2625 INCL_RANGE, |
|
2626 EXCL_RANGE, |
|
2627 } |
|
2628 |
|
2629 JCTree currentTree; |
|
2630 LVTAssignAnalyzer analyzer; |
|
2631 private int[] oldBits = null; |
|
2632 BitsState stateBeforeOp; |
|
2633 |
|
2634 LVTBits() { |
|
2635 super(false); |
|
2636 } |
|
2637 |
|
2638 LVTBits(int[] bits, BitsState initState) { |
|
2639 super(bits, initState); |
|
2640 } |
|
2641 |
|
2642 @Override |
|
2643 public void clear() { |
|
2644 generalOp(null, -1, BitsOpKind.CLEAR); |
|
2645 } |
|
2646 |
|
2647 @Override |
|
2648 protected void internalReset() { |
|
2649 super.internalReset(); |
|
2650 oldBits = null; |
|
2651 } |
|
2652 |
|
2653 @Override |
|
2654 public Bits assign(Bits someBits) { |
|
2655 // bits can be null |
|
2656 oldBits = bits; |
|
2657 stateBeforeOp = currentState; |
|
2658 super.assign(someBits); |
|
2659 changed(); |
|
2660 return this; |
|
2661 } |
|
2662 |
|
2663 @Override |
|
2664 public void excludeFrom(int start) { |
|
2665 generalOp(null, start, BitsOpKind.EXCL_RANGE); |
|
2666 } |
|
2667 |
|
2668 @Override |
|
2669 public void excl(int x) { |
|
2670 Assert.check(x >= 0); |
|
2671 generalOp(null, x, BitsOpKind.EXCL_BIT); |
|
2672 } |
|
2673 |
|
2674 @Override |
|
2675 public Bits andSet(Bits xs) { |
|
2676 return generalOp(xs, -1, BitsOpKind.AND_SET); |
|
2677 } |
|
2678 |
|
2679 @Override |
|
2680 public Bits orSet(Bits xs) { |
|
2681 return generalOp(xs, -1, BitsOpKind.OR_SET); |
|
2682 } |
|
2683 |
|
2684 @Override |
|
2685 public Bits diffSet(Bits xs) { |
|
2686 return generalOp(xs, -1, BitsOpKind.DIFF_SET); |
|
2687 } |
|
2688 |
|
2689 @Override |
|
2690 public Bits xorSet(Bits xs) { |
|
2691 return generalOp(xs, -1, BitsOpKind.XOR_SET); |
|
2692 } |
|
2693 |
|
2694 private Bits generalOp(Bits xs, int i, BitsOpKind opKind) { |
|
2695 Assert.check(currentState != BitsState.UNKNOWN); |
|
2696 oldBits = dupBits(); |
|
2697 stateBeforeOp = currentState; |
|
2698 switch (opKind) { |
|
2699 case AND_SET: |
|
2700 super.andSet(xs); |
|
2701 break; |
|
2702 case OR_SET: |
|
2703 super.orSet(xs); |
|
2704 break; |
|
2705 case XOR_SET: |
|
2706 super.xorSet(xs); |
|
2707 break; |
|
2708 case DIFF_SET: |
|
2709 super.diffSet(xs); |
|
2710 break; |
|
2711 case CLEAR: |
|
2712 super.clear(); |
|
2713 break; |
|
2714 case EXCL_BIT: |
|
2715 super.excl(i); |
|
2716 break; |
|
2717 case EXCL_RANGE: |
|
2718 super.excludeFrom(i); |
|
2719 break; |
|
2720 } |
|
2721 changed(); |
|
2722 return this; |
|
2723 } |
|
2724 |
|
2725 /* The tree we need to anchor the bits instance to. |
|
2726 */ |
|
2727 LVTBits at(JCTree tree) { |
|
2728 this.currentTree = tree; |
|
2729 return this; |
|
2730 } |
|
2731 |
|
2732 /* If the instance should be changed but the tree is not a closing |
|
2733 * tree then a reset is needed or the former tree can mistakingly be |
|
2734 * used. |
|
2735 */ |
|
2736 LVTBits resetTree() { |
|
2737 this.currentTree = null; |
|
2738 return this; |
|
2739 } |
|
2740 |
|
2741 /** This method will be called after any operation that causes a change to |
|
2742 * the bits. Subclasses can thus override it in order to extract information |
|
2743 * from the changes produced to the bits by the given operation. |
|
2744 */ |
|
2745 public void changed() { |
|
2746 if (currentTree != null && |
|
2747 stateBeforeOp != BitsState.UNKNOWN && |
|
2748 trackTree(currentTree)) { |
|
2749 List<VarSymbol> locals = |
|
2750 analyzer.lvtRanges |
|
2751 .getVars(analyzer.currentMethod, currentTree); |
|
2752 locals = locals != null ? |
|
2753 locals : List.<VarSymbol>nil(); |
|
2754 for (JCVariableDecl vardecl : analyzer.vardecls) { |
|
2755 //once the first is null, the rest will be so. |
|
2756 if (vardecl == null) { |
|
2757 break; |
|
2758 } |
|
2759 if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) { |
|
2760 locals = locals.prepend(vardecl.sym); |
|
2761 } |
|
2762 } |
|
2763 if (!locals.isEmpty()) { |
|
2764 analyzer.lvtRanges.setEntry(analyzer.currentMethod, |
|
2765 currentTree, locals); |
|
2766 } |
|
2767 } |
|
2768 } |
|
2769 |
|
2770 boolean bitChanged(int x) { |
|
2771 boolean isMemberOfBits = isMember(x); |
|
2772 int[] tmp = bits; |
|
2773 bits = oldBits; |
|
2774 boolean isMemberOfOldBits = isMember(x); |
|
2775 bits = tmp; |
|
2776 return (!isMemberOfBits && isMemberOfOldBits); |
|
2777 } |
|
2778 |
|
2779 boolean trackVar(VarSymbol var) { |
|
2780 return (var.owner.kind == MTH && |
|
2781 (var.flags() & (PARAMETER | HASINIT)) == 0 && |
|
2782 analyzer.trackable(var)); |
|
2783 } |
|
2784 |
|
2785 boolean trackTree(JCTree tree) { |
|
2786 switch (tree.getTag()) { |
|
2787 // of course a method closes the alive range of a local variable. |
|
2788 case METHODDEF: |
|
2789 // for while loops we want only the body |
|
2790 case WHILELOOP: |
|
2791 return false; |
|
2792 } |
|
2793 return true; |
|
2794 } |
|
2795 |
|
2796 } |
|
2797 |
|
2798 public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit { |
|
2799 |
|
2800 LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { |
|
2801 super(tree, inits, uninits); |
|
2802 } |
|
2803 |
|
2804 @Override |
|
2805 public void resolveJump(JCTree tree) { |
|
2806 lvtInits.at(tree); |
|
2807 super.resolveJump(tree); |
|
2808 } |
|
2809 } |
|
2810 |
|
2811 private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) { |
|
2812 super(new LVTBits(), syms, names); |
|
2813 lvtInits = (LVTBits)inits; |
|
2814 this.lvtRanges = lvtRanges; |
|
2815 } |
|
2816 |
|
2817 public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) { |
|
2818 LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names); |
|
2819 result.lvtInits.analyzer = result; |
|
2820 return result; |
|
2821 } |
|
2822 |
|
2823 @Override |
|
2824 protected void markDead(JCTree tree) { |
|
2825 lvtInits.at(tree).inclRange(returnadr, nextadr); |
|
2826 super.markDead(tree); |
|
2827 } |
|
2828 |
|
2829 @Override |
|
2830 protected void merge(JCTree tree) { |
|
2831 lvtInits.at(tree); |
|
2832 super.merge(tree); |
|
2833 } |
|
2834 |
|
2835 boolean isSyntheticOrMandated(Symbol sym) { |
|
2836 return (sym.flags() & (SYNTHETIC | MANDATED)) != 0; |
|
2837 } |
|
2838 |
|
2839 @Override |
|
2840 protected boolean trackable(VarSymbol sym) { |
|
2841 if (isSyntheticOrMandated(sym)) { |
|
2842 //fast check to avoid tracking synthetic or mandated variables |
|
2843 return false; |
|
2844 } |
|
2845 return super.trackable(sym); |
|
2846 } |
|
2847 |
|
2848 @Override |
|
2849 protected void initParam(JCVariableDecl def) { |
|
2850 if (!isSyntheticOrMandated(def.sym)) { |
|
2851 super.initParam(def); |
|
2852 } |
|
2853 } |
|
2854 |
|
2855 @Override |
|
2856 protected void assignToInits(JCTree tree, Bits bits) { |
|
2857 lvtInits.at(tree); |
|
2858 lvtInits.assign(bits); |
|
2859 } |
|
2860 |
|
2861 @Override |
|
2862 protected void andSetInits(JCTree tree, Bits bits) { |
|
2863 lvtInits.at(tree); |
|
2864 lvtInits.andSet(bits); |
|
2865 } |
|
2866 |
|
2867 @Override |
|
2868 protected void orSetInits(JCTree tree, Bits bits) { |
|
2869 lvtInits.at(tree); |
|
2870 lvtInits.orSet(bits); |
|
2871 } |
|
2872 |
|
2873 @Override |
|
2874 protected void exclVarFromInits(JCTree tree, int adr) { |
|
2875 lvtInits.at(tree); |
|
2876 lvtInits.excl(adr); |
|
2877 } |
|
2878 |
|
2879 @Override |
|
2880 protected LVTAssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) { |
|
2881 return new LVTAssignPendingExit(tree, inits, uninits); |
|
2882 } |
|
2883 |
|
2884 MethodSymbol currentMethod; |
|
2885 |
|
2886 @Override |
|
2887 public void visitMethodDef(JCMethodDecl tree) { |
|
2888 if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0) { |
|
2889 return; |
|
2890 } |
|
2891 if (tree.name.equals(names.clinit)) { |
|
2892 return; |
|
2893 } |
|
2894 boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0; |
|
2895 if (enumClass && |
|
2896 (tree.name.equals(names.valueOf) || |
|
2897 tree.name.equals(names.values) || |
|
2898 tree.name.equals(names.init))) { |
|
2899 return; |
|
2900 } |
|
2901 currentMethod = tree.sym; |
|
2902 super.visitMethodDef(tree); |
|
2903 } |
|
2904 |
|
2905 } |
|
2906 |
2510 } |
2907 } |