72 private final Type stringBufferType; |
72 private final Type stringBufferType; |
73 private final Map<Type,Symbol> stringBufferAppend; |
73 private final Map<Type,Symbol> stringBufferAppend; |
74 private Name accessDollar; |
74 private Name accessDollar; |
75 private final Types types; |
75 private final Types types; |
76 private final Lower lower; |
76 private final Lower lower; |
|
77 private final Flow flow; |
77 |
78 |
78 /** Format of stackmap tables to be generated. */ |
79 /** Format of stackmap tables to be generated. */ |
79 private final Code.StackMapFormat stackMap; |
80 private final Code.StackMapFormat stackMap; |
80 |
81 |
81 /** A type that serves as the expected type for all method expressions. |
82 /** A type that serves as the expected type for all method expressions. |
111 methodType = new MethodType(null, null, null, syms.methodClass); |
112 methodType = new MethodType(null, null, null, syms.methodClass); |
112 stringBufferType = syms.stringBuilderType; |
113 stringBufferType = syms.stringBuilderType; |
113 stringBufferAppend = new HashMap<>(); |
114 stringBufferAppend = new HashMap<>(); |
114 accessDollar = names. |
115 accessDollar = names. |
115 fromString("access" + target.syntheticNameChar()); |
116 fromString("access" + target.syntheticNameChar()); |
|
117 flow = Flow.instance(context); |
116 lower = Lower.instance(context); |
118 lower = Lower.instance(context); |
117 |
119 |
118 Options options = Options.instance(context); |
120 Options options = Options.instance(context); |
119 lineDebugInfo = |
121 lineDebugInfo = |
120 options.isUnset(G_CUSTOM) || |
122 options.isUnset(G_CUSTOM) || |
2381 |
2383 |
2382 /* We must not analyze synthetic methods |
2384 /* We must not analyze synthetic methods |
2383 */ |
2385 */ |
2384 if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) { |
2386 if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) { |
2385 try { |
2387 try { |
2386 LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make( |
2388 new LVTAssignAnalyzer().analyzeTree(localEnv); |
2387 lvtRanges, syms, names); |
|
2388 lvtAssignAnalyzer.analyzeTree(localEnv); |
|
2389 } catch (Throwable e) { |
2389 } catch (Throwable e) { |
2390 throw e; |
2390 throw e; |
2391 } |
2391 } |
2392 } |
2392 } |
2393 |
2393 |
2474 void addCont(Chain c) { |
2474 void addCont(Chain c) { |
2475 cont = Code.mergeChains(c, cont); |
2475 cont = Code.mergeChains(c, cont); |
2476 } |
2476 } |
2477 } |
2477 } |
2478 |
2478 |
2479 static class LVTAssignAnalyzer |
2479 class LVTAssignAnalyzer |
2480 extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> { |
2480 extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> { |
2481 |
2481 |
2482 final LVTBits lvtInits; |
2482 final LVTBits lvtInits; |
2483 final LVTRanges lvtRanges; |
|
2484 |
2483 |
2485 /* This class is anchored to a context dependent tree. The tree can |
2484 /* This class is anchored to a context dependent tree. The tree can |
2486 * vary inside the same instruction for example in the switch instruction |
2485 * vary inside the same instruction for example in the switch instruction |
2487 * the same FlowBits instance can be anchored to the whole tree, or |
2486 * the same FlowBits instance can be anchored to the whole tree, or |
2488 * to a given case. The aim is to always anchor the bits to the tree |
2487 * to a given case. The aim is to always anchor the bits to the tree |
2489 * capable of closing a DA range. |
2488 * capable of closing a DA range. |
2490 */ |
2489 */ |
2491 static class LVTBits extends Bits { |
2490 class LVTBits extends Bits { |
2492 |
|
2493 enum BitsOpKind { |
|
2494 INIT, |
|
2495 CLEAR, |
|
2496 INCL_BIT, |
|
2497 EXCL_BIT, |
|
2498 ASSIGN, |
|
2499 AND_SET, |
|
2500 OR_SET, |
|
2501 DIFF_SET, |
|
2502 XOR_SET, |
|
2503 INCL_RANGE, |
|
2504 EXCL_RANGE, |
|
2505 } |
|
2506 |
2491 |
2507 JCTree currentTree; |
2492 JCTree currentTree; |
2508 LVTAssignAnalyzer analyzer; |
|
2509 private int[] oldBits = null; |
2493 private int[] oldBits = null; |
2510 BitsState stateBeforeOp; |
2494 BitsState stateBeforeOp; |
2511 |
|
2512 LVTBits() { |
|
2513 super(false); |
|
2514 } |
|
2515 |
|
2516 LVTBits(int[] bits, BitsState initState) { |
|
2517 super(bits, initState); |
|
2518 } |
|
2519 |
2495 |
2520 @Override |
2496 @Override |
2521 public void clear() { |
2497 public void clear() { |
2522 generalOp(null, -1, BitsOpKind.CLEAR); |
2498 generalOp(null, -1, BitsOpKind.CLEAR); |
2523 } |
2499 } |
2622 */ |
2598 */ |
2623 public void changed() { |
2599 public void changed() { |
2624 if (currentTree != null && |
2600 if (currentTree != null && |
2625 stateBeforeOp != BitsState.UNKNOWN && |
2601 stateBeforeOp != BitsState.UNKNOWN && |
2626 trackTree(currentTree)) { |
2602 trackTree(currentTree)) { |
2627 List<VarSymbol> locals = |
2603 List<VarSymbol> locals = lvtRanges |
2628 analyzer.lvtRanges |
2604 .getVars(currentMethod, currentTree); |
2629 .getVars(analyzer.currentMethod, currentTree); |
|
2630 locals = locals != null ? |
2605 locals = locals != null ? |
2631 locals : List.<VarSymbol>nil(); |
2606 locals : List.<VarSymbol>nil(); |
2632 for (JCVariableDecl vardecl : analyzer.vardecls) { |
2607 for (JCVariableDecl vardecl : vardecls) { |
2633 //once the first is null, the rest will be so. |
2608 //once the first is null, the rest will be so. |
2634 if (vardecl == null) { |
2609 if (vardecl == null) { |
2635 break; |
2610 break; |
2636 } |
2611 } |
2637 if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) { |
2612 if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) { |
2638 locals = locals.prepend(vardecl.sym); |
2613 locals = locals.prepend(vardecl.sym); |
2639 } |
2614 } |
2640 } |
2615 } |
2641 if (!locals.isEmpty()) { |
2616 if (!locals.isEmpty()) { |
2642 analyzer.lvtRanges.setEntry(analyzer.currentMethod, |
2617 lvtRanges.setEntry(currentMethod, |
2643 currentTree, locals); |
2618 currentTree, locals); |
2644 } |
2619 } |
2645 } |
2620 } |
2646 } |
2621 } |
2647 |
2622 |
2655 } |
2630 } |
2656 |
2631 |
2657 boolean trackVar(VarSymbol var) { |
2632 boolean trackVar(VarSymbol var) { |
2658 return (var.owner.kind == MTH && |
2633 return (var.owner.kind == MTH && |
2659 (var.flags() & PARAMETER) == 0 && |
2634 (var.flags() & PARAMETER) == 0 && |
2660 analyzer.trackable(var)); |
2635 trackable(var)); |
2661 } |
2636 } |
2662 |
2637 |
2663 boolean trackTree(JCTree tree) { |
2638 boolean trackTree(JCTree tree) { |
2664 switch (tree.getTag()) { |
2639 switch (tree.getTag()) { |
2665 // of course a method closes the alive range of a local variable. |
2640 // of course a method closes the alive range of a local variable. |
2671 return true; |
2646 return true; |
2672 } |
2647 } |
2673 |
2648 |
2674 } |
2649 } |
2675 |
2650 |
2676 public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit { |
2651 public class LVTAssignPendingExit extends |
|
2652 Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit { |
2677 |
2653 |
2678 LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { |
2654 LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { |
2679 super(tree, inits, uninits); |
2655 super(tree, inits, uninits); |
2680 } |
2656 } |
2681 |
2657 |
2684 lvtInits.at(tree); |
2660 lvtInits.at(tree); |
2685 super.resolveJump(tree); |
2661 super.resolveJump(tree); |
2686 } |
2662 } |
2687 } |
2663 } |
2688 |
2664 |
2689 private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) { |
2665 private LVTAssignAnalyzer() { |
2690 super(new LVTBits(), syms, names, false); |
2666 flow.super(); |
2691 lvtInits = (LVTBits)inits; |
2667 lvtInits = new LVTBits(); |
2692 this.lvtRanges = lvtRanges; |
2668 inits = lvtInits; |
2693 } |
|
2694 |
|
2695 public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) { |
|
2696 LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names); |
|
2697 result.lvtInits.analyzer = result; |
|
2698 return result; |
|
2699 } |
2669 } |
2700 |
2670 |
2701 @Override |
2671 @Override |
2702 protected void markDead(JCTree tree) { |
2672 protected void markDead(JCTree tree) { |
2703 lvtInits.at(tree).inclRange(returnadr, nextadr); |
2673 lvtInits.at(tree).inclRange(returnadr, nextadr); |