langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
changeset 26537 026471c1a12b
parent 26532 aa84b6606229
child 27120 8ed4ea81b048
equal deleted inserted replaced
26536:730984f89f90 26537:026471c1a12b
    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);