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

Tue, 28 Jul 2009 12:12:59 -0700

author
xdono
date
Tue, 28 Jul 2009 12:12:59 -0700
changeset 323
14b1a8ede954
parent 310
7c154fdc3547
child 478
0eaf89e08564
permissions
-rw-r--r--

6862919: Update copyright year
Summary: Update copyright for files that have been modified in 2009, up to 07/09
Reviewed-by: tbell, ohair

     1 /*
     2  * Copyright 1999-2009 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 invokedynamic instruction.
   460      */
   461     public void emitInvokedynamic(int desc, Type mtype) {
   462         // N.B. this format is under consideration by the JSR 292 EG
   463         int argsize = width(mtype.getParameterTypes());
   464         emitop(invokedynamic);
   465         if (!alive) return;
   466         emit2(desc);
   467         emit2(0);
   468         state.pop(argsize);
   469         state.push(mtype.getReturnType());
   470     }
   472     /** Emit an opcode with no operand field.
   473      */
   474     public void emitop0(int op) {
   475         emitop(op);
   476         if (!alive) return;
   477         switch (op) {
   478         case aaload: {
   479             state.pop(1);// index
   480             Type a = state.stack[state.stacksize-1];
   481             state.pop(1);
   482             state.push(types.erasure(types.elemtype(a))); }
   483             break;
   484         case goto_:
   485             markDead();
   486             break;
   487         case nop:
   488         case ineg:
   489         case lneg:
   490         case fneg:
   491         case dneg:
   492             break;
   493         case aconst_null:
   494             state.push(syms.botType);
   495             break;
   496         case iconst_m1:
   497         case iconst_0:
   498         case iconst_1:
   499         case iconst_2:
   500         case iconst_3:
   501         case iconst_4:
   502         case iconst_5:
   503         case iload_0:
   504         case iload_1:
   505         case iload_2:
   506         case iload_3:
   507             state.push(syms.intType);
   508             break;
   509         case lconst_0:
   510         case lconst_1:
   511         case lload_0:
   512         case lload_1:
   513         case lload_2:
   514         case lload_3:
   515             state.push(syms.longType);
   516             break;
   517         case fconst_0:
   518         case fconst_1:
   519         case fconst_2:
   520         case fload_0:
   521         case fload_1:
   522         case fload_2:
   523         case fload_3:
   524             state.push(syms.floatType);
   525             break;
   526         case dconst_0:
   527         case dconst_1:
   528         case dload_0:
   529         case dload_1:
   530         case dload_2:
   531         case dload_3:
   532             state.push(syms.doubleType);
   533             break;
   534         case aload_0:
   535             state.push(lvar[0].sym.type);
   536             break;
   537         case aload_1:
   538             state.push(lvar[1].sym.type);
   539             break;
   540         case aload_2:
   541             state.push(lvar[2].sym.type);
   542             break;
   543         case aload_3:
   544             state.push(lvar[3].sym.type);
   545             break;
   546         case iaload:
   547         case baload:
   548         case caload:
   549         case saload:
   550             state.pop(2);
   551             state.push(syms.intType);
   552             break;
   553         case laload:
   554             state.pop(2);
   555             state.push(syms.longType);
   556             break;
   557         case faload:
   558             state.pop(2);
   559             state.push(syms.floatType);
   560             break;
   561         case daload:
   562             state.pop(2);
   563             state.push(syms.doubleType);
   564             break;
   565         case istore_0:
   566         case istore_1:
   567         case istore_2:
   568         case istore_3:
   569         case fstore_0:
   570         case fstore_1:
   571         case fstore_2:
   572         case fstore_3:
   573         case astore_0:
   574         case astore_1:
   575         case astore_2:
   576         case astore_3:
   577         case pop:
   578         case lshr:
   579         case lshl:
   580         case lushr:
   581             state.pop(1);
   582             break;
   583         case areturn:
   584         case ireturn:
   585         case freturn:
   586             assert state.nlocks == 0;
   587             state.pop(1);
   588             markDead();
   589             break;
   590         case athrow:
   591             state.pop(1);
   592             markDead();
   593             break;
   594         case lstore_0:
   595         case lstore_1:
   596         case lstore_2:
   597         case lstore_3:
   598         case dstore_0:
   599         case dstore_1:
   600         case dstore_2:
   601         case dstore_3:
   602         case pop2:
   603             state.pop(2);
   604             break;
   605         case lreturn:
   606         case dreturn:
   607             assert state.nlocks == 0;
   608             state.pop(2);
   609             markDead();
   610             break;
   611         case dup:
   612             state.push(state.stack[state.stacksize-1]);
   613             break;
   614         case return_:
   615             assert state.nlocks == 0;
   616             markDead();
   617             break;
   618         case arraylength:
   619             state.pop(1);
   620             state.push(syms.intType);
   621             break;
   622         case isub:
   623         case iadd:
   624         case imul:
   625         case idiv:
   626         case imod:
   627         case ishl:
   628         case ishr:
   629         case iushr:
   630         case iand:
   631         case ior:
   632         case ixor:
   633             state.pop(1);
   634             // state.pop(1);
   635             // state.push(syms.intType);
   636             break;
   637         case aastore:
   638             state.pop(3);
   639             break;
   640         case land:
   641         case lor:
   642         case lxor:
   643         case lmod:
   644         case ldiv:
   645         case lmul:
   646         case lsub:
   647         case ladd:
   648             state.pop(2);
   649             break;
   650         case lcmp:
   651             state.pop(4);
   652             state.push(syms.intType);
   653             break;
   654         case l2i:
   655             state.pop(2);
   656             state.push(syms.intType);
   657             break;
   658         case i2l:
   659             state.pop(1);
   660             state.push(syms.longType);
   661             break;
   662         case i2f:
   663             state.pop(1);
   664             state.push(syms.floatType);
   665             break;
   666         case i2d:
   667             state.pop(1);
   668             state.push(syms.doubleType);
   669             break;
   670         case l2f:
   671             state.pop(2);
   672             state.push(syms.floatType);
   673             break;
   674         case l2d:
   675             state.pop(2);
   676             state.push(syms.doubleType);
   677             break;
   678         case f2i:
   679             state.pop(1);
   680             state.push(syms.intType);
   681             break;
   682         case f2l:
   683             state.pop(1);
   684             state.push(syms.longType);
   685             break;
   686         case f2d:
   687             state.pop(1);
   688             state.push(syms.doubleType);
   689             break;
   690         case d2i:
   691             state.pop(2);
   692             state.push(syms.intType);
   693             break;
   694         case d2l:
   695             state.pop(2);
   696             state.push(syms.longType);
   697             break;
   698         case d2f:
   699             state.pop(2);
   700             state.push(syms.floatType);
   701             break;
   702         case tableswitch:
   703         case lookupswitch:
   704             state.pop(1);
   705             // the caller is responsible for patching up the state
   706             break;
   707         case dup_x1: {
   708             Type val1 = state.pop1();
   709             Type val2 = state.pop1();
   710             state.push(val1);
   711             state.push(val2);
   712             state.push(val1);
   713             break;
   714         }
   715         case bastore:
   716             state.pop(3);
   717             break;
   718         case int2byte:
   719         case int2char:
   720         case int2short:
   721             break;
   722         case fmul:
   723         case fadd:
   724         case fsub:
   725         case fdiv:
   726         case fmod:
   727             state.pop(1);
   728             break;
   729         case castore:
   730         case iastore:
   731         case fastore:
   732         case sastore:
   733             state.pop(3);
   734             break;
   735         case lastore:
   736         case dastore:
   737             state.pop(4);
   738             break;
   739         case dup2:
   740             if (state.stack[state.stacksize-1] != null) {
   741                 Type value1 = state.pop1();
   742                 Type value2 = state.pop1();
   743                 state.push(value2);
   744                 state.push(value1);
   745                 state.push(value2);
   746                 state.push(value1);
   747             } else {
   748                 Type value = state.pop2();
   749                 state.push(value);
   750                 state.push(value);
   751             }
   752             break;
   753         case dup2_x1:
   754             if (state.stack[state.stacksize-1] != null) {
   755                 Type value1 = state.pop1();
   756                 Type value2 = state.pop1();
   757                 Type value3 = state.pop1();
   758                 state.push(value2);
   759                 state.push(value1);
   760                 state.push(value3);
   761                 state.push(value2);
   762                 state.push(value1);
   763             } else {
   764                 Type value1 = state.pop2();
   765                 Type value2 = state.pop1();
   766                 state.push(value1);
   767                 state.push(value2);
   768                 state.push(value1);
   769             }
   770             break;
   771         case dup2_x2:
   772             if (state.stack[state.stacksize-1] != null) {
   773                 Type value1 = state.pop1();
   774                 Type value2 = state.pop1();
   775                 if (state.stack[state.stacksize-1] != null) {
   776                     // form 1
   777                     Type value3 = state.pop1();
   778                     Type value4 = state.pop1();
   779                     state.push(value2);
   780                     state.push(value1);
   781                     state.push(value4);
   782                     state.push(value3);
   783                     state.push(value2);
   784                     state.push(value1);
   785                 } else {
   786                     // form 3
   787                     Type value3 = state.pop2();
   788                     state.push(value2);
   789                     state.push(value1);
   790                     state.push(value3);
   791                     state.push(value2);
   792                     state.push(value1);
   793                 }
   794             } else {
   795                 Type value1 = state.pop2();
   796                 if (state.stack[state.stacksize-1] != null) {
   797                     // form 2
   798                     Type value2 = state.pop1();
   799                     Type value3 = state.pop1();
   800                     state.push(value1);
   801                     state.push(value3);
   802                     state.push(value2);
   803                     state.push(value1);
   804                 } else {
   805                     // form 4
   806                     Type value2 = state.pop2();
   807                     state.push(value1);
   808                     state.push(value2);
   809                     state.push(value1);
   810                 }
   811             }
   812             break;
   813         case dup_x2: {
   814             Type value1 = state.pop1();
   815             if (state.stack[state.stacksize-1] != null) {
   816                 // form 1
   817                 Type value2 = state.pop1();
   818                 Type value3 = state.pop1();
   819                 state.push(value1);
   820                 state.push(value3);
   821                 state.push(value2);
   822                 state.push(value1);
   823             } else {
   824                 // form 2
   825                 Type value2 = state.pop2();
   826                 state.push(value1);
   827                 state.push(value2);
   828                 state.push(value1);
   829             }
   830         }
   831             break;
   832         case fcmpl:
   833         case fcmpg:
   834             state.pop(2);
   835             state.push(syms.intType);
   836             break;
   837         case dcmpl:
   838         case dcmpg:
   839             state.pop(4);
   840             state.push(syms.intType);
   841             break;
   842         case swap: {
   843             Type value1 = state.pop1();
   844             Type value2 = state.pop1();
   845             state.push(value1);
   846             state.push(value2);
   847             break;
   848         }
   849         case dadd:
   850         case dsub:
   851         case dmul:
   852         case ddiv:
   853         case dmod:
   854             state.pop(2);
   855             break;
   856         case ret:
   857             markDead();
   858             break;
   859         case wide:
   860             // must be handled by the caller.
   861             return;
   862         case monitorenter:
   863         case monitorexit:
   864             state.pop(1);
   865             break;
   867         default:
   868             throw new AssertionError(mnem(op));
   869         }
   870         postop();
   871     }
   873     /** Emit an opcode with a one-byte operand field.
   874      */
   875     public void emitop1(int op, int od) {
   876         emitop(op);
   877         if (!alive) return;
   878         emit1(od);
   879         switch (op) {
   880         case bipush:
   881             state.push(syms.intType);
   882             break;
   883         case ldc1:
   884             state.push(typeForPool(pool.pool[od]));
   885             break;
   886         default:
   887             throw new AssertionError(mnem(op));
   888         }
   889         postop();
   890     }
   892     /** The type of a constant pool entry. */
   893     private Type typeForPool(Object o) {
   894         if (o instanceof Integer) return syms.intType;
   895         if (o instanceof Float) return syms.floatType;
   896         if (o instanceof String) return syms.stringType;
   897         if (o instanceof Long) return syms.longType;
   898         if (o instanceof Double) return syms.doubleType;
   899         if (o instanceof ClassSymbol) return syms.classType;
   900         if (o instanceof Type.ArrayType) return syms.classType;
   901         throw new AssertionError(o);
   902     }
   904     /** Emit an opcode with a one-byte operand field;
   905      *  widen if field does not fit in a byte.
   906      */
   907     public void emitop1w(int op, int od) {
   908         if (od > 0xFF) {
   909             emitop(wide);
   910             emitop(op);
   911             emit2(od);
   912         } else {
   913             emitop(op);
   914             emit1(od);
   915         }
   916         if (!alive) return;
   917         switch (op) {
   918         case iload:
   919             state.push(syms.intType);
   920             break;
   921         case lload:
   922             state.push(syms.longType);
   923             break;
   924         case fload:
   925             state.push(syms.floatType);
   926             break;
   927         case dload:
   928             state.push(syms.doubleType);
   929             break;
   930         case aload:
   931             state.push(lvar[od].sym.type);
   932             break;
   933         case lstore:
   934         case dstore:
   935             state.pop(2);
   936             break;
   937         case istore:
   938         case fstore:
   939         case astore:
   940             state.pop(1);
   941             break;
   942         case ret:
   943             markDead();
   944             break;
   945         default:
   946             throw new AssertionError(mnem(op));
   947         }
   948         postop();
   949     }
   951     /** Emit an opcode with two one-byte operand fields;
   952      *  widen if either field does not fit in a byte.
   953      */
   954     public void emitop1w(int op, int od1, int od2) {
   955         if (od1 > 0xFF || od2 < -128 || od2 > 127) {
   956             emitop(wide);
   957             emitop(op);
   958             emit2(od1);
   959             emit2(od2);
   960         } else {
   961             emitop(op);
   962             emit1(od1);
   963             emit1(od2);
   964         }
   965         if (!alive) return;
   966         switch (op) {
   967         case iinc:
   968             break;
   969         default:
   970             throw new AssertionError(mnem(op));
   971         }
   972     }
   974     /** Emit an opcode with a two-byte operand field.
   975      */
   976     public void emitop2(int op, int od) {
   977         emitop(op);
   978         if (!alive) return;
   979         emit2(od);
   980         switch (op) {
   981         case getstatic:
   982             state.push(((Symbol)(pool.pool[od])).erasure(types));
   983             break;
   984         case putstatic:
   985             state.pop(((Symbol)(pool.pool[od])).erasure(types));
   986             break;
   987         case new_:
   988             state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
   989             break;
   990         case sipush:
   991             state.push(syms.intType);
   992             break;
   993         case if_acmp_null:
   994         case if_acmp_nonnull:
   995         case ifeq:
   996         case ifne:
   997         case iflt:
   998         case ifge:
   999         case ifgt:
  1000         case ifle:
  1001             state.pop(1);
  1002             break;
  1003         case if_icmpeq:
  1004         case if_icmpne:
  1005         case if_icmplt:
  1006         case if_icmpge:
  1007         case if_icmpgt:
  1008         case if_icmple:
  1009         case if_acmpeq:
  1010         case if_acmpne:
  1011             state.pop(2);
  1012             break;
  1013         case goto_:
  1014             markDead();
  1015             break;
  1016         case putfield:
  1017             state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1018             state.pop(1); // object ref
  1019             break;
  1020         case getfield:
  1021             state.pop(1); // object ref
  1022             state.push(((Symbol)(pool.pool[od])).erasure(types));
  1023             break;
  1024         case checkcast: {
  1025             state.pop(1); // object ref
  1026             Object o = pool.pool[od];
  1027             Type t = (o instanceof Symbol)
  1028                 ? ((Symbol)o).erasure(types)
  1029                 : types.erasure(((Type)o));
  1030             state.push(t);
  1031             break; }
  1032         case ldc2w:
  1033             state.push(typeForPool(pool.pool[od]));
  1034             break;
  1035         case instanceof_:
  1036             state.pop(1);
  1037             state.push(syms.intType);
  1038             break;
  1039         case ldc2:
  1040             state.push(typeForPool(pool.pool[od]));
  1041             break;
  1042         case jsr:
  1043             break;
  1044         default:
  1045             throw new AssertionError(mnem(op));
  1047         // postop();
  1050     /** Emit an opcode with a four-byte operand field.
  1051      */
  1052     public void emitop4(int op, int od) {
  1053         emitop(op);
  1054         if (!alive) return;
  1055         emit4(od);
  1056         switch (op) {
  1057         case goto_w:
  1058             markDead();
  1059             break;
  1060         case jsr_w:
  1061             break;
  1062         default:
  1063             throw new AssertionError(mnem(op));
  1065         // postop();
  1068     /** Align code pointer to next `incr' boundary.
  1069      */
  1070     public void align(int incr) {
  1071         if (alive)
  1072             while (cp % incr != 0) emitop0(nop);
  1075     /** Place a byte into code at address pc. Pre: pc + 1 <= cp.
  1076      */
  1077     private void put1(int pc, int op) {
  1078         code[pc] = (byte)op;
  1081     /** Place two bytes into code at address pc. Pre: pc + 2 <= cp.
  1082      */
  1083     private void put2(int pc, int od) {
  1084         // pre: pc + 2 <= cp
  1085         put1(pc, od >> 8);
  1086         put1(pc+1, od);
  1089     /** Place four  bytes into code at address pc. Pre: pc + 4 <= cp.
  1090      */
  1091     public void put4(int pc, int od) {
  1092         // pre: pc + 4 <= cp
  1093         put1(pc  , od >> 24);
  1094         put1(pc+1, od >> 16);
  1095         put1(pc+2, od >> 8);
  1096         put1(pc+3, od);
  1099     /** Return code byte at position pc as an unsigned int.
  1100      */
  1101     private int get1(int pc) {
  1102         return code[pc] & 0xFF;
  1105     /** Return two code bytes at position pc as an unsigned int.
  1106      */
  1107     private int get2(int pc) {
  1108         return (get1(pc) << 8) | get1(pc+1);
  1111     /** Return four code bytes at position pc as an int.
  1112      */
  1113     public int get4(int pc) {
  1114         // pre: pc + 4 <= cp
  1115         return
  1116             (get1(pc) << 24) |
  1117             (get1(pc+1) << 16) |
  1118             (get1(pc+2) << 8) |
  1119             (get1(pc+3));
  1122     /** Is code generation currently enabled?
  1123      */
  1124     public boolean isAlive() {
  1125         return alive || pendingJumps != null;
  1128     /** Switch code generation on/off.
  1129      */
  1130     public void markDead() {
  1131         alive = false;
  1134     /** Declare an entry point; return current code pointer
  1135      */
  1136     public int entryPoint() {
  1137         int pc = curPc();
  1138         alive = true;
  1139         pendingStackMap = needStackMap;
  1140         return pc;
  1143     /** Declare an entry point with initial state;
  1144      *  return current code pointer
  1145      */
  1146     public int entryPoint(State state) {
  1147         int pc = curPc();
  1148         alive = true;
  1149         this.state = state.dup();
  1150         assert state.stacksize <= max_stack;
  1151         if (debugCode) System.err.println("entry point " + state);
  1152         pendingStackMap = needStackMap;
  1153         return pc;
  1156     /** Declare an entry point with initial state plus a pushed value;
  1157      *  return current code pointer
  1158      */
  1159     public int entryPoint(State state, Type pushed) {
  1160         int pc = curPc();
  1161         alive = true;
  1162         this.state = state.dup();
  1163         assert state.stacksize <= max_stack;
  1164         this.state.push(pushed);
  1165         if (debugCode) System.err.println("entry point " + state);
  1166         pendingStackMap = needStackMap;
  1167         return pc;
  1171 /**************************************************************************
  1172  * Stack map generation
  1173  *************************************************************************/
  1175     /** An entry in the stack map. */
  1176     static class StackMapFrame {
  1177         int pc;
  1178         Type[] locals;
  1179         Type[] stack;
  1182     /** A buffer of cldc stack map entries. */
  1183     StackMapFrame[] stackMapBuffer = null;
  1185     /** A buffer of compressed StackMapTable entries. */
  1186     StackMapTableFrame[] stackMapTableBuffer = null;
  1187     int stackMapBufferSize = 0;
  1189     /** The last PC at which we generated a stack map. */
  1190     int lastStackMapPC = -1;
  1192     /** The last stack map frame in StackMapTable. */
  1193     StackMapFrame lastFrame = null;
  1195     /** The stack map frame before the last one. */
  1196     StackMapFrame frameBeforeLast = null;
  1198     /** Emit a stack map entry.  */
  1199     public void emitStackMap() {
  1200         int pc = curPc();
  1201         if (!needStackMap) return;
  1205         switch (stackMap) {
  1206             case CLDC:
  1207                 emitCLDCStackMap(pc, getLocalsSize());
  1208                 break;
  1209             case JSR202:
  1210                 emitStackMapFrame(pc, getLocalsSize());
  1211                 break;
  1212             default:
  1213                 throw new AssertionError("Should have chosen a stackmap format");
  1215         // DEBUG code follows
  1216         if (debugCode) state.dump(pc);
  1219     private int getLocalsSize() {
  1220         int nextLocal = 0;
  1221         for (int i=max_locals-1; i>=0; i--) {
  1222             if (state.defined.isMember(i) && lvar[i] != null) {
  1223                 nextLocal = i + width(lvar[i].sym.erasure(types));
  1224                 break;
  1227         return nextLocal;
  1230     /** Emit a CLDC stack map frame. */
  1231     void emitCLDCStackMap(int pc, int localsSize) {
  1232         if (lastStackMapPC == pc) {
  1233             // drop existing stackmap at this offset
  1234             stackMapBuffer[--stackMapBufferSize] = null;
  1236         lastStackMapPC = pc;
  1238         if (stackMapBuffer == null) {
  1239             stackMapBuffer = new StackMapFrame[20];
  1240         } else if (stackMapBuffer.length == stackMapBufferSize) {
  1241             StackMapFrame[] newStackMapBuffer =
  1242                 new StackMapFrame[stackMapBufferSize << 1];
  1243             System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,
  1244                              0, stackMapBufferSize);
  1245             stackMapBuffer = newStackMapBuffer;
  1247         StackMapFrame frame =
  1248             stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
  1249         frame.pc = pc;
  1251         frame.locals = new Type[localsSize];
  1252         for (int i=0; i<localsSize; i++) {
  1253             if (state.defined.isMember(i) && lvar[i] != null) {
  1254                 Type vtype = lvar[i].sym.type;
  1255                 if (!(vtype instanceof UninitializedType))
  1256                     vtype = types.erasure(vtype);
  1257                 frame.locals[i] = vtype;
  1260         frame.stack = new Type[state.stacksize];
  1261         for (int i=0; i<state.stacksize; i++)
  1262             frame.stack[i] = state.stack[i];
  1265     void emitStackMapFrame(int pc, int localsSize) {
  1266         if (lastFrame == null) {
  1267             // first frame
  1268             lastFrame = getInitialFrame();
  1269         } else if (lastFrame.pc == pc) {
  1270             // drop existing stackmap at this offset
  1271             stackMapTableBuffer[--stackMapBufferSize] = null;
  1272             lastFrame = frameBeforeLast;
  1273             frameBeforeLast = null;
  1276         StackMapFrame frame = new StackMapFrame();
  1277         frame.pc = pc;
  1279         int localCount = 0;
  1280         Type[] locals = new Type[localsSize];
  1281         for (int i=0; i<localsSize; i++, localCount++) {
  1282             if (state.defined.isMember(i) && lvar[i] != null) {
  1283                 Type vtype = lvar[i].sym.type;
  1284                 if (!(vtype instanceof UninitializedType))
  1285                     vtype = types.erasure(vtype);
  1286                 locals[i] = vtype;
  1287                 if (width(vtype) > 1) i++;
  1290         frame.locals = new Type[localCount];
  1291         for (int i=0, j=0; i<localsSize; i++, j++) {
  1292             assert(j < localCount);
  1293             frame.locals[j] = locals[i];
  1294             if (width(locals[i]) > 1) i++;
  1297         int stackCount = 0;
  1298         for (int i=0; i<state.stacksize; i++) {
  1299             if (state.stack[i] != null) {
  1300                 stackCount++;
  1303         frame.stack = new Type[stackCount];
  1304         stackCount = 0;
  1305         for (int i=0; i<state.stacksize; i++) {
  1306             if (state.stack[i] != null) {
  1307                 frame.stack[stackCount++] = state.stack[i];
  1311         if (stackMapTableBuffer == null) {
  1312             stackMapTableBuffer = new StackMapTableFrame[20];
  1313         } else if (stackMapTableBuffer.length == stackMapBufferSize) {
  1314             StackMapTableFrame[] newStackMapTableBuffer =
  1315                 new StackMapTableFrame[stackMapBufferSize << 1];
  1316             System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,
  1317                              0, stackMapBufferSize);
  1318             stackMapTableBuffer = newStackMapTableBuffer;
  1320         stackMapTableBuffer[stackMapBufferSize++] =
  1321                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
  1323         frameBeforeLast = lastFrame;
  1324         lastFrame = frame;
  1327     StackMapFrame getInitialFrame() {
  1328         StackMapFrame frame = new StackMapFrame();
  1329         List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
  1330         int len = arg_types.length();
  1331         int count = 0;
  1332         if (!meth.isStatic()) {
  1333             Type thisType = meth.owner.type;
  1334             frame.locals = new Type[len+1];
  1335             if (meth.isConstructor() && thisType != syms.objectType) {
  1336                 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
  1337             } else {
  1338                 frame.locals[count++] = types.erasure(thisType);
  1340         } else {
  1341             frame.locals = new Type[len];
  1343         for (Type arg_type : arg_types) {
  1344             frame.locals[count++] = types.erasure(arg_type);
  1346         frame.pc = -1;
  1347         frame.stack = null;
  1348         return frame;
  1352 /**************************************************************************
  1353  * Operations having to do with jumps
  1354  *************************************************************************/
  1356     /** A chain represents a list of unresolved jumps. Jump locations
  1357      *  are sorted in decreasing order.
  1358      */
  1359     public static class Chain {
  1361         /** The position of the jump instruction.
  1362          */
  1363         public final int pc;
  1365         /** The machine state after the jump instruction.
  1366          *  Invariant: all elements of a chain list have the same stacksize
  1367          *  and compatible stack and register contents.
  1368          */
  1369         Code.State state;
  1371         /** The next jump in the list.
  1372          */
  1373         public final Chain next;
  1375         /** Construct a chain from its jump position, stacksize, previous
  1376          *  chain, and machine state.
  1377          */
  1378         public Chain(int pc, Chain next, Code.State state) {
  1379             this.pc = pc;
  1380             this.next = next;
  1381             this.state = state;
  1385     /** Negate a branch opcode.
  1386      */
  1387     public static int negate(int opcode) {
  1388         if (opcode == if_acmp_null) return if_acmp_nonnull;
  1389         else if (opcode == if_acmp_nonnull) return if_acmp_null;
  1390         else return ((opcode + 1) ^ 1) - 1;
  1393     /** Emit a jump instruction.
  1394      *  Return code pointer of instruction to be patched.
  1395      */
  1396     public int emitJump(int opcode) {
  1397         if (fatcode) {
  1398             if (opcode == goto_ || opcode == jsr) {
  1399                 emitop4(opcode + goto_w - goto_, 0);
  1400             } else {
  1401                 emitop2(negate(opcode), 8);
  1402                 emitop4(goto_w, 0);
  1403                 alive = true;
  1404                 pendingStackMap = needStackMap;
  1406             return cp - 5;
  1407         } else {
  1408             emitop2(opcode, 0);
  1409             return cp - 3;
  1413     /** Emit a branch with given opcode; return its chain.
  1414      *  branch differs from jump in that jsr is treated as no-op.
  1415      */
  1416     public Chain branch(int opcode) {
  1417         Chain result = null;
  1418         if (opcode == goto_) {
  1419             result = pendingJumps;
  1420             pendingJumps = null;
  1422         if (opcode != dontgoto && isAlive()) {
  1423             result = new Chain(emitJump(opcode),
  1424                                result,
  1425                                state.dup());
  1426             fixedPc = fatcode;
  1427             if (opcode == goto_) alive = false;
  1429         return result;
  1432     /** Resolve chain to point to given target.
  1433      */
  1434     public void resolve(Chain chain, int target) {
  1435         boolean changed = false;
  1436         State newState = state;
  1437         for (; chain != null; chain = chain.next) {
  1438             assert state != chain.state;
  1439             assert target > chain.pc || state.stacksize == 0;
  1440             if (target >= cp) {
  1441                 target = cp;
  1442             } else if (get1(target) == goto_) {
  1443                 if (fatcode) target = target + get4(target + 1);
  1444                 else target = target + get2(target + 1);
  1446             if (get1(chain.pc) == goto_ &&
  1447                 chain.pc + 3 == target && target == cp && !fixedPc) {
  1448                 // If goto the next instruction, the jump is not needed:
  1449                 // compact the code.
  1450                 cp = cp - 3;
  1451                 target = target - 3;
  1452                 if (chain.next == null) {
  1453                     // This is the only jump to the target. Exit the loop
  1454                     // without setting new state. The code is reachable
  1455                     // from the instruction before goto_.
  1456                     alive = true;
  1457                     break;
  1459             } else {
  1460                 if (fatcode)
  1461                     put4(chain.pc + 1, target - chain.pc);
  1462                 else if (target - chain.pc < Short.MIN_VALUE ||
  1463                          target - chain.pc > Short.MAX_VALUE)
  1464                     fatcode = true;
  1465                 else
  1466                     put2(chain.pc + 1, target - chain.pc);
  1467                 assert !alive ||
  1468                     chain.state.stacksize == newState.stacksize &&
  1469                     chain.state.nlocks == newState.nlocks;
  1471             fixedPc = true;
  1472             if (cp == target) {
  1473                 changed = true;
  1474                 if (debugCode)
  1475                     System.err.println("resolving chain state=" + chain.state);
  1476                 if (alive) {
  1477                     newState = chain.state.join(newState);
  1478                 } else {
  1479                     newState = chain.state;
  1480                     alive = true;
  1484         assert !changed || state != newState;
  1485         if (state != newState) {
  1486             setDefined(newState.defined);
  1487             state = newState;
  1488             pendingStackMap = needStackMap;
  1492     /** Resolve chain to point to current code pointer.
  1493      */
  1494     public void resolve(Chain chain) {
  1495         assert
  1496             !alive ||
  1497             chain==null ||
  1498             state.stacksize == chain.state.stacksize &&
  1499             state.nlocks == chain.state.nlocks;
  1500         pendingJumps = mergeChains(chain, pendingJumps);
  1503     /** Resolve any pending jumps.
  1504      */
  1505     public void resolvePending() {
  1506         Chain x = pendingJumps;
  1507         pendingJumps = null;
  1508         resolve(x, cp);
  1511     /** Merge the jumps in of two chains into one.
  1512      */
  1513     public static Chain mergeChains(Chain chain1, Chain chain2) {
  1514         // recursive merge sort
  1515         if (chain2 == null) return chain1;
  1516         if (chain1 == null) return chain2;
  1517         assert
  1518             chain1.state.stacksize == chain2.state.stacksize &&
  1519             chain1.state.nlocks == chain2.state.nlocks;
  1520         if (chain1.pc < chain2.pc)
  1521             return new Chain(
  1522                 chain2.pc,
  1523                 mergeChains(chain1, chain2.next),
  1524                 chain2.state);
  1525         return new Chain(
  1526                 chain1.pc,
  1527                 mergeChains(chain1.next, chain2),
  1528                 chain1.state);
  1532 /* **************************************************************************
  1533  * Catch clauses
  1534  ****************************************************************************/
  1536     /** Add a catch clause to code.
  1537      */
  1538     public void addCatch(
  1539         char startPc, char endPc, char handlerPc, char catchType) {
  1540         catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
  1544 /* **************************************************************************
  1545  * Line numbers
  1546  ****************************************************************************/
  1548     /** Add a line number entry.
  1549      */
  1550     public void addLineNumber(char startPc, char lineNumber) {
  1551         if (lineDebugInfo) {
  1552             if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
  1553                 lineInfo = lineInfo.tail;
  1554             if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
  1555                 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
  1559     /** Mark beginning of statement.
  1560      */
  1561     public void statBegin(int pos) {
  1562         if (pos != Position.NOPOS) {
  1563             pendingStatPos = pos;
  1567     /** Force stat begin eagerly
  1568      */
  1569     public void markStatBegin() {
  1570         if (alive && lineDebugInfo) {
  1571             int line = lineMap.getLineNumber(pendingStatPos);
  1572             char cp1 = (char)cp;
  1573             char line1 = (char)line;
  1574             if (cp1 == cp && line1 == line)
  1575                 addLineNumber(cp1, line1);
  1577         pendingStatPos = Position.NOPOS;
  1581 /* **************************************************************************
  1582  * Simulated VM machine state
  1583  ****************************************************************************/
  1585     class State implements Cloneable {
  1586         /** The set of registers containing values. */
  1587         Bits defined;
  1589         /** The (types of the) contents of the machine stack. */
  1590         Type[] stack;
  1592         /** The first stack position currently unused. */
  1593         int stacksize;
  1595         /** The numbers of registers containing locked monitors. */
  1596         int[] locks;
  1597         int nlocks;
  1599         State() {
  1600             defined = new Bits();
  1601             stack = new Type[16];
  1604         State dup() {
  1605             try {
  1606                 State state = (State)super.clone();
  1607                 state.defined = defined.dup();
  1608                 state.stack = stack.clone();
  1609                 if (locks != null) state.locks = locks.clone();
  1610                 if (debugCode) {
  1611                     System.err.println("duping state " + this);
  1612                     dump();
  1614                 return state;
  1615             } catch (CloneNotSupportedException ex) {
  1616                 throw new AssertionError(ex);
  1620         void lock(int register) {
  1621             if (locks == null) {
  1622                 locks = new int[20];
  1623             } else if (locks.length == nlocks) {
  1624                 int[] newLocks = new int[locks.length << 1];
  1625                 System.arraycopy(locks, 0, newLocks, 0, locks.length);
  1626                 locks = newLocks;
  1628             locks[nlocks] = register;
  1629             nlocks++;
  1632         void unlock(int register) {
  1633             nlocks--;
  1634             assert locks[nlocks] == register;
  1635             locks[nlocks] = -1;
  1638         void push(Type t) {
  1639             if (debugCode) System.err.println("   pushing " + t);
  1640             switch (t.tag) {
  1641             case TypeTags.VOID:
  1642                 return;
  1643             case TypeTags.BYTE:
  1644             case TypeTags.CHAR:
  1645             case TypeTags.SHORT:
  1646             case TypeTags.BOOLEAN:
  1647                 t = syms.intType;
  1648                 break;
  1649             default:
  1650                 break;
  1652             if (stacksize+2 >= stack.length) {
  1653                 Type[] newstack = new Type[2*stack.length];
  1654                 System.arraycopy(stack, 0, newstack, 0, stack.length);
  1655                 stack = newstack;
  1657             stack[stacksize++] = t;
  1658             switch (width(t)) {
  1659             case 1:
  1660                 break;
  1661             case 2:
  1662                 stack[stacksize++] = null;
  1663                 break;
  1664             default:
  1665                 throw new AssertionError(t);
  1667             if (stacksize > max_stack)
  1668                 max_stack = stacksize;
  1671         Type pop1() {
  1672             if (debugCode) System.err.println("   popping " + 1);
  1673             stacksize--;
  1674             Type result = stack[stacksize];
  1675             stack[stacksize] = null;
  1676             assert result != null && width(result) == 1;
  1677             return result;
  1680         Type peek() {
  1681             return stack[stacksize-1];
  1684         Type pop2() {
  1685             if (debugCode) System.err.println("   popping " + 2);
  1686             stacksize -= 2;
  1687             Type result = stack[stacksize];
  1688             stack[stacksize] = null;
  1689             assert stack[stacksize+1] == null;
  1690             assert result != null && width(result) == 2;
  1691             return result;
  1694         void pop(int n) {
  1695             if (debugCode) System.err.println("   popping " + n);
  1696             while (n > 0) {
  1697                 stack[--stacksize] = null;
  1698                 n--;
  1702         void pop(Type t) {
  1703             pop(width(t));
  1706         /** Force the top of the stack to be treated as this supertype
  1707          *  of its current type. */
  1708         void forceStackTop(Type t) {
  1709             if (!alive) return;
  1710             switch (t.tag) {
  1711             case CLASS:
  1712             case ARRAY:
  1713                 int width = width(t);
  1714                 Type old = stack[stacksize-width];
  1715                 assert types.isSubtype(types.erasure(old),
  1716                                        types.erasure(t));
  1717                 stack[stacksize-width] = t;
  1718                 break;
  1719             default:
  1723         void markInitialized(UninitializedType old) {
  1724             Type newtype = old.initializedType();
  1725             for (int i=0; i<stacksize; i++)
  1726                 if (stack[i] == old) stack[i] = newtype;
  1727             for (int i=0; i<lvar.length; i++) {
  1728                 LocalVar lv = lvar[i];
  1729                 if (lv != null && lv.sym.type == old) {
  1730                     VarSymbol sym = lv.sym;
  1731                     sym = sym.clone(sym.owner);
  1732                     sym.type = newtype;
  1733                     LocalVar newlv = lvar[i] = new LocalVar(sym);
  1734                     // should the following be initialized to cp?
  1735                     newlv.start_pc = lv.start_pc;
  1740         State join(State other) {
  1741             defined = defined.andSet(other.defined);
  1742             assert stacksize == other.stacksize;
  1743             assert nlocks == other.nlocks;
  1744             for (int i=0; i<stacksize; ) {
  1745                 Type t = stack[i];
  1746                 Type tother = other.stack[i];
  1747                 Type result =
  1748                     t==tother ? t :
  1749                     types.isSubtype(t, tother) ? tother :
  1750                     types.isSubtype(tother, t) ? t :
  1751                     error();
  1752                 int w = width(result);
  1753                 stack[i] = result;
  1754                 if (w == 2) assert stack[i+1] == null;
  1755                 i += w;
  1757             return this;
  1760         Type error() {
  1761             throw new AssertionError("inconsistent stack types at join point");
  1764         void dump() {
  1765             dump(-1);
  1768         void dump(int pc) {
  1769             System.err.print("stackMap for " + meth.owner + "." + meth);
  1770             if (pc == -1)
  1771                 System.out.println();
  1772             else
  1773                 System.out.println(" at " + pc);
  1774             System.err.println(" stack (from bottom):");
  1775             for (int i=0; i<stacksize; i++)
  1776                 System.err.println("  " + i + ": " + stack[i]);
  1778             int lastLocal = 0;
  1779             for (int i=max_locals-1; i>=0; i--) {
  1780                 if (defined.isMember(i)) {
  1781                     lastLocal = i;
  1782                     break;
  1785             if (lastLocal >= 0)
  1786                 System.err.println(" locals:");
  1787             for (int i=0; i<=lastLocal; i++) {
  1788                 System.err.print("  " + i + ": ");
  1789                 if (defined.isMember(i)) {
  1790                     LocalVar var = lvar[i];
  1791                     if (var == null) {
  1792                         System.err.println("(none)");
  1793                     } else if (var.sym == null)
  1794                         System.err.println("UNKNOWN!");
  1795                     else
  1796                         System.err.println("" + var.sym + " of type " +
  1797                                            var.sym.erasure(types));
  1798                 } else {
  1799                     System.err.println("undefined");
  1802             if (nlocks != 0) {
  1803                 System.err.print(" locks:");
  1804                 for (int i=0; i<nlocks; i++) {
  1805                     System.err.print(" " + locks[i]);
  1807                 System.err.println();
  1812     static Type jsrReturnValue = new Type(TypeTags.INT, null);
  1815 /* **************************************************************************
  1816  * Local variables
  1817  ****************************************************************************/
  1819     /** A live range of a local variable. */
  1820     static class LocalVar {
  1821         final VarSymbol sym;
  1822         final char reg;
  1823         char start_pc = Character.MAX_VALUE;
  1824         char length = Character.MAX_VALUE;
  1825         LocalVar(VarSymbol v) {
  1826             this.sym = v;
  1827             this.reg = (char)v.adr;
  1829         public LocalVar dup() {
  1830             return new LocalVar(sym);
  1832         public String toString() {
  1833             return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
  1835     };
  1837     /** Local variables, indexed by register. */
  1838     LocalVar[] lvar;
  1840     /** Add a new local variable. */
  1841     private void addLocalVar(VarSymbol v) {
  1842         int adr = v.adr;
  1843         if (adr+1 >= lvar.length) {
  1844             int newlength = lvar.length << 1;
  1845             if (newlength <= adr) newlength = adr + 10;
  1846             LocalVar[] new_lvar = new LocalVar[newlength];
  1847             System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);
  1848             lvar = new_lvar;
  1850         assert lvar[adr] == null;
  1851         if (pendingJumps != null) resolvePending();
  1852         lvar[adr] = new LocalVar(v);
  1853         state.defined.excl(adr);
  1856     /** Set the current variable defined state. */
  1857     public void setDefined(Bits newDefined) {
  1858         if (alive && newDefined != state.defined) {
  1859             Bits diff = state.defined.dup().xorSet(newDefined);
  1860             for (int adr = diff.nextBit(0);
  1861                  adr >= 0;
  1862                  adr = diff.nextBit(adr+1)) {
  1863                 if (adr >= nextreg)
  1864                     state.defined.excl(adr);
  1865                 else if (state.defined.isMember(adr))
  1866                     setUndefined(adr);
  1867                 else
  1868                     setDefined(adr);
  1873     /** Mark a register as being (possibly) defined. */
  1874     public void setDefined(int adr) {
  1875         LocalVar v = lvar[adr];
  1876         if (v == null) {
  1877             state.defined.excl(adr);
  1878         } else {
  1879             state.defined.incl(adr);
  1880             if (cp < Character.MAX_VALUE) {
  1881                 if (v.start_pc == Character.MAX_VALUE)
  1882                     v.start_pc = (char)cp;
  1887     /** Mark a register as being undefined. */
  1888     public void setUndefined(int adr) {
  1889         state.defined.excl(adr);
  1890         if (adr < lvar.length &&
  1891             lvar[adr] != null &&
  1892             lvar[adr].start_pc != Character.MAX_VALUE) {
  1893             LocalVar v = lvar[adr];
  1894             char length = (char)(curPc() - v.start_pc);
  1895             if (length > 0 && length < Character.MAX_VALUE) {
  1896                 lvar[adr] = v.dup();
  1897                 v.length = length;
  1898                 putVar(v);
  1899             } else {
  1900                 v.start_pc = Character.MAX_VALUE;
  1905     /** End the scope of a variable. */
  1906     private void endScope(int adr) {
  1907         LocalVar v = lvar[adr];
  1908         if (v != null) {
  1909             lvar[adr] = null;
  1910             if (v.start_pc != Character.MAX_VALUE) {
  1911                 char length = (char)(curPc() - v.start_pc);
  1912                 if (length < Character.MAX_VALUE) {
  1913                     v.length = length;
  1914                     putVar(v);
  1915                     fillLocalVarPosition(v);
  1919         state.defined.excl(adr);
  1922     private void fillLocalVarPosition(LocalVar lv) {
  1923         if (lv == null || lv.sym == null
  1924                 || lv.sym.typeAnnotations == null)
  1925             return;
  1926         for (Attribute.TypeCompound ta : lv.sym.typeAnnotations) {
  1927             TypeAnnotationPosition p = ta.position;
  1928             while (p != null) {
  1929                 p.lvarOffset[0] = (int)lv.start_pc;
  1930                 p.lvarLength[0] = (int)lv.length;
  1931                 p.lvarIndex[0] = (int)lv.reg;
  1932                 p.isValidOffset = true;
  1933                 p = p.wildcard_position;
  1938     /** Put a live variable range into the buffer to be output to the
  1939      *  class file.
  1940      */
  1941     void putVar(LocalVar var) {
  1942         if (!varDebugInfo) return;
  1943         if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
  1944         if (varBuffer == null)
  1945             varBuffer = new LocalVar[20];
  1946         else if (varBufferSize >= varBuffer.length) {
  1947             LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2];
  1948             System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);
  1949             varBuffer = newVarBuffer;
  1951         varBuffer[varBufferSize++] = var;
  1954     /** Previously live local variables, to be put into the variable table. */
  1955     LocalVar[] varBuffer;
  1956     int varBufferSize;
  1958     /** Create a new local variable address and return it.
  1959      */
  1960     private int newLocal(int typecode) {
  1961         int reg = nextreg;
  1962         int w = width(typecode);
  1963         nextreg = reg + w;
  1964         if (nextreg > max_locals) max_locals = nextreg;
  1965         return reg;
  1968     private int newLocal(Type type) {
  1969         return newLocal(typecode(type));
  1972     public int newLocal(VarSymbol v) {
  1973         int reg = v.adr = newLocal(v.erasure(types));
  1974         addLocalVar(v);
  1975         return reg;
  1978     /** Start a set of fresh registers.
  1979      */
  1980     public void newRegSegment() {
  1981         nextreg = max_locals;
  1984     /** End scopes of all variables with registers >= first.
  1985      */
  1986     public void endScopes(int first) {
  1987         int prevNextReg = nextreg;
  1988         nextreg = first;
  1989         for (int i = nextreg; i < prevNextReg; i++) endScope(i);
  1992 /**************************************************************************
  1993  * static tables
  1994  *************************************************************************/
  1996     public static String mnem(int opcode) {
  1997         return Mneumonics.mnem[opcode];
  2000     private static class Mneumonics {
  2001         private final static String[] mnem = new String[ByteCodeCount];
  2002         static {
  2003             mnem[nop] = "nop";
  2004             mnem[aconst_null] = "aconst_null";
  2005             mnem[iconst_m1] = "iconst_m1";
  2006             mnem[iconst_0] = "iconst_0";
  2007             mnem[iconst_1] = "iconst_1";
  2008             mnem[iconst_2] = "iconst_2";
  2009             mnem[iconst_3] = "iconst_3";
  2010             mnem[iconst_4] = "iconst_4";
  2011             mnem[iconst_5] = "iconst_5";
  2012             mnem[lconst_0] = "lconst_0";
  2013             mnem[lconst_1] = "lconst_1";
  2014             mnem[fconst_0] = "fconst_0";
  2015             mnem[fconst_1] = "fconst_1";
  2016             mnem[fconst_2] = "fconst_2";
  2017             mnem[dconst_0] = "dconst_0";
  2018             mnem[dconst_1] = "dconst_1";
  2019             mnem[bipush] = "bipush";
  2020             mnem[sipush] = "sipush";
  2021             mnem[ldc1] = "ldc1";
  2022             mnem[ldc2] = "ldc2";
  2023             mnem[ldc2w] = "ldc2w";
  2024             mnem[iload] = "iload";
  2025             mnem[lload] = "lload";
  2026             mnem[fload] = "fload";
  2027             mnem[dload] = "dload";
  2028             mnem[aload] = "aload";
  2029             mnem[iload_0] = "iload_0";
  2030             mnem[lload_0] = "lload_0";
  2031             mnem[fload_0] = "fload_0";
  2032             mnem[dload_0] = "dload_0";
  2033             mnem[aload_0] = "aload_0";
  2034             mnem[iload_1] = "iload_1";
  2035             mnem[lload_1] = "lload_1";
  2036             mnem[fload_1] = "fload_1";
  2037             mnem[dload_1] = "dload_1";
  2038             mnem[aload_1] = "aload_1";
  2039             mnem[iload_2] = "iload_2";
  2040             mnem[lload_2] = "lload_2";
  2041             mnem[fload_2] = "fload_2";
  2042             mnem[dload_2] = "dload_2";
  2043             mnem[aload_2] = "aload_2";
  2044             mnem[iload_3] = "iload_3";
  2045             mnem[lload_3] = "lload_3";
  2046             mnem[fload_3] = "fload_3";
  2047             mnem[dload_3] = "dload_3";
  2048             mnem[aload_3] = "aload_3";
  2049             mnem[iaload] = "iaload";
  2050             mnem[laload] = "laload";
  2051             mnem[faload] = "faload";
  2052             mnem[daload] = "daload";
  2053             mnem[aaload] = "aaload";
  2054             mnem[baload] = "baload";
  2055             mnem[caload] = "caload";
  2056             mnem[saload] = "saload";
  2057             mnem[istore] = "istore";
  2058             mnem[lstore] = "lstore";
  2059             mnem[fstore] = "fstore";
  2060             mnem[dstore] = "dstore";
  2061             mnem[astore] = "astore";
  2062             mnem[istore_0] = "istore_0";
  2063             mnem[lstore_0] = "lstore_0";
  2064             mnem[fstore_0] = "fstore_0";
  2065             mnem[dstore_0] = "dstore_0";
  2066             mnem[astore_0] = "astore_0";
  2067             mnem[istore_1] = "istore_1";
  2068             mnem[lstore_1] = "lstore_1";
  2069             mnem[fstore_1] = "fstore_1";
  2070             mnem[dstore_1] = "dstore_1";
  2071             mnem[astore_1] = "astore_1";
  2072             mnem[istore_2] = "istore_2";
  2073             mnem[lstore_2] = "lstore_2";
  2074             mnem[fstore_2] = "fstore_2";
  2075             mnem[dstore_2] = "dstore_2";
  2076             mnem[astore_2] = "astore_2";
  2077             mnem[istore_3] = "istore_3";
  2078             mnem[lstore_3] = "lstore_3";
  2079             mnem[fstore_3] = "fstore_3";
  2080             mnem[dstore_3] = "dstore_3";
  2081             mnem[astore_3] = "astore_3";
  2082             mnem[iastore] = "iastore";
  2083             mnem[lastore] = "lastore";
  2084             mnem[fastore] = "fastore";
  2085             mnem[dastore] = "dastore";
  2086             mnem[aastore] = "aastore";
  2087             mnem[bastore] = "bastore";
  2088             mnem[castore] = "castore";
  2089             mnem[sastore] = "sastore";
  2090             mnem[pop] = "pop";
  2091             mnem[pop2] = "pop2";
  2092             mnem[dup] = "dup";
  2093             mnem[dup_x1] = "dup_x1";
  2094             mnem[dup_x2] = "dup_x2";
  2095             mnem[dup2] = "dup2";
  2096             mnem[dup2_x1] = "dup2_x1";
  2097             mnem[dup2_x2] = "dup2_x2";
  2098             mnem[swap] = "swap";
  2099             mnem[iadd] = "iadd";
  2100             mnem[ladd] = "ladd";
  2101             mnem[fadd] = "fadd";
  2102             mnem[dadd] = "dadd";
  2103             mnem[isub] = "isub";
  2104             mnem[lsub] = "lsub";
  2105             mnem[fsub] = "fsub";
  2106             mnem[dsub] = "dsub";
  2107             mnem[imul] = "imul";
  2108             mnem[lmul] = "lmul";
  2109             mnem[fmul] = "fmul";
  2110             mnem[dmul] = "dmul";
  2111             mnem[idiv] = "idiv";
  2112             mnem[ldiv] = "ldiv";
  2113             mnem[fdiv] = "fdiv";
  2114             mnem[ddiv] = "ddiv";
  2115             mnem[imod] = "imod";
  2116             mnem[lmod] = "lmod";
  2117             mnem[fmod] = "fmod";
  2118             mnem[dmod] = "dmod";
  2119             mnem[ineg] = "ineg";
  2120             mnem[lneg] = "lneg";
  2121             mnem[fneg] = "fneg";
  2122             mnem[dneg] = "dneg";
  2123             mnem[ishl] = "ishl";
  2124             mnem[lshl] = "lshl";
  2125             mnem[ishr] = "ishr";
  2126             mnem[lshr] = "lshr";
  2127             mnem[iushr] = "iushr";
  2128             mnem[lushr] = "lushr";
  2129             mnem[iand] = "iand";
  2130             mnem[land] = "land";
  2131             mnem[ior] = "ior";
  2132             mnem[lor] = "lor";
  2133             mnem[ixor] = "ixor";
  2134             mnem[lxor] = "lxor";
  2135             mnem[iinc] = "iinc";
  2136             mnem[i2l] = "i2l";
  2137             mnem[i2f] = "i2f";
  2138             mnem[i2d] = "i2d";
  2139             mnem[l2i] = "l2i";
  2140             mnem[l2f] = "l2f";
  2141             mnem[l2d] = "l2d";
  2142             mnem[f2i] = "f2i";
  2143             mnem[f2l] = "f2l";
  2144             mnem[f2d] = "f2d";
  2145             mnem[d2i] = "d2i";
  2146             mnem[d2l] = "d2l";
  2147             mnem[d2f] = "d2f";
  2148             mnem[int2byte] = "int2byte";
  2149             mnem[int2char] = "int2char";
  2150             mnem[int2short] = "int2short";
  2151             mnem[lcmp] = "lcmp";
  2152             mnem[fcmpl] = "fcmpl";
  2153             mnem[fcmpg] = "fcmpg";
  2154             mnem[dcmpl] = "dcmpl";
  2155             mnem[dcmpg] = "dcmpg";
  2156             mnem[ifeq] = "ifeq";
  2157             mnem[ifne] = "ifne";
  2158             mnem[iflt] = "iflt";
  2159             mnem[ifge] = "ifge";
  2160             mnem[ifgt] = "ifgt";
  2161             mnem[ifle] = "ifle";
  2162             mnem[if_icmpeq] = "if_icmpeq";
  2163             mnem[if_icmpne] = "if_icmpne";
  2164             mnem[if_icmplt] = "if_icmplt";
  2165             mnem[if_icmpge] = "if_icmpge";
  2166             mnem[if_icmpgt] = "if_icmpgt";
  2167             mnem[if_icmple] = "if_icmple";
  2168             mnem[if_acmpeq] = "if_acmpeq";
  2169             mnem[if_acmpne] = "if_acmpne";
  2170             mnem[goto_] = "goto_";
  2171             mnem[jsr] = "jsr";
  2172             mnem[ret] = "ret";
  2173             mnem[tableswitch] = "tableswitch";
  2174             mnem[lookupswitch] = "lookupswitch";
  2175             mnem[ireturn] = "ireturn";
  2176             mnem[lreturn] = "lreturn";
  2177             mnem[freturn] = "freturn";
  2178             mnem[dreturn] = "dreturn";
  2179             mnem[areturn] = "areturn";
  2180             mnem[return_] = "return_";
  2181             mnem[getstatic] = "getstatic";
  2182             mnem[putstatic] = "putstatic";
  2183             mnem[getfield] = "getfield";
  2184             mnem[putfield] = "putfield";
  2185             mnem[invokevirtual] = "invokevirtual";
  2186             mnem[invokespecial] = "invokespecial";
  2187             mnem[invokestatic] = "invokestatic";
  2188             mnem[invokeinterface] = "invokeinterface";
  2189             mnem[invokedynamic] = "invokedynamic";
  2190             mnem[new_] = "new_";
  2191             mnem[newarray] = "newarray";
  2192             mnem[anewarray] = "anewarray";
  2193             mnem[arraylength] = "arraylength";
  2194             mnem[athrow] = "athrow";
  2195             mnem[checkcast] = "checkcast";
  2196             mnem[instanceof_] = "instanceof_";
  2197             mnem[monitorenter] = "monitorenter";
  2198             mnem[monitorexit] = "monitorexit";
  2199             mnem[wide] = "wide";
  2200             mnem[multianewarray] = "multianewarray";
  2201             mnem[if_acmp_null] = "if_acmp_null";
  2202             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
  2203             mnem[goto_w] = "goto_w";
  2204             mnem[jsr_w] = "jsr_w";
  2205             mnem[breakpoint] = "breakpoint";

mercurial