src/share/classes/com/sun/tools/javac/jvm/Code.java

Thu, 02 Oct 2008 19:58:40 -0700

author
xdono
date
Thu, 02 Oct 2008 19:58:40 -0700
changeset 117
24a47c3062fe
parent 113
eff38cc97183
child 267
e2722bd43f3a
permissions
-rw-r--r--

6754988: Update copyright year
Summary: Update for files that have been modified starting July 2008
Reviewed-by: ohair, tbell

     1 /*
     2  * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javac.jvm;
    28 import com.sun.tools.javac.code.*;
    29 import com.sun.tools.javac.code.Symbol.*;
    30 import com.sun.tools.javac.util.*;
    31 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    33 import static com.sun.tools.javac.code.TypeTags.*;
    34 import static com.sun.tools.javac.jvm.ByteCodes.*;
    35 import static com.sun.tools.javac.jvm.UninitializedType.*;
    36 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
    38 /** An internal structure that corresponds to the code attribute of
    39  *  methods in a classfile. The class also provides some utility operations to
    40  *  generate bytecode instructions.
    41  *
    42  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    43  *  you write code that depends on this, you do so at your own risk.
    44  *  This code and its internal interfaces are subject to change or
    45  *  deletion without notice.</b>
    46  */
    47 public class Code {
    49     public final boolean debugCode;
    50     public final boolean needStackMap;
    52     public enum StackMapFormat {
    53         NONE,
    54         CLDC {
    55             Name getAttributeName(Names names) {
    56                 return names.StackMap;
    57             }
    58         },
    59         JSR202 {
    60             Name getAttributeName(Names names) {
    61                 return names.StackMapTable;
    62             }
    63         };
    64         Name getAttributeName(Names names) {
    65             return names.empty;
    66         }
    67     }
    69     final Types types;
    70     final Symtab syms;
    72 /*---------- classfile fields: --------------- */
    74     /** The maximum stack size.
    75      */
    76     public int max_stack = 0;
    78     /** The maximum number of local variable slots.
    79      */
    80     public int max_locals = 0;
    82     /** The code buffer.
    83      */
    84     public byte[] code = new byte[64];
    86     /** the current code pointer.
    87      */
    88     public int cp = 0;
    90     /** Check the code against VM spec limits; if
    91      *  problems report them and return true.
    92      */
    93     public boolean checkLimits(DiagnosticPosition pos, Log log) {
    94         if (cp > ClassFile.MAX_CODE) {
    95             log.error(pos, "limit.code");
    96             return true;
    97         }
    98         if (max_locals > ClassFile.MAX_LOCALS) {
    99             log.error(pos, "limit.locals");
   100             return true;
   101         }
   102         if (max_stack > ClassFile.MAX_STACK) {
   103             log.error(pos, "limit.stack");
   104             return true;
   105         }
   106         return false;
   107     }
   109     /** A buffer for expression catch data. Each enter is a vector
   110      *  of four unsigned shorts.
   111      */
   112     ListBuffer<char[]> catchInfo = new ListBuffer<char[]>();
   114     /** A buffer for line number information. Each entry is a vector
   115      *  of two unsigned shorts.
   116      */
   117     List<char[]> lineInfo = List.nil(); // handled in stack fashion
   119     /** The CharacterRangeTable
   120      */
   121     public CRTable crt;
   123 /*---------- internal fields: --------------- */
   125     /** Are we generating code with jumps >= 32K?
   126      */
   127     public boolean fatcode;
   129     /** Code generation enabled?
   130      */
   131     private boolean alive = true;
   133     /** The current machine state (registers and stack).
   134      */
   135     State state;
   137     /** Is it forbidden to compactify code, because something is
   138      *  pointing to current location?
   139      */
   140     private boolean fixedPc = false;
   142     /** The next available register.
   143      */
   144     public int nextreg = 0;
   146     /** A chain for jumps to be resolved before the next opcode is emitted.
   147      *  We do this lazily to avoid jumps to jumps.
   148      */
   149     Chain pendingJumps = null;
   151     /** The position of the currently statement, if we are at the
   152      *  start of this statement, NOPOS otherwise.
   153      *  We need this to emit line numbers lazily, which we need to do
   154      *  because of jump-to-jump optimization.
   155      */
   156     int pendingStatPos = Position.NOPOS;
   158     /** Set true when a stackMap is needed at the current PC. */
   159     boolean pendingStackMap = false;
   161     /** The stack map format to be generated. */
   162     StackMapFormat stackMap;
   164     /** Switch: emit variable debug info.
   165      */
   166     boolean varDebugInfo;
   168     /** Switch: emit line number info.
   169      */
   170     boolean lineDebugInfo;
   172     /** Emit line number info if map supplied
   173      */
   174     Position.LineMap lineMap;
   176     /** The constant pool of the current class.
   177      */
   178     final Pool pool;
   180     final MethodSymbol meth;
   182     /** Construct a code object, given the settings of the fatcode,
   183      *  debugging info switches and the CharacterRangeTable.
   184      */
   185     public Code(MethodSymbol meth,
   186                 boolean fatcode,
   187                 Position.LineMap lineMap,
   188                 boolean varDebugInfo,
   189                 StackMapFormat stackMap,
   190                 boolean debugCode,
   191                 CRTable crt,
   192                 Symtab syms,
   193                 Types types,
   194                 Pool pool) {
   195         this.meth = meth;
   196         this.fatcode = fatcode;
   197         this.lineMap = lineMap;
   198         this.lineDebugInfo = lineMap != null;
   199         this.varDebugInfo = varDebugInfo;
   200         this.crt = crt;
   201         this.syms = syms;
   202         this.types = types;
   203         this.debugCode = debugCode;
   204         this.stackMap = stackMap;
   205         switch (stackMap) {
   206         case CLDC:
   207         case JSR202:
   208             this.needStackMap = true;
   209             break;
   210         default:
   211             this.needStackMap = false;
   212         }
   213         state = new State();
   214         lvar = new LocalVar[20];
   215         this.pool = pool;
   216     }
   219 /* **************************************************************************
   220  * Typecodes & related stuff
   221  ****************************************************************************/
   223     /** Given a type, return its type code (used implicitly in the
   224      *  JVM architecture).
   225      */
   226     public static int typecode(Type type) {
   227         switch (type.tag) {
   228         case BYTE: return BYTEcode;
   229         case SHORT: return SHORTcode;
   230         case CHAR: return CHARcode;
   231         case INT: return INTcode;
   232         case LONG: return LONGcode;
   233         case FLOAT: return FLOATcode;
   234         case DOUBLE: return DOUBLEcode;
   235         case BOOLEAN: return BYTEcode;
   236         case VOID: return VOIDcode;
   237         case CLASS:
   238         case ARRAY:
   239         case METHOD:
   240         case BOT:
   241         case TYPEVAR:
   242         case UNINITIALIZED_THIS:
   243         case UNINITIALIZED_OBJECT:
   244             return OBJECTcode;
   245         default: throw new AssertionError("typecode " + type.tag);
   246         }
   247     }
   249     /** Collapse type code for subtypes of int to INTcode.
   250      */
   251     public static int truncate(int tc) {
   252         switch (tc) {
   253         case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
   254         default: return tc;
   255         }
   256     }
   258     /** The width in bytes of objects of the type.
   259      */
   260     public static int width(int typecode) {
   261         switch (typecode) {
   262         case LONGcode: case DOUBLEcode: return 2;
   263         case VOIDcode: return 0;
   264         default: return 1;
   265         }
   266     }
   268     public static int width(Type type) {
   269         return type == null ? 1 : width(typecode(type));
   270     }
   272     /** The total width taken up by a vector of objects.
   273      */
   274     public static int width(List<Type> types) {
   275         int w = 0;
   276         for (List<Type> l = types; l.nonEmpty(); l = l.tail)
   277             w = w + width(l.head);
   278         return w;
   279     }
   281     /** Given a type, return its code for allocating arrays of that type.
   282      */
   283     public static int arraycode(Type type) {
   284         switch (type.tag) {
   285         case BYTE: return 8;
   286         case BOOLEAN: return 4;
   287         case SHORT: return 9;
   288         case CHAR: return 5;
   289         case INT: return 10;
   290         case LONG: return 11;
   291         case FLOAT: return 6;
   292         case DOUBLE: return 7;
   293         case CLASS: return 0;
   294         case ARRAY: return 1;
   295         default: throw new AssertionError("arraycode " + type);
   296         }
   297     }
   300 /* **************************************************************************
   301  * Emit code
   302  ****************************************************************************/
   304     /** The current output code pointer.
   305      */
   306     public int curPc() {
   307         if (pendingJumps != null) resolvePending();
   308         if (pendingStatPos != Position.NOPOS) markStatBegin();
   309         fixedPc = true;
   310         return cp;
   311     }
   313     /** Emit a byte of code.
   314      */
   315     private  void emit1(int od) {
   316         if (!alive) return;
   317         if (cp == code.length) {
   318             byte[] newcode = new byte[cp * 2];
   319             System.arraycopy(code, 0, newcode, 0, cp);
   320             code = newcode;
   321         }
   322         code[cp++] = (byte)od;
   323     }
   325     /** Emit two bytes of code.
   326      */
   327     private void emit2(int od) {
   328         if (!alive) return;
   329         if (cp + 2 > code.length) {
   330             emit1(od >> 8);
   331             emit1(od);
   332         } else {
   333             code[cp++] = (byte)(od >> 8);
   334             code[cp++] = (byte)od;
   335         }
   336     }
   338     /** Emit four bytes of code.
   339      */
   340     public void emit4(int od) {
   341         if (!alive) return;
   342         if (cp + 4 > code.length) {
   343             emit1(od >> 24);
   344             emit1(od >> 16);
   345             emit1(od >> 8);
   346             emit1(od);
   347         } else {
   348             code[cp++] = (byte)(od >> 24);
   349             code[cp++] = (byte)(od >> 16);
   350             code[cp++] = (byte)(od >> 8);
   351             code[cp++] = (byte)od;
   352         }
   353     }
   355     /** Emit an opcode.
   356      */
   357     private void emitop(int op) {
   358         if (pendingJumps != null) resolvePending();
   359         if (alive) {
   360             if (pendingStatPos != Position.NOPOS)
   361                 markStatBegin();
   362             if (pendingStackMap) {
   363                 pendingStackMap = false;
   364                 emitStackMap();
   365             }
   366             if (debugCode)
   367                 System.err.println("emit@" + cp + " stack=" +
   368                                    state.stacksize + ": " +
   369                                    mnem(op));
   370             emit1(op);
   371         }
   372     }
   374     void postop() {
   375         assert alive || state.stacksize == 0;
   376     }
   378     /** Emit a multinewarray instruction.
   379      */
   380     public void emitMultianewarray(int ndims, int type, Type arrayType) {
   381         emitop(multianewarray);
   382         if (!alive) return;
   383         emit2(type);
   384         emit1(ndims);
   385         state.pop(ndims);
   386         state.push(arrayType);
   387     }
   389     /** Emit newarray.
   390      */
   391     public void emitNewarray(int elemcode, Type arrayType) {
   392         emitop(newarray);
   393         if (!alive) return;
   394         emit1(elemcode);
   395         state.pop(1); // count
   396         state.push(arrayType);
   397     }
   399     /** Emit anewarray.
   400      */
   401     public void emitAnewarray(int od, Type arrayType) {
   402         emitop(anewarray);
   403         if (!alive) return;
   404         emit2(od);
   405         state.pop(1);
   406         state.push(arrayType);
   407     }
   409     /** Emit an invokeinterface instruction.
   410      */
   411     public void emitInvokeinterface(int meth, Type mtype) {
   412         int argsize = width(mtype.getParameterTypes());
   413         emitop(invokeinterface);
   414         if (!alive) return;
   415         emit2(meth);
   416         emit1(argsize + 1);
   417         emit1(0);
   418         state.pop(argsize + 1);
   419         state.push(mtype.getReturnType());
   420     }
   422     /** Emit an invokespecial instruction.
   423      */
   424     public void emitInvokespecial(int meth, Type mtype) {
   425         int argsize = width(mtype.getParameterTypes());
   426         emitop(invokespecial);
   427         if (!alive) return;
   428         emit2(meth);
   429         Symbol sym = (Symbol)pool.pool[meth];
   430         state.pop(argsize);
   431         if (sym.isConstructor())
   432             state.markInitialized((UninitializedType)state.peek());
   433         state.pop(1);
   434         state.push(mtype.getReturnType());
   435     }
   437     /** Emit an invokestatic instruction.
   438      */
   439     public void emitInvokestatic(int meth, Type mtype) {
   440         int argsize = width(mtype.getParameterTypes());
   441         emitop(invokestatic);
   442         if (!alive) return;
   443         emit2(meth);
   444         state.pop(argsize);
   445         state.push(mtype.getReturnType());
   446     }
   448     /** Emit an invokevirtual instruction.
   449      */
   450     public void emitInvokevirtual(int meth, Type mtype) {
   451         int argsize = width(mtype.getParameterTypes());
   452         emitop(invokevirtual);
   453         if (!alive) return;
   454         emit2(meth);
   455         state.pop(argsize + 1);
   456         state.push(mtype.getReturnType());
   457     }
   459     /** Emit an opcode with no operand field.
   460      */
   461     public void emitop0(int op) {
   462         emitop(op);
   463         if (!alive) return;
   464         switch (op) {
   465         case aaload: {
   466             state.pop(1);// index
   467             Type a = state.stack[state.stacksize-1];
   468             state.pop(1);
   469             state.push(types.erasure(types.elemtype(a))); }
   470             break;
   471         case goto_:
   472             markDead();
   473             break;
   474         case nop:
   475         case ineg:
   476         case lneg:
   477         case fneg:
   478         case dneg:
   479             break;
   480         case aconst_null:
   481             state.push(syms.botType);
   482             break;
   483         case iconst_m1:
   484         case iconst_0:
   485         case iconst_1:
   486         case iconst_2:
   487         case iconst_3:
   488         case iconst_4:
   489         case iconst_5:
   490         case iload_0:
   491         case iload_1:
   492         case iload_2:
   493         case iload_3:
   494             state.push(syms.intType);
   495             break;
   496         case lconst_0:
   497         case lconst_1:
   498         case lload_0:
   499         case lload_1:
   500         case lload_2:
   501         case lload_3:
   502             state.push(syms.longType);
   503             break;
   504         case fconst_0:
   505         case fconst_1:
   506         case fconst_2:
   507         case fload_0:
   508         case fload_1:
   509         case fload_2:
   510         case fload_3:
   511             state.push(syms.floatType);
   512             break;
   513         case dconst_0:
   514         case dconst_1:
   515         case dload_0:
   516         case dload_1:
   517         case dload_2:
   518         case dload_3:
   519             state.push(syms.doubleType);
   520             break;
   521         case aload_0:
   522             state.push(lvar[0].sym.type);
   523             break;
   524         case aload_1:
   525             state.push(lvar[1].sym.type);
   526             break;
   527         case aload_2:
   528             state.push(lvar[2].sym.type);
   529             break;
   530         case aload_3:
   531             state.push(lvar[3].sym.type);
   532             break;
   533         case iaload:
   534         case baload:
   535         case caload:
   536         case saload:
   537             state.pop(2);
   538             state.push(syms.intType);
   539             break;
   540         case laload:
   541             state.pop(2);
   542             state.push(syms.longType);
   543             break;
   544         case faload:
   545             state.pop(2);
   546             state.push(syms.floatType);
   547             break;
   548         case daload:
   549             state.pop(2);
   550             state.push(syms.doubleType);
   551             break;
   552         case istore_0:
   553         case istore_1:
   554         case istore_2:
   555         case istore_3:
   556         case fstore_0:
   557         case fstore_1:
   558         case fstore_2:
   559         case fstore_3:
   560         case astore_0:
   561         case astore_1:
   562         case astore_2:
   563         case astore_3:
   564         case pop:
   565         case lshr:
   566         case lshl:
   567         case lushr:
   568             state.pop(1);
   569             break;
   570         case areturn:
   571         case ireturn:
   572         case freturn:
   573             assert state.nlocks == 0;
   574             state.pop(1);
   575             markDead();
   576             break;
   577         case athrow:
   578             state.pop(1);
   579             markDead();
   580             break;
   581         case lstore_0:
   582         case lstore_1:
   583         case lstore_2:
   584         case lstore_3:
   585         case dstore_0:
   586         case dstore_1:
   587         case dstore_2:
   588         case dstore_3:
   589         case pop2:
   590             state.pop(2);
   591             break;
   592         case lreturn:
   593         case dreturn:
   594             assert state.nlocks == 0;
   595             state.pop(2);
   596             markDead();
   597             break;
   598         case dup:
   599             state.push(state.stack[state.stacksize-1]);
   600             break;
   601         case return_:
   602             assert state.nlocks == 0;
   603             markDead();
   604             break;
   605         case arraylength:
   606             state.pop(1);
   607             state.push(syms.intType);
   608             break;
   609         case isub:
   610         case iadd:
   611         case imul:
   612         case idiv:
   613         case imod:
   614         case ishl:
   615         case ishr:
   616         case iushr:
   617         case iand:
   618         case ior:
   619         case ixor:
   620             state.pop(1);
   621             // state.pop(1);
   622             // state.push(syms.intType);
   623             break;
   624         case aastore:
   625             state.pop(3);
   626             break;
   627         case land:
   628         case lor:
   629         case lxor:
   630         case lmod:
   631         case ldiv:
   632         case lmul:
   633         case lsub:
   634         case ladd:
   635             state.pop(2);
   636             break;
   637         case lcmp:
   638             state.pop(4);
   639             state.push(syms.intType);
   640             break;
   641         case l2i:
   642             state.pop(2);
   643             state.push(syms.intType);
   644             break;
   645         case i2l:
   646             state.pop(1);
   647             state.push(syms.longType);
   648             break;
   649         case i2f:
   650             state.pop(1);
   651             state.push(syms.floatType);
   652             break;
   653         case i2d:
   654             state.pop(1);
   655             state.push(syms.doubleType);
   656             break;
   657         case l2f:
   658             state.pop(2);
   659             state.push(syms.floatType);
   660             break;
   661         case l2d:
   662             state.pop(2);
   663             state.push(syms.doubleType);
   664             break;
   665         case f2i:
   666             state.pop(1);
   667             state.push(syms.intType);
   668             break;
   669         case f2l:
   670             state.pop(1);
   671             state.push(syms.longType);
   672             break;
   673         case f2d:
   674             state.pop(1);
   675             state.push(syms.doubleType);
   676             break;
   677         case d2i:
   678             state.pop(2);
   679             state.push(syms.intType);
   680             break;
   681         case d2l:
   682             state.pop(2);
   683             state.push(syms.longType);
   684             break;
   685         case d2f:
   686             state.pop(2);
   687             state.push(syms.floatType);
   688             break;
   689         case tableswitch:
   690         case lookupswitch:
   691             state.pop(1);
   692             // the caller is responsible for patching up the state
   693             break;
   694         case dup_x1: {
   695             Type val1 = state.pop1();
   696             Type val2 = state.pop1();
   697             state.push(val1);
   698             state.push(val2);
   699             state.push(val1);
   700             break;
   701         }
   702         case bastore:
   703             state.pop(3);
   704             break;
   705         case int2byte:
   706         case int2char:
   707         case int2short:
   708             break;
   709         case fmul:
   710         case fadd:
   711         case fsub:
   712         case fdiv:
   713         case fmod:
   714             state.pop(1);
   715             break;
   716         case castore:
   717         case iastore:
   718         case fastore:
   719         case sastore:
   720             state.pop(3);
   721             break;
   722         case lastore:
   723         case dastore:
   724             state.pop(4);
   725             break;
   726         case dup2:
   727             if (state.stack[state.stacksize-1] != null) {
   728                 Type value1 = state.pop1();
   729                 Type value2 = state.pop1();
   730                 state.push(value2);
   731                 state.push(value1);
   732                 state.push(value2);
   733                 state.push(value1);
   734             } else {
   735                 Type value = state.pop2();
   736                 state.push(value);
   737                 state.push(value);
   738             }
   739             break;
   740         case dup2_x1:
   741             if (state.stack[state.stacksize-1] != null) {
   742                 Type value1 = state.pop1();
   743                 Type value2 = state.pop1();
   744                 Type value3 = state.pop1();
   745                 state.push(value2);
   746                 state.push(value1);
   747                 state.push(value3);
   748                 state.push(value2);
   749                 state.push(value1);
   750             } else {
   751                 Type value1 = state.pop2();
   752                 Type value2 = state.pop1();
   753                 state.push(value1);
   754                 state.push(value2);
   755                 state.push(value1);
   756             }
   757             break;
   758         case dup2_x2:
   759             if (state.stack[state.stacksize-1] != null) {
   760                 Type value1 = state.pop1();
   761                 Type value2 = state.pop1();
   762                 if (state.stack[state.stacksize-1] != null) {
   763                     // form 1
   764                     Type value3 = state.pop1();
   765                     Type value4 = state.pop1();
   766                     state.push(value2);
   767                     state.push(value1);
   768                     state.push(value4);
   769                     state.push(value3);
   770                     state.push(value2);
   771                     state.push(value1);
   772                 } else {
   773                     // form 3
   774                     Type value3 = state.pop2();
   775                     state.push(value2);
   776                     state.push(value1);
   777                     state.push(value3);
   778                     state.push(value2);
   779                     state.push(value1);
   780                 }
   781             } else {
   782                 Type value1 = state.pop2();
   783                 if (state.stack[state.stacksize-1] != null) {
   784                     // form 2
   785                     Type value2 = state.pop1();
   786                     Type value3 = state.pop1();
   787                     state.push(value1);
   788                     state.push(value3);
   789                     state.push(value2);
   790                     state.push(value1);
   791                 } else {
   792                     // form 4
   793                     Type value2 = state.pop2();
   794                     state.push(value1);
   795                     state.push(value2);
   796                     state.push(value1);
   797                 }
   798             }
   799             break;
   800         case dup_x2: {
   801             Type value1 = state.pop1();
   802             if (state.stack[state.stacksize-1] != null) {
   803                 // form 1
   804                 Type value2 = state.pop1();
   805                 Type value3 = state.pop1();
   806                 state.push(value1);
   807                 state.push(value3);
   808                 state.push(value2);
   809                 state.push(value1);
   810             } else {
   811                 // form 2
   812                 Type value2 = state.pop2();
   813                 state.push(value1);
   814                 state.push(value2);
   815                 state.push(value1);
   816             }
   817         }
   818             break;
   819         case fcmpl:
   820         case fcmpg:
   821             state.pop(2);
   822             state.push(syms.intType);
   823             break;
   824         case dcmpl:
   825         case dcmpg:
   826             state.pop(4);
   827             state.push(syms.intType);
   828             break;
   829         case swap: {
   830             Type value1 = state.pop1();
   831             Type value2 = state.pop1();
   832             state.push(value1);
   833             state.push(value2);
   834             break;
   835         }
   836         case dadd:
   837         case dsub:
   838         case dmul:
   839         case ddiv:
   840         case dmod:
   841             state.pop(2);
   842             break;
   843         case ret:
   844             markDead();
   845             break;
   846         case wide:
   847             // must be handled by the caller.
   848             return;
   849         case monitorenter:
   850         case monitorexit:
   851             state.pop(1);
   852             break;
   854         default:
   855             throw new AssertionError(mnem(op));
   856         }
   857         postop();
   858     }
   860     /** Emit an opcode with a one-byte operand field.
   861      */
   862     public void emitop1(int op, int od) {
   863         emitop(op);
   864         if (!alive) return;
   865         emit1(od);
   866         switch (op) {
   867         case bipush:
   868             state.push(syms.intType);
   869             break;
   870         case ldc1:
   871             state.push(typeForPool(pool.pool[od]));
   872             break;
   873         default:
   874             throw new AssertionError(mnem(op));
   875         }
   876         postop();
   877     }
   879     /** The type of a constant pool entry. */
   880     private Type typeForPool(Object o) {
   881         if (o instanceof Integer) return syms.intType;
   882         if (o instanceof Float) return syms.floatType;
   883         if (o instanceof String) return syms.stringType;
   884         if (o instanceof Long) return syms.longType;
   885         if (o instanceof Double) return syms.doubleType;
   886         if (o instanceof ClassSymbol) return syms.classType;
   887         if (o instanceof Type.ArrayType) return syms.classType;
   888         throw new AssertionError(o);
   889     }
   891     /** Emit an opcode with a one-byte operand field;
   892      *  widen if field does not fit in a byte.
   893      */
   894     public void emitop1w(int op, int od) {
   895         if (od > 0xFF) {
   896             emitop(wide);
   897             emitop(op);
   898             emit2(od);
   899         } else {
   900             emitop(op);
   901             emit1(od);
   902         }
   903         if (!alive) return;
   904         switch (op) {
   905         case iload:
   906             state.push(syms.intType);
   907             break;
   908         case lload:
   909             state.push(syms.longType);
   910             break;
   911         case fload:
   912             state.push(syms.floatType);
   913             break;
   914         case dload:
   915             state.push(syms.doubleType);
   916             break;
   917         case aload:
   918             state.push(lvar[od].sym.type);
   919             break;
   920         case lstore:
   921         case dstore:
   922             state.pop(2);
   923             break;
   924         case istore:
   925         case fstore:
   926         case astore:
   927             state.pop(1);
   928             break;
   929         case ret:
   930             markDead();
   931             break;
   932         default:
   933             throw new AssertionError(mnem(op));
   934         }
   935         postop();
   936     }
   938     /** Emit an opcode with two one-byte operand fields;
   939      *  widen if either field does not fit in a byte.
   940      */
   941     public void emitop1w(int op, int od1, int od2) {
   942         if (od1 > 0xFF || od2 < -128 || od2 > 127) {
   943             emitop(wide);
   944             emitop(op);
   945             emit2(od1);
   946             emit2(od2);
   947         } else {
   948             emitop(op);
   949             emit1(od1);
   950             emit1(od2);
   951         }
   952         if (!alive) return;
   953         switch (op) {
   954         case iinc:
   955             break;
   956         default:
   957             throw new AssertionError(mnem(op));
   958         }
   959     }
   961     /** Emit an opcode with a two-byte operand field.
   962      */
   963     public void emitop2(int op, int od) {
   964         emitop(op);
   965         if (!alive) return;
   966         emit2(od);
   967         switch (op) {
   968         case getstatic:
   969             state.push(((Symbol)(pool.pool[od])).erasure(types));
   970             break;
   971         case putstatic:
   972             state.pop(((Symbol)(pool.pool[od])).erasure(types));
   973             break;
   974         case new_:
   975             state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
   976             break;
   977         case sipush:
   978             state.push(syms.intType);
   979             break;
   980         case if_acmp_null:
   981         case if_acmp_nonnull:
   982         case ifeq:
   983         case ifne:
   984         case iflt:
   985         case ifge:
   986         case ifgt:
   987         case ifle:
   988             state.pop(1);
   989             break;
   990         case if_icmpeq:
   991         case if_icmpne:
   992         case if_icmplt:
   993         case if_icmpge:
   994         case if_icmpgt:
   995         case if_icmple:
   996         case if_acmpeq:
   997         case if_acmpne:
   998             state.pop(2);
   999             break;
  1000         case goto_:
  1001             markDead();
  1002             break;
  1003         case putfield:
  1004             state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1005             state.pop(1); // object ref
  1006             break;
  1007         case getfield:
  1008             state.pop(1); // object ref
  1009             state.push(((Symbol)(pool.pool[od])).erasure(types));
  1010             break;
  1011         case checkcast: {
  1012             state.pop(1); // object ref
  1013             Object o = pool.pool[od];
  1014             Type t = (o instanceof Symbol)
  1015                 ? ((Symbol)o).erasure(types)
  1016                 : types.erasure(((Type)o));
  1017             state.push(t);
  1018             break; }
  1019         case ldc2w:
  1020             state.push(typeForPool(pool.pool[od]));
  1021             break;
  1022         case instanceof_:
  1023             state.pop(1);
  1024             state.push(syms.intType);
  1025             break;
  1026         case ldc2:
  1027             state.push(typeForPool(pool.pool[od]));
  1028             break;
  1029         case jsr:
  1030             break;
  1031         default:
  1032             throw new AssertionError(mnem(op));
  1034         // postop();
  1037     /** Emit an opcode with a four-byte operand field.
  1038      */
  1039     public void emitop4(int op, int od) {
  1040         emitop(op);
  1041         if (!alive) return;
  1042         emit4(od);
  1043         switch (op) {
  1044         case goto_w:
  1045             markDead();
  1046             break;
  1047         case jsr_w:
  1048             break;
  1049         default:
  1050             throw new AssertionError(mnem(op));
  1052         // postop();
  1055     /** Align code pointer to next `incr' boundary.
  1056      */
  1057     public void align(int incr) {
  1058         if (alive)
  1059             while (cp % incr != 0) emitop0(nop);
  1062     /** Place a byte into code at address pc. Pre: pc + 1 <= cp.
  1063      */
  1064     private void put1(int pc, int op) {
  1065         code[pc] = (byte)op;
  1068     /** Place two bytes into code at address pc. Pre: pc + 2 <= cp.
  1069      */
  1070     private void put2(int pc, int od) {
  1071         // pre: pc + 2 <= cp
  1072         put1(pc, od >> 8);
  1073         put1(pc+1, od);
  1076     /** Place four  bytes into code at address pc. Pre: pc + 4 <= cp.
  1077      */
  1078     public void put4(int pc, int od) {
  1079         // pre: pc + 4 <= cp
  1080         put1(pc  , od >> 24);
  1081         put1(pc+1, od >> 16);
  1082         put1(pc+2, od >> 8);
  1083         put1(pc+3, od);
  1086     /** Return code byte at position pc as an unsigned int.
  1087      */
  1088     private int get1(int pc) {
  1089         return code[pc] & 0xFF;
  1092     /** Return two code bytes at position pc as an unsigned int.
  1093      */
  1094     private int get2(int pc) {
  1095         return (get1(pc) << 8) | get1(pc+1);
  1098     /** Return four code bytes at position pc as an int.
  1099      */
  1100     public int get4(int pc) {
  1101         // pre: pc + 4 <= cp
  1102         return
  1103             (get1(pc) << 24) |
  1104             (get1(pc+1) << 16) |
  1105             (get1(pc+2) << 8) |
  1106             (get1(pc+3));
  1109     /** Is code generation currently enabled?
  1110      */
  1111     public boolean isAlive() {
  1112         return alive || pendingJumps != null;
  1115     /** Switch code generation on/off.
  1116      */
  1117     public void markDead() {
  1118         alive = false;
  1121     /** Declare an entry point; return current code pointer
  1122      */
  1123     public int entryPoint() {
  1124         int pc = curPc();
  1125         alive = true;
  1126         pendingStackMap = needStackMap;
  1127         return pc;
  1130     /** Declare an entry point with initial state;
  1131      *  return current code pointer
  1132      */
  1133     public int entryPoint(State state) {
  1134         int pc = curPc();
  1135         alive = true;
  1136         this.state = state.dup();
  1137         assert state.stacksize <= max_stack;
  1138         if (debugCode) System.err.println("entry point " + state);
  1139         pendingStackMap = needStackMap;
  1140         return pc;
  1143     /** Declare an entry point with initial state plus a pushed value;
  1144      *  return current code pointer
  1145      */
  1146     public int entryPoint(State state, Type pushed) {
  1147         int pc = curPc();
  1148         alive = true;
  1149         this.state = state.dup();
  1150         assert state.stacksize <= max_stack;
  1151         this.state.push(pushed);
  1152         if (debugCode) System.err.println("entry point " + state);
  1153         pendingStackMap = needStackMap;
  1154         return pc;
  1158 /**************************************************************************
  1159  * Stack map generation
  1160  *************************************************************************/
  1162     /** An entry in the stack map. */
  1163     static class StackMapFrame {
  1164         int pc;
  1165         Type[] locals;
  1166         Type[] stack;
  1169     /** A buffer of cldc stack map entries. */
  1170     StackMapFrame[] stackMapBuffer = null;
  1172     /** A buffer of compressed StackMapTable entries. */
  1173     StackMapTableFrame[] stackMapTableBuffer = null;
  1174     int stackMapBufferSize = 0;
  1176     /** The last PC at which we generated a stack map. */
  1177     int lastStackMapPC = -1;
  1179     /** The last stack map frame in StackMapTable. */
  1180     StackMapFrame lastFrame = null;
  1182     /** The stack map frame before the last one. */
  1183     StackMapFrame frameBeforeLast = null;
  1185     /** Emit a stack map entry.  */
  1186     public void emitStackMap() {
  1187         int pc = curPc();
  1188         if (!needStackMap) return;
  1192         switch (stackMap) {
  1193             case CLDC:
  1194                 emitCLDCStackMap(pc, getLocalsSize());
  1195                 break;
  1196             case JSR202:
  1197                 emitStackMapFrame(pc, getLocalsSize());
  1198                 break;
  1199             default:
  1200                 throw new AssertionError("Should have chosen a stackmap format");
  1202         // DEBUG code follows
  1203         if (debugCode) state.dump(pc);
  1206     private int getLocalsSize() {
  1207         int nextLocal = 0;
  1208         for (int i=max_locals-1; i>=0; i--) {
  1209             if (state.defined.isMember(i) && lvar[i] != null) {
  1210                 nextLocal = i + width(lvar[i].sym.erasure(types));
  1211                 break;
  1214         return nextLocal;
  1217     /** Emit a CLDC stack map frame. */
  1218     void emitCLDCStackMap(int pc, int localsSize) {
  1219         if (lastStackMapPC == pc) {
  1220             // drop existing stackmap at this offset
  1221             stackMapBuffer[--stackMapBufferSize] = null;
  1223         lastStackMapPC = pc;
  1225         if (stackMapBuffer == null) {
  1226             stackMapBuffer = new StackMapFrame[20];
  1227         } else if (stackMapBuffer.length == stackMapBufferSize) {
  1228             StackMapFrame[] newStackMapBuffer =
  1229                 new StackMapFrame[stackMapBufferSize << 1];
  1230             System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,
  1231                              0, stackMapBufferSize);
  1232             stackMapBuffer = newStackMapBuffer;
  1234         StackMapFrame frame =
  1235             stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
  1236         frame.pc = pc;
  1238         frame.locals = new Type[localsSize];
  1239         for (int i=0; i<localsSize; i++) {
  1240             if (state.defined.isMember(i) && lvar[i] != null) {
  1241                 Type vtype = lvar[i].sym.type;
  1242                 if (!(vtype instanceof UninitializedType))
  1243                     vtype = types.erasure(vtype);
  1244                 frame.locals[i] = vtype;
  1247         frame.stack = new Type[state.stacksize];
  1248         for (int i=0; i<state.stacksize; i++)
  1249             frame.stack[i] = state.stack[i];
  1252     void emitStackMapFrame(int pc, int localsSize) {
  1253         if (lastFrame == null) {
  1254             // first frame
  1255             lastFrame = getInitialFrame();
  1256         } else if (lastFrame.pc == pc) {
  1257             // drop existing stackmap at this offset
  1258             stackMapTableBuffer[--stackMapBufferSize] = null;
  1259             lastFrame = frameBeforeLast;
  1260             frameBeforeLast = null;
  1263         StackMapFrame frame = new StackMapFrame();
  1264         frame.pc = pc;
  1266         int localCount = 0;
  1267         Type[] locals = new Type[localsSize];
  1268         for (int i=0; i<localsSize; i++, localCount++) {
  1269             if (state.defined.isMember(i) && lvar[i] != null) {
  1270                 Type vtype = lvar[i].sym.type;
  1271                 if (!(vtype instanceof UninitializedType))
  1272                     vtype = types.erasure(vtype);
  1273                 locals[i] = vtype;
  1274                 if (width(vtype) > 1) i++;
  1277         frame.locals = new Type[localCount];
  1278         for (int i=0, j=0; i<localsSize; i++, j++) {
  1279             assert(j < localCount);
  1280             frame.locals[j] = locals[i];
  1281             if (width(locals[i]) > 1) i++;
  1284         int stackCount = 0;
  1285         for (int i=0; i<state.stacksize; i++) {
  1286             if (state.stack[i] != null) {
  1287                 stackCount++;
  1290         frame.stack = new Type[stackCount];
  1291         stackCount = 0;
  1292         for (int i=0; i<state.stacksize; i++) {
  1293             if (state.stack[i] != null) {
  1294                 frame.stack[stackCount++] = state.stack[i];
  1298         if (stackMapTableBuffer == null) {
  1299             stackMapTableBuffer = new StackMapTableFrame[20];
  1300         } else if (stackMapTableBuffer.length == stackMapBufferSize) {
  1301             StackMapTableFrame[] newStackMapTableBuffer =
  1302                 new StackMapTableFrame[stackMapBufferSize << 1];
  1303             System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,
  1304                              0, stackMapBufferSize);
  1305             stackMapTableBuffer = newStackMapTableBuffer;
  1307         stackMapTableBuffer[stackMapBufferSize++] =
  1308                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
  1310         frameBeforeLast = lastFrame;
  1311         lastFrame = frame;
  1314     StackMapFrame getInitialFrame() {
  1315         StackMapFrame frame = new StackMapFrame();
  1316         List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
  1317         int len = arg_types.length();
  1318         int count = 0;
  1319         if (!meth.isStatic()) {
  1320             Type thisType = meth.owner.type;
  1321             frame.locals = new Type[len+1];
  1322             if (meth.isConstructor() && thisType != syms.objectType) {
  1323                 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
  1324             } else {
  1325                 frame.locals[count++] = types.erasure(thisType);
  1327         } else {
  1328             frame.locals = new Type[len];
  1330         for (Type arg_type : arg_types) {
  1331             frame.locals[count++] = types.erasure(arg_type);
  1333         frame.pc = -1;
  1334         frame.stack = null;
  1335         return frame;
  1339 /**************************************************************************
  1340  * Operations having to do with jumps
  1341  *************************************************************************/
  1343     /** A chain represents a list of unresolved jumps. Jump locations
  1344      *  are sorted in decreasing order.
  1345      */
  1346     public static class Chain {
  1348         /** The position of the jump instruction.
  1349          */
  1350         public final int pc;
  1352         /** The machine state after the jump instruction.
  1353          *  Invariant: all elements of a chain list have the same stacksize
  1354          *  and compatible stack and register contents.
  1355          */
  1356         Code.State state;
  1358         /** The next jump in the list.
  1359          */
  1360         public final Chain next;
  1362         /** Construct a chain from its jump position, stacksize, previous
  1363          *  chain, and machine state.
  1364          */
  1365         public Chain(int pc, Chain next, Code.State state) {
  1366             this.pc = pc;
  1367             this.next = next;
  1368             this.state = state;
  1372     /** Negate a branch opcode.
  1373      */
  1374     public static int negate(int opcode) {
  1375         if (opcode == if_acmp_null) return if_acmp_nonnull;
  1376         else if (opcode == if_acmp_nonnull) return if_acmp_null;
  1377         else return ((opcode + 1) ^ 1) - 1;
  1380     /** Emit a jump instruction.
  1381      *  Return code pointer of instruction to be patched.
  1382      */
  1383     public int emitJump(int opcode) {
  1384         if (fatcode) {
  1385             if (opcode == goto_ || opcode == jsr) {
  1386                 emitop4(opcode + goto_w - goto_, 0);
  1387             } else {
  1388                 emitop2(negate(opcode), 8);
  1389                 emitop4(goto_w, 0);
  1390                 alive = true;
  1391                 pendingStackMap = needStackMap;
  1393             return cp - 5;
  1394         } else {
  1395             emitop2(opcode, 0);
  1396             return cp - 3;
  1400     /** Emit a branch with given opcode; return its chain.
  1401      *  branch differs from jump in that jsr is treated as no-op.
  1402      */
  1403     public Chain branch(int opcode) {
  1404         Chain result = null;
  1405         if (opcode == goto_) {
  1406             result = pendingJumps;
  1407             pendingJumps = null;
  1409         if (opcode != dontgoto && isAlive()) {
  1410             result = new Chain(emitJump(opcode),
  1411                                result,
  1412                                state.dup());
  1413             fixedPc = fatcode;
  1414             if (opcode == goto_) alive = false;
  1416         return result;
  1419     /** Resolve chain to point to given target.
  1420      */
  1421     public void resolve(Chain chain, int target) {
  1422         boolean changed = false;
  1423         State newState = state;
  1424         for (; chain != null; chain = chain.next) {
  1425             assert state != chain.state;
  1426             assert target > chain.pc || state.stacksize == 0;
  1427             if (target >= cp) {
  1428                 target = cp;
  1429             } else if (get1(target) == goto_) {
  1430                 if (fatcode) target = target + get4(target + 1);
  1431                 else target = target + get2(target + 1);
  1433             if (get1(chain.pc) == goto_ &&
  1434                 chain.pc + 3 == target && target == cp && !fixedPc) {
  1435                 // If goto the next instruction, the jump is not needed:
  1436                 // compact the code.
  1437                 cp = cp - 3;
  1438                 target = target - 3;
  1439                 if (chain.next == null) {
  1440                     // This is the only jump to the target. Exit the loop
  1441                     // without setting new state. The code is reachable
  1442                     // from the instruction before goto_.
  1443                     alive = true;
  1444                     break;
  1446             } else {
  1447                 if (fatcode)
  1448                     put4(chain.pc + 1, target - chain.pc);
  1449                 else if (target - chain.pc < Short.MIN_VALUE ||
  1450                          target - chain.pc > Short.MAX_VALUE)
  1451                     fatcode = true;
  1452                 else
  1453                     put2(chain.pc + 1, target - chain.pc);
  1454                 assert !alive ||
  1455                     chain.state.stacksize == newState.stacksize &&
  1456                     chain.state.nlocks == newState.nlocks;
  1458             fixedPc = true;
  1459             if (cp == target) {
  1460                 changed = true;
  1461                 if (debugCode)
  1462                     System.err.println("resolving chain state=" + chain.state);
  1463                 if (alive) {
  1464                     newState = chain.state.join(newState);
  1465                 } else {
  1466                     newState = chain.state;
  1467                     alive = true;
  1471         assert !changed || state != newState;
  1472         if (state != newState) {
  1473             setDefined(newState.defined);
  1474             state = newState;
  1475             pendingStackMap = needStackMap;
  1479     /** Resolve chain to point to current code pointer.
  1480      */
  1481     public void resolve(Chain chain) {
  1482         assert
  1483             !alive ||
  1484             chain==null ||
  1485             state.stacksize == chain.state.stacksize &&
  1486             state.nlocks == chain.state.nlocks;
  1487         pendingJumps = mergeChains(chain, pendingJumps);
  1490     /** Resolve any pending jumps.
  1491      */
  1492     public void resolvePending() {
  1493         Chain x = pendingJumps;
  1494         pendingJumps = null;
  1495         resolve(x, cp);
  1498     /** Merge the jumps in of two chains into one.
  1499      */
  1500     public static Chain mergeChains(Chain chain1, Chain chain2) {
  1501         // recursive merge sort
  1502         if (chain2 == null) return chain1;
  1503         if (chain1 == null) return chain2;
  1504         assert
  1505             chain1.state.stacksize == chain2.state.stacksize &&
  1506             chain1.state.nlocks == chain2.state.nlocks;
  1507         if (chain1.pc < chain2.pc)
  1508             return new Chain(
  1509                 chain2.pc,
  1510                 mergeChains(chain1, chain2.next),
  1511                 chain2.state);
  1512         return new Chain(
  1513                 chain1.pc,
  1514                 mergeChains(chain1.next, chain2),
  1515                 chain1.state);
  1519 /* **************************************************************************
  1520  * Catch clauses
  1521  ****************************************************************************/
  1523     /** Add a catch clause to code.
  1524      */
  1525     public void addCatch(
  1526         char startPc, char endPc, char handlerPc, char catchType) {
  1527         catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
  1531 /* **************************************************************************
  1532  * Line numbers
  1533  ****************************************************************************/
  1535     /** Add a line number entry.
  1536      */
  1537     public void addLineNumber(char startPc, char lineNumber) {
  1538         if (lineDebugInfo) {
  1539             if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
  1540                 lineInfo = lineInfo.tail;
  1541             if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
  1542                 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
  1546     /** Mark beginning of statement.
  1547      */
  1548     public void statBegin(int pos) {
  1549         if (pos != Position.NOPOS) {
  1550             pendingStatPos = pos;
  1554     /** Force stat begin eagerly
  1555      */
  1556     public void markStatBegin() {
  1557         if (alive && lineDebugInfo) {
  1558             int line = lineMap.getLineNumber(pendingStatPos);
  1559             char cp1 = (char)cp;
  1560             char line1 = (char)line;
  1561             if (cp1 == cp && line1 == line)
  1562                 addLineNumber(cp1, line1);
  1564         pendingStatPos = Position.NOPOS;
  1568 /* **************************************************************************
  1569  * Simulated VM machine state
  1570  ****************************************************************************/
  1572     class State implements Cloneable {
  1573         /** The set of registers containing values. */
  1574         Bits defined;
  1576         /** The (types of the) contents of the machine stack. */
  1577         Type[] stack;
  1579         /** The first stack position currently unused. */
  1580         int stacksize;
  1582         /** The numbers of registers containing locked monitors. */
  1583         int[] locks;
  1584         int nlocks;
  1586         State() {
  1587             defined = new Bits();
  1588             stack = new Type[16];
  1591         State dup() {
  1592             try {
  1593                 State state = (State)super.clone();
  1594                 state.defined = defined.dup();
  1595                 state.stack = stack.clone();
  1596                 if (locks != null) state.locks = locks.clone();
  1597                 if (debugCode) {
  1598                     System.err.println("duping state " + this);
  1599                     dump();
  1601                 return state;
  1602             } catch (CloneNotSupportedException ex) {
  1603                 throw new AssertionError(ex);
  1607         void lock(int register) {
  1608             if (locks == null) {
  1609                 locks = new int[20];
  1610             } else if (locks.length == nlocks) {
  1611                 int[] newLocks = new int[locks.length << 1];
  1612                 System.arraycopy(locks, 0, newLocks, 0, locks.length);
  1613                 locks = newLocks;
  1615             locks[nlocks] = register;
  1616             nlocks++;
  1619         void unlock(int register) {
  1620             nlocks--;
  1621             assert locks[nlocks] == register;
  1622             locks[nlocks] = -1;
  1625         void push(Type t) {
  1626             if (debugCode) System.err.println("   pushing " + t);
  1627             switch (t.tag) {
  1628             case TypeTags.VOID:
  1629                 return;
  1630             case TypeTags.BYTE:
  1631             case TypeTags.CHAR:
  1632             case TypeTags.SHORT:
  1633             case TypeTags.BOOLEAN:
  1634                 t = syms.intType;
  1635                 break;
  1636             default:
  1637                 break;
  1639             if (stacksize+2 >= stack.length) {
  1640                 Type[] newstack = new Type[2*stack.length];
  1641                 System.arraycopy(stack, 0, newstack, 0, stack.length);
  1642                 stack = newstack;
  1644             stack[stacksize++] = t;
  1645             switch (width(t)) {
  1646             case 1:
  1647                 break;
  1648             case 2:
  1649                 stack[stacksize++] = null;
  1650                 break;
  1651             default:
  1652                 throw new AssertionError(t);
  1654             if (stacksize > max_stack)
  1655                 max_stack = stacksize;
  1658         Type pop1() {
  1659             if (debugCode) System.err.println("   popping " + 1);
  1660             stacksize--;
  1661             Type result = stack[stacksize];
  1662             stack[stacksize] = null;
  1663             assert result != null && width(result) == 1;
  1664             return result;
  1667         Type peek() {
  1668             return stack[stacksize-1];
  1671         Type pop2() {
  1672             if (debugCode) System.err.println("   popping " + 2);
  1673             stacksize -= 2;
  1674             Type result = stack[stacksize];
  1675             stack[stacksize] = null;
  1676             assert stack[stacksize+1] == null;
  1677             assert result != null && width(result) == 2;
  1678             return result;
  1681         void pop(int n) {
  1682             if (debugCode) System.err.println("   popping " + n);
  1683             while (n > 0) {
  1684                 stack[--stacksize] = null;
  1685                 n--;
  1689         void pop(Type t) {
  1690             pop(width(t));
  1693         /** Force the top of the stack to be treated as this supertype
  1694          *  of its current type. */
  1695         void forceStackTop(Type t) {
  1696             if (!alive) return;
  1697             switch (t.tag) {
  1698             case CLASS:
  1699             case ARRAY:
  1700                 int width = width(t);
  1701                 Type old = stack[stacksize-width];
  1702                 assert types.isSubtype(types.erasure(old),
  1703                                        types.erasure(t));
  1704                 stack[stacksize-width] = t;
  1705                 break;
  1706             default:
  1710         void markInitialized(UninitializedType old) {
  1711             Type newtype = old.initializedType();
  1712             for (int i=0; i<stacksize; i++)
  1713                 if (stack[i] == old) stack[i] = newtype;
  1714             for (int i=0; i<lvar.length; i++) {
  1715                 LocalVar lv = lvar[i];
  1716                 if (lv != null && lv.sym.type == old) {
  1717                     VarSymbol sym = lv.sym;
  1718                     sym = sym.clone(sym.owner);
  1719                     sym.type = newtype;
  1720                     LocalVar newlv = lvar[i] = new LocalVar(sym);
  1721                     // should the following be initialized to cp?
  1722                     newlv.start_pc = lv.start_pc;
  1727         State join(State other) {
  1728             defined = defined.andSet(other.defined);
  1729             assert stacksize == other.stacksize;
  1730             assert nlocks == other.nlocks;
  1731             for (int i=0; i<stacksize; ) {
  1732                 Type t = stack[i];
  1733                 Type tother = other.stack[i];
  1734                 Type result =
  1735                     t==tother ? t :
  1736                     types.isSubtype(t, tother) ? tother :
  1737                     types.isSubtype(tother, t) ? t :
  1738                     error();
  1739                 int w = width(result);
  1740                 stack[i] = result;
  1741                 if (w == 2) assert stack[i+1] == null;
  1742                 i += w;
  1744             return this;
  1747         Type error() {
  1748             throw new AssertionError("inconsistent stack types at join point");
  1751         void dump() {
  1752             dump(-1);
  1755         void dump(int pc) {
  1756             System.err.print("stackMap for " + meth.owner + "." + meth);
  1757             if (pc == -1)
  1758                 System.out.println();
  1759             else
  1760                 System.out.println(" at " + pc);
  1761             System.err.println(" stack (from bottom):");
  1762             for (int i=0; i<stacksize; i++)
  1763                 System.err.println("  " + i + ": " + stack[i]);
  1765             int lastLocal = 0;
  1766             for (int i=max_locals-1; i>=0; i--) {
  1767                 if (defined.isMember(i)) {
  1768                     lastLocal = i;
  1769                     break;
  1772             if (lastLocal >= 0)
  1773                 System.err.println(" locals:");
  1774             for (int i=0; i<=lastLocal; i++) {
  1775                 System.err.print("  " + i + ": ");
  1776                 if (defined.isMember(i)) {
  1777                     LocalVar var = lvar[i];
  1778                     if (var == null) {
  1779                         System.err.println("(none)");
  1780                     } else if (var.sym == null)
  1781                         System.err.println("UNKNOWN!");
  1782                     else
  1783                         System.err.println("" + var.sym + " of type " +
  1784                                            var.sym.erasure(types));
  1785                 } else {
  1786                     System.err.println("undefined");
  1789             if (nlocks != 0) {
  1790                 System.err.print(" locks:");
  1791                 for (int i=0; i<nlocks; i++) {
  1792                     System.err.print(" " + locks[i]);
  1794                 System.err.println();
  1799     static Type jsrReturnValue = new Type(TypeTags.INT, null);
  1802 /* **************************************************************************
  1803  * Local variables
  1804  ****************************************************************************/
  1806     /** A live range of a local variable. */
  1807     static class LocalVar {
  1808         final VarSymbol sym;
  1809         final char reg;
  1810         char start_pc = Character.MAX_VALUE;
  1811         char length = Character.MAX_VALUE;
  1812         LocalVar(VarSymbol v) {
  1813             this.sym = v;
  1814             this.reg = (char)v.adr;
  1816         public LocalVar dup() {
  1817             return new LocalVar(sym);
  1819         public String toString() {
  1820             return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
  1822     };
  1824     /** Local variables, indexed by register. */
  1825     LocalVar[] lvar;
  1827     /** Add a new local variable. */
  1828     private void addLocalVar(VarSymbol v) {
  1829         int adr = v.adr;
  1830         if (adr+1 >= lvar.length) {
  1831             int newlength = lvar.length << 1;
  1832             if (newlength <= adr) newlength = adr + 10;
  1833             LocalVar[] new_lvar = new LocalVar[newlength];
  1834             System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);
  1835             lvar = new_lvar;
  1837         assert lvar[adr] == null;
  1838         if (pendingJumps != null) resolvePending();
  1839         lvar[adr] = new LocalVar(v);
  1840         state.defined.excl(adr);
  1843     /** Set the current variable defined state. */
  1844     public void setDefined(Bits newDefined) {
  1845         if (alive && newDefined != state.defined) {
  1846             Bits diff = state.defined.dup().xorSet(newDefined);
  1847             for (int adr = diff.nextBit(0);
  1848                  adr >= 0;
  1849                  adr = diff.nextBit(adr+1)) {
  1850                 if (adr >= nextreg)
  1851                     state.defined.excl(adr);
  1852                 else if (state.defined.isMember(adr))
  1853                     setUndefined(adr);
  1854                 else
  1855                     setDefined(adr);
  1860     /** Mark a register as being (possibly) defined. */
  1861     public void setDefined(int adr) {
  1862         LocalVar v = lvar[adr];
  1863         if (v == null) {
  1864             state.defined.excl(adr);
  1865         } else {
  1866             state.defined.incl(adr);
  1867             if (cp < Character.MAX_VALUE) {
  1868                 if (v.start_pc == Character.MAX_VALUE)
  1869                     v.start_pc = (char)cp;
  1874     /** Mark a register as being undefined. */
  1875     public void setUndefined(int adr) {
  1876         state.defined.excl(adr);
  1877         if (adr < lvar.length &&
  1878             lvar[adr] != null &&
  1879             lvar[adr].start_pc != Character.MAX_VALUE) {
  1880             LocalVar v = lvar[adr];
  1881             char length = (char)(curPc() - v.start_pc);
  1882             if (length > 0 && length < Character.MAX_VALUE) {
  1883                 lvar[adr] = v.dup();
  1884                 v.length = length;
  1885                 putVar(v);
  1886             } else {
  1887                 v.start_pc = Character.MAX_VALUE;
  1892     /** End the scope of a variable. */
  1893     private void endScope(int adr) {
  1894         LocalVar v = lvar[adr];
  1895         if (v != null) {
  1896             lvar[adr] = null;
  1897             if (v.start_pc != Character.MAX_VALUE) {
  1898                 char length = (char)(curPc() - v.start_pc);
  1899                 if (length < Character.MAX_VALUE) {
  1900                     v.length = length;
  1901                     putVar(v);
  1905         state.defined.excl(adr);
  1908     /** Put a live variable range into the buffer to be output to the
  1909      *  class file.
  1910      */
  1911     void putVar(LocalVar var) {
  1912         if (!varDebugInfo) return;
  1913         if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
  1914         if (varBuffer == null)
  1915             varBuffer = new LocalVar[20];
  1916         else if (varBufferSize >= varBuffer.length) {
  1917             LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2];
  1918             System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);
  1919             varBuffer = newVarBuffer;
  1921         varBuffer[varBufferSize++] = var;
  1924     /** Previously live local variables, to be put into the variable table. */
  1925     LocalVar[] varBuffer;
  1926     int varBufferSize;
  1928     /** Create a new local variable address and return it.
  1929      */
  1930     private int newLocal(int typecode) {
  1931         int reg = nextreg;
  1932         int w = width(typecode);
  1933         nextreg = reg + w;
  1934         if (nextreg > max_locals) max_locals = nextreg;
  1935         return reg;
  1938     private int newLocal(Type type) {
  1939         return newLocal(typecode(type));
  1942     public int newLocal(VarSymbol v) {
  1943         int reg = v.adr = newLocal(v.erasure(types));
  1944         addLocalVar(v);
  1945         return reg;
  1948     /** Start a set of fresh registers.
  1949      */
  1950     public void newRegSegment() {
  1951         nextreg = max_locals;
  1954     /** End scopes of all variables with registers >= first.
  1955      */
  1956     public void endScopes(int first) {
  1957         int prevNextReg = nextreg;
  1958         nextreg = first;
  1959         for (int i = nextreg; i < prevNextReg; i++) endScope(i);
  1962 /**************************************************************************
  1963  * static tables
  1964  *************************************************************************/
  1966     public static String mnem(int opcode) {
  1967         return Mneumonics.mnem[opcode];
  1970     private static class Mneumonics {
  1971         private final static String[] mnem = new String[ByteCodeCount];
  1972         static {
  1973             mnem[nop] = "nop";
  1974             mnem[aconst_null] = "aconst_null";
  1975             mnem[iconst_m1] = "iconst_m1";
  1976             mnem[iconst_0] = "iconst_0";
  1977             mnem[iconst_1] = "iconst_1";
  1978             mnem[iconst_2] = "iconst_2";
  1979             mnem[iconst_3] = "iconst_3";
  1980             mnem[iconst_4] = "iconst_4";
  1981             mnem[iconst_5] = "iconst_5";
  1982             mnem[lconst_0] = "lconst_0";
  1983             mnem[lconst_1] = "lconst_1";
  1984             mnem[fconst_0] = "fconst_0";
  1985             mnem[fconst_1] = "fconst_1";
  1986             mnem[fconst_2] = "fconst_2";
  1987             mnem[dconst_0] = "dconst_0";
  1988             mnem[dconst_1] = "dconst_1";
  1989             mnem[bipush] = "bipush";
  1990             mnem[sipush] = "sipush";
  1991             mnem[ldc1] = "ldc1";
  1992             mnem[ldc2] = "ldc2";
  1993             mnem[ldc2w] = "ldc2w";
  1994             mnem[iload] = "iload";
  1995             mnem[lload] = "lload";
  1996             mnem[fload] = "fload";
  1997             mnem[dload] = "dload";
  1998             mnem[aload] = "aload";
  1999             mnem[iload_0] = "iload_0";
  2000             mnem[lload_0] = "lload_0";
  2001             mnem[fload_0] = "fload_0";
  2002             mnem[dload_0] = "dload_0";
  2003             mnem[aload_0] = "aload_0";
  2004             mnem[iload_1] = "iload_1";
  2005             mnem[lload_1] = "lload_1";
  2006             mnem[fload_1] = "fload_1";
  2007             mnem[dload_1] = "dload_1";
  2008             mnem[aload_1] = "aload_1";
  2009             mnem[iload_2] = "iload_2";
  2010             mnem[lload_2] = "lload_2";
  2011             mnem[fload_2] = "fload_2";
  2012             mnem[dload_2] = "dload_2";
  2013             mnem[aload_2] = "aload_2";
  2014             mnem[iload_3] = "iload_3";
  2015             mnem[lload_3] = "lload_3";
  2016             mnem[fload_3] = "fload_3";
  2017             mnem[dload_3] = "dload_3";
  2018             mnem[aload_3] = "aload_3";
  2019             mnem[iaload] = "iaload";
  2020             mnem[laload] = "laload";
  2021             mnem[faload] = "faload";
  2022             mnem[daload] = "daload";
  2023             mnem[aaload] = "aaload";
  2024             mnem[baload] = "baload";
  2025             mnem[caload] = "caload";
  2026             mnem[saload] = "saload";
  2027             mnem[istore] = "istore";
  2028             mnem[lstore] = "lstore";
  2029             mnem[fstore] = "fstore";
  2030             mnem[dstore] = "dstore";
  2031             mnem[astore] = "astore";
  2032             mnem[istore_0] = "istore_0";
  2033             mnem[lstore_0] = "lstore_0";
  2034             mnem[fstore_0] = "fstore_0";
  2035             mnem[dstore_0] = "dstore_0";
  2036             mnem[astore_0] = "astore_0";
  2037             mnem[istore_1] = "istore_1";
  2038             mnem[lstore_1] = "lstore_1";
  2039             mnem[fstore_1] = "fstore_1";
  2040             mnem[dstore_1] = "dstore_1";
  2041             mnem[astore_1] = "astore_1";
  2042             mnem[istore_2] = "istore_2";
  2043             mnem[lstore_2] = "lstore_2";
  2044             mnem[fstore_2] = "fstore_2";
  2045             mnem[dstore_2] = "dstore_2";
  2046             mnem[astore_2] = "astore_2";
  2047             mnem[istore_3] = "istore_3";
  2048             mnem[lstore_3] = "lstore_3";
  2049             mnem[fstore_3] = "fstore_3";
  2050             mnem[dstore_3] = "dstore_3";
  2051             mnem[astore_3] = "astore_3";
  2052             mnem[iastore] = "iastore";
  2053             mnem[lastore] = "lastore";
  2054             mnem[fastore] = "fastore";
  2055             mnem[dastore] = "dastore";
  2056             mnem[aastore] = "aastore";
  2057             mnem[bastore] = "bastore";
  2058             mnem[castore] = "castore";
  2059             mnem[sastore] = "sastore";
  2060             mnem[pop] = "pop";
  2061             mnem[pop2] = "pop2";
  2062             mnem[dup] = "dup";
  2063             mnem[dup_x1] = "dup_x1";
  2064             mnem[dup_x2] = "dup_x2";
  2065             mnem[dup2] = "dup2";
  2066             mnem[dup2_x1] = "dup2_x1";
  2067             mnem[dup2_x2] = "dup2_x2";
  2068             mnem[swap] = "swap";
  2069             mnem[iadd] = "iadd";
  2070             mnem[ladd] = "ladd";
  2071             mnem[fadd] = "fadd";
  2072             mnem[dadd] = "dadd";
  2073             mnem[isub] = "isub";
  2074             mnem[lsub] = "lsub";
  2075             mnem[fsub] = "fsub";
  2076             mnem[dsub] = "dsub";
  2077             mnem[imul] = "imul";
  2078             mnem[lmul] = "lmul";
  2079             mnem[fmul] = "fmul";
  2080             mnem[dmul] = "dmul";
  2081             mnem[idiv] = "idiv";
  2082             mnem[ldiv] = "ldiv";
  2083             mnem[fdiv] = "fdiv";
  2084             mnem[ddiv] = "ddiv";
  2085             mnem[imod] = "imod";
  2086             mnem[lmod] = "lmod";
  2087             mnem[fmod] = "fmod";
  2088             mnem[dmod] = "dmod";
  2089             mnem[ineg] = "ineg";
  2090             mnem[lneg] = "lneg";
  2091             mnem[fneg] = "fneg";
  2092             mnem[dneg] = "dneg";
  2093             mnem[ishl] = "ishl";
  2094             mnem[lshl] = "lshl";
  2095             mnem[ishr] = "ishr";
  2096             mnem[lshr] = "lshr";
  2097             mnem[iushr] = "iushr";
  2098             mnem[lushr] = "lushr";
  2099             mnem[iand] = "iand";
  2100             mnem[land] = "land";
  2101             mnem[ior] = "ior";
  2102             mnem[lor] = "lor";
  2103             mnem[ixor] = "ixor";
  2104             mnem[lxor] = "lxor";
  2105             mnem[iinc] = "iinc";
  2106             mnem[i2l] = "i2l";
  2107             mnem[i2f] = "i2f";
  2108             mnem[i2d] = "i2d";
  2109             mnem[l2i] = "l2i";
  2110             mnem[l2f] = "l2f";
  2111             mnem[l2d] = "l2d";
  2112             mnem[f2i] = "f2i";
  2113             mnem[f2l] = "f2l";
  2114             mnem[f2d] = "f2d";
  2115             mnem[d2i] = "d2i";
  2116             mnem[d2l] = "d2l";
  2117             mnem[d2f] = "d2f";
  2118             mnem[int2byte] = "int2byte";
  2119             mnem[int2char] = "int2char";
  2120             mnem[int2short] = "int2short";
  2121             mnem[lcmp] = "lcmp";
  2122             mnem[fcmpl] = "fcmpl";
  2123             mnem[fcmpg] = "fcmpg";
  2124             mnem[dcmpl] = "dcmpl";
  2125             mnem[dcmpg] = "dcmpg";
  2126             mnem[ifeq] = "ifeq";
  2127             mnem[ifne] = "ifne";
  2128             mnem[iflt] = "iflt";
  2129             mnem[ifge] = "ifge";
  2130             mnem[ifgt] = "ifgt";
  2131             mnem[ifle] = "ifle";
  2132             mnem[if_icmpeq] = "if_icmpeq";
  2133             mnem[if_icmpne] = "if_icmpne";
  2134             mnem[if_icmplt] = "if_icmplt";
  2135             mnem[if_icmpge] = "if_icmpge";
  2136             mnem[if_icmpgt] = "if_icmpgt";
  2137             mnem[if_icmple] = "if_icmple";
  2138             mnem[if_acmpeq] = "if_acmpeq";
  2139             mnem[if_acmpne] = "if_acmpne";
  2140             mnem[goto_] = "goto_";
  2141             mnem[jsr] = "jsr";
  2142             mnem[ret] = "ret";
  2143             mnem[tableswitch] = "tableswitch";
  2144             mnem[lookupswitch] = "lookupswitch";
  2145             mnem[ireturn] = "ireturn";
  2146             mnem[lreturn] = "lreturn";
  2147             mnem[freturn] = "freturn";
  2148             mnem[dreturn] = "dreturn";
  2149             mnem[areturn] = "areturn";
  2150             mnem[return_] = "return_";
  2151             mnem[getstatic] = "getstatic";
  2152             mnem[putstatic] = "putstatic";
  2153             mnem[getfield] = "getfield";
  2154             mnem[putfield] = "putfield";
  2155             mnem[invokevirtual] = "invokevirtual";
  2156             mnem[invokespecial] = "invokespecial";
  2157             mnem[invokestatic] = "invokestatic";
  2158             mnem[invokeinterface] = "invokeinterface";
  2159             // mnem[___unused___] = "___unused___";
  2160             mnem[new_] = "new_";
  2161             mnem[newarray] = "newarray";
  2162             mnem[anewarray] = "anewarray";
  2163             mnem[arraylength] = "arraylength";
  2164             mnem[athrow] = "athrow";
  2165             mnem[checkcast] = "checkcast";
  2166             mnem[instanceof_] = "instanceof_";
  2167             mnem[monitorenter] = "monitorenter";
  2168             mnem[monitorexit] = "monitorexit";
  2169             mnem[wide] = "wide";
  2170             mnem[multianewarray] = "multianewarray";
  2171             mnem[if_acmp_null] = "if_acmp_null";
  2172             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
  2173             mnem[goto_w] = "goto_w";
  2174             mnem[jsr_w] = "jsr_w";
  2175             mnem[breakpoint] = "breakpoint";

mercurial