langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java
changeset 19941 8b91e8eb2d20
parent 19923 4895f15b3845
child 21010 5ffe0d8a5e24
equal deleted inserted replaced
19940:d6d6e623f0b4 19941:8b91e8eb2d20
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.javac.jvm;
    26 package com.sun.tools.javac.jvm;
       
    27 
    27 import java.util.*;
    28 import java.util.*;
    28 
    29 
    29 import com.sun.tools.javac.util.*;
    30 import com.sun.tools.javac.util.*;
    30 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    31 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    31 import com.sun.tools.javac.util.List;
    32 import com.sun.tools.javac.util.List;
    93         if (instance == null)
    94         if (instance == null)
    94             instance = new Gen(context);
    95             instance = new Gen(context);
    95         return instance;
    96         return instance;
    96     }
    97     }
    97 
    98 
    98     /* Constant pool, reset by genClass.
    99     /** Constant pool, reset by genClass.
    99      */
   100      */
   100     private Pool pool;
   101     private Pool pool;
       
   102 
       
   103     /** LVTRanges info.
       
   104      */
       
   105     private LVTRanges lvtRanges;
   101 
   106 
   102     protected Gen(Context context) {
   107     protected Gen(Context context) {
   103         context.put(genKey, this);
   108         context.put(genKey, this);
   104 
   109 
   105         names = Names.instance(context);
   110         names = Names.instance(context);
   126             options.isSet(G_CUSTOM, "lines");
   131             options.isSet(G_CUSTOM, "lines");
   127         varDebugInfo =
   132         varDebugInfo =
   128             options.isUnset(G_CUSTOM)
   133             options.isUnset(G_CUSTOM)
   129             ? options.isSet(G)
   134             ? options.isSet(G)
   130             : options.isSet(G_CUSTOM, "vars");
   135             : options.isSet(G_CUSTOM, "vars");
       
   136         if (varDebugInfo) {
       
   137             lvtRanges = LVTRanges.instance(context);
       
   138         }
   131         genCrt = options.isSet(XJCOV);
   139         genCrt = options.isSet(XJCOV);
   132         debugCode = options.isSet("debugcode");
   140         debugCode = options.isSet("debugcode");
   133         allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
   141         allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
   134         pool = new Pool(types);
   142         pool = new Pool(types);
   135 
   143 
   421      *  @param env   the environment which might contain the finalizer
   429      *  @param env   the environment which might contain the finalizer
   422      *               (if it does, env.info.gaps != null).
   430      *               (if it does, env.info.gaps != null).
   423      */
   431      */
   424     void endFinalizerGap(Env<GenContext> env) {
   432     void endFinalizerGap(Env<GenContext> env) {
   425         if (env.info.gaps != null && env.info.gaps.length() % 2 == 1)
   433         if (env.info.gaps != null && env.info.gaps.length() % 2 == 1)
   426             env.info.gaps.append(code.curPc());
   434             env.info.gaps.append(code.curCP());
   427     }
   435     }
   428 
   436 
   429     /** Mark end of all gaps in catch-all ranges for finalizers of environments
   437     /** Mark end of all gaps in catch-all ranges for finalizers of environments
   430      *  lying between, and including to two environments.
   438      *  lying between, and including to two environments.
   431      *  @param from    the most deeply nested environment to mark
   439      *  @param from    the most deeply nested environment to mark
   741     public void genStat(JCTree tree, Env<GenContext> env, int crtFlags) {
   749     public void genStat(JCTree tree, Env<GenContext> env, int crtFlags) {
   742         if (!genCrt) {
   750         if (!genCrt) {
   743             genStat(tree, env);
   751             genStat(tree, env);
   744             return;
   752             return;
   745         }
   753         }
   746         int startpc = code.curPc();
   754         int startpc = code.curCP();
   747         genStat(tree, env);
   755         genStat(tree, env);
   748         if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK;
   756         if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK;
   749         code.crt.put(tree, crtFlags, startpc, code.curPc());
   757         code.crt.put(tree, crtFlags, startpc, code.curCP());
   750     }
   758     }
   751 
   759 
   752     /** Derived visitor method: generate code for a statement.
   760     /** Derived visitor method: generate code for a statement.
   753      */
   761      */
   754     public void genStat(JCTree tree, Env<GenContext> env) {
   762     public void genStat(JCTree tree, Env<GenContext> env) {
   779             return;
   787             return;
   780         }
   788         }
   781         if (trees.length() == 1) {        // mark one statement with the flags
   789         if (trees.length() == 1) {        // mark one statement with the flags
   782             genStat(trees.head, env, crtFlags | CRT_STATEMENT);
   790             genStat(trees.head, env, crtFlags | CRT_STATEMENT);
   783         } else {
   791         } else {
   784             int startpc = code.curPc();
   792             int startpc = code.curCP();
   785             genStats(trees, env);
   793             genStats(trees, env);
   786             code.crt.put(trees, crtFlags, startpc, code.curPc());
   794             code.crt.put(trees, crtFlags, startpc, code.curCP());
   787         }
   795         }
   788     }
   796     }
   789 
   797 
   790     /** Derived visitor method: generate code for a list of statements.
   798     /** Derived visitor method: generate code for a list of statements.
   791      */
   799      */
   804      *  @param  crtFlags The CharacterRangeTable flags
   812      *  @param  crtFlags The CharacterRangeTable flags
   805      *                   indicating type of the entry.
   813      *                   indicating type of the entry.
   806      */
   814      */
   807     public CondItem genCond(JCTree tree, int crtFlags) {
   815     public CondItem genCond(JCTree tree, int crtFlags) {
   808         if (!genCrt) return genCond(tree, false);
   816         if (!genCrt) return genCond(tree, false);
   809         int startpc = code.curPc();
   817         int startpc = code.curCP();
   810         CondItem item = genCond(tree, (crtFlags & CRT_FLOW_CONTROLLER) != 0);
   818         CondItem item = genCond(tree, (crtFlags & CRT_FLOW_CONTROLLER) != 0);
   811         code.crt.put(tree, crtFlags, startpc, code.curPc());
   819         code.crt.put(tree, crtFlags, startpc, code.curCP());
   812         return item;
   820         return item;
   813     }
   821     }
   814 
   822 
   815     /** Derived visitor method: generate code for a boolean
   823     /** Derived visitor method: generate code for a boolean
   816      *  expression in a control-flow context.
   824      *  expression in a control-flow context.
   969     public void visitMethodDef(JCMethodDecl tree) {
   977     public void visitMethodDef(JCMethodDecl tree) {
   970         // Create a new local environment that points pack at method
   978         // Create a new local environment that points pack at method
   971         // definition.
   979         // definition.
   972         Env<GenContext> localEnv = env.dup(tree);
   980         Env<GenContext> localEnv = env.dup(tree);
   973         localEnv.enclMethod = tree;
   981         localEnv.enclMethod = tree;
   974 
       
   975         // The expected type of every return statement in this method
   982         // The expected type of every return statement in this method
   976         // is the method's return type.
   983         // is the method's return type.
   977         this.pt = tree.sym.erasure(types).getReturnType();
   984         this.pt = tree.sym.erasure(types).getReturnType();
   978 
   985 
   979         checkDimension(tree.pos(), tree.sym.erasure(types));
   986         checkDimension(tree.pos(), tree.sym.erasure(types));
  1043                 }
  1050                 }
  1044                 if (genCrt)
  1051                 if (genCrt)
  1045                     code.crt.put(tree.body,
  1052                     code.crt.put(tree.body,
  1046                                  CRT_BLOCK,
  1053                                  CRT_BLOCK,
  1047                                  startpcCrt,
  1054                                  startpcCrt,
  1048                                  code.curPc());
  1055                                  code.curCP());
  1049 
  1056 
  1050                 code.endScopes(0);
  1057                 code.endScopes(0);
  1051 
  1058 
  1052                 // If we exceeded limits, panic
  1059                 // If we exceeded limits, panic
  1053                 if (code.checkLimits(tree.pos(), log)) {
  1060                 if (code.checkLimits(tree.pos(), log)) {
  1085                                         debugCode,
  1092                                         debugCode,
  1086                                         genCrt ? new CRTable(tree, env.toplevel.endPositions)
  1093                                         genCrt ? new CRTable(tree, env.toplevel.endPositions)
  1087                                                : null,
  1094                                                : null,
  1088                                         syms,
  1095                                         syms,
  1089                                         types,
  1096                                         types,
  1090                                         pool);
  1097                                         pool,
       
  1098                                         varDebugInfo ? lvtRanges : null);
  1091             items = new Items(pool, code, syms, types);
  1099             items = new Items(pool, code, syms, types);
  1092             if (code.debugCode)
  1100             if (code.debugCode) {
  1093                 System.err.println(meth + " for body " + tree);
  1101                 System.err.println(meth + " for body " + tree);
       
  1102             }
  1094 
  1103 
  1095             // If method is not static, create a new local variable address
  1104             // If method is not static, create a new local variable address
  1096             // for `this'.
  1105             // for `this'.
  1097             if ((tree.mods.flags & STATIC) == 0) {
  1106             if ((tree.mods.flags & STATIC) == 0) {
  1098                 Type selfType = meth.owner.type;
  1107                 Type selfType = meth.owner.type;
  1109                 checkDimension(l.head.pos(), l.head.sym.type);
  1118                 checkDimension(l.head.pos(), l.head.sym.type);
  1110                 code.setDefined(code.newLocal(l.head.sym));
  1119                 code.setDefined(code.newLocal(l.head.sym));
  1111             }
  1120             }
  1112 
  1121 
  1113             // Get ready to generate code for method body.
  1122             // Get ready to generate code for method body.
  1114             int startpcCrt = genCrt ? code.curPc() : 0;
  1123             int startpcCrt = genCrt ? code.curCP() : 0;
  1115             code.entryPoint();
  1124             code.entryPoint();
  1116 
  1125 
  1117             // Suppress initial stackmap
  1126             // Suppress initial stackmap
  1118             code.pendingStackMap = false;
  1127             code.pendingStackMap = false;
  1119 
  1128 
  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.
  1276                 table_space_cost + 3 * table_time_cost <=
  1339                 table_space_cost + 3 * table_time_cost <=
  1277                 lookup_space_cost + 3 * lookup_time_cost
  1340                 lookup_space_cost + 3 * lookup_time_cost
  1278                 ?
  1341                 ?
  1279                 tableswitch : lookupswitch;
  1342                 tableswitch : lookupswitch;
  1280 
  1343 
  1281             int startpc = code.curPc();    // the position of the selector operation
  1344             int startpc = code.curCP();    // the position of the selector operation
  1282             code.emitop0(opcode);
  1345             code.emitop0(opcode);
  1283             code.align(4);
  1346             code.align(4);
  1284             int tableBase = code.curPc();  // the start of the jump table
  1347             int tableBase = code.curCP();  // the start of the jump table
  1285             int[] offsets = null;          // a table of offsets for a lookupswitch
  1348             int[] offsets = null;          // a table of offsets for a lookupswitch
  1286             code.emit4(-1);                // leave space for default offset
  1349             code.emit4(-1);                // leave space for default offset
  1287             if (opcode == tableswitch) {
  1350             if (opcode == tableswitch) {
  1288                 code.emit4(lo);            // minimum label
  1351                 code.emit4(lo);            // minimum label
  1289                 code.emit4(hi);            // maximum label
  1352                 code.emit4(hi);            // maximum label
  1321                     code.put4(tableBase, pc - startpc);
  1384                     code.put4(tableBase, pc - startpc);
  1322                 }
  1385                 }
  1323 
  1386 
  1324                 // Generate code for the statements in this case.
  1387                 // Generate code for the statements in this case.
  1325                 genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
  1388                 genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
       
  1389                 if (varDebugInfo && lvtRanges.containsKey(code.meth, c.stats.last())) {
       
  1390                     code.closeAliveRanges(c.stats.last());
       
  1391                 }
  1326             }
  1392             }
  1327 
  1393 
  1328             // Resolve all breaks.
  1394             // Resolve all breaks.
  1329             code.resolve(switchEnv.info.exit);
  1395             code.resolve(switchEnv.info.exit);
  1330 
  1396 
  1400         final Env<GenContext> syncEnv = env.dup(tree, new GenContext());
  1466         final Env<GenContext> syncEnv = env.dup(tree, new GenContext());
  1401         syncEnv.info.finalize = new GenFinalizer() {
  1467         syncEnv.info.finalize = new GenFinalizer() {
  1402             void gen() {
  1468             void gen() {
  1403                 genLast();
  1469                 genLast();
  1404                 Assert.check(syncEnv.info.gaps.length() % 2 == 0);
  1470                 Assert.check(syncEnv.info.gaps.length() % 2 == 0);
  1405                 syncEnv.info.gaps.append(code.curPc());
  1471                 syncEnv.info.gaps.append(code.curCP());
  1406             }
  1472             }
  1407             void genLast() {
  1473             void genLast() {
  1408                 if (code.isAlive()) {
  1474                 if (code.isAlive()) {
  1409                     lockVar.load();
  1475                     lockVar.load();
  1410                     code.emitop0(monitorexit);
  1476                     code.emitop0(monitorexit);
  1439                             new Chain(code.emitJump(jsr),
  1505                             new Chain(code.emitJump(jsr),
  1440                                       tryEnv.info.cont,
  1506                                       tryEnv.info.cont,
  1441                                       jsrState);
  1507                                       jsrState);
  1442                     }
  1508                     }
  1443                     Assert.check(tryEnv.info.gaps.length() % 2 == 0);
  1509                     Assert.check(tryEnv.info.gaps.length() % 2 == 0);
  1444                     tryEnv.info.gaps.append(code.curPc());
  1510                     tryEnv.info.gaps.append(code.curCP());
  1445                 } else {
  1511                 } else {
  1446                     Assert.check(tryEnv.info.gaps.length() % 2 == 0);
  1512                     Assert.check(tryEnv.info.gaps.length() % 2 == 0);
  1447                     tryEnv.info.gaps.append(code.curPc());
  1513                     tryEnv.info.gaps.append(code.curCP());
  1448                     genLast();
  1514                     genLast();
  1449                 }
  1515                 }
  1450             }
  1516             }
  1451             void genLast() {
  1517             void genLast() {
  1452                 if (tree.finalizer != null)
  1518                 if (tree.finalizer != null)
  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);
  1571                 while (gaps.nonEmpty()) {
  1640                 while (gaps.nonEmpty()) {
  1572                     for (JCExpression subCatch : subClauses) {
  1641                     for (JCExpression subCatch : subClauses) {
  1573                         int catchType = makeRef(tree.pos(), subCatch.type);
  1642                         int catchType = makeRef(tree.pos(), subCatch.type);
  1574                         int end = gaps.head.intValue();
  1643                         int end = gaps.head.intValue();
  1575                         registerCatch(tree.pos(),
  1644                         registerCatch(tree.pos(),
  1576                                       startpc,  end, code.curPc(),
  1645                                       startpc,  end, code.curCP(),
  1577                                       catchType);
  1646                                       catchType);
  1578                         if (subCatch.type.isAnnotated()) {
  1647                         if (subCatch.type.isAnnotated()) {
  1579                             // All compounds share the same position, simply update the
  1648                             // All compounds share the same position, simply update the
  1580                             // first one.
  1649                             // first one.
  1581                             subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
  1650                             subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
  1587                 }
  1656                 }
  1588                 if (startpc < endpc) {
  1657                 if (startpc < endpc) {
  1589                     for (JCExpression subCatch : subClauses) {
  1658                     for (JCExpression subCatch : subClauses) {
  1590                         int catchType = makeRef(tree.pos(), subCatch.type);
  1659                         int catchType = makeRef(tree.pos(), subCatch.type);
  1591                         registerCatch(tree.pos(),
  1660                         registerCatch(tree.pos(),
  1592                                       startpc, endpc, code.curPc(),
  1661                                       startpc, endpc, code.curCP(),
  1593                                       catchType);
  1662                                       catchType);
  1594                         if (subCatch.type.isAnnotated()) {
  1663                         if (subCatch.type.isAnnotated()) {
  1595                             // All compounds share the same position, simply update the
  1664                             // All compounds share the same position, simply update the
  1596                             // first one.
  1665                             // first one.
  1597                             subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
  1666                             subCatch.type.getAnnotationMirrors().head.position.type_index = catchType;
  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 }