< prev index next >

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

Print this page

  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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;
  29 import com.sun.tools.javac.code.Symbol.*;
  30 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  31 import com.sun.tools.javac.util.*;
  32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  33 
  34 import java.util.function.ToIntBiFunction;
  35 import java.util.function.ToIntFunction;
  36 
  37 import static com.sun.tools.javac.code.TypeTag.BOT;
  38 import static com.sun.tools.javac.code.TypeTag.INT;
  39 import static com.sun.tools.javac.jvm.ByteCodes.*;
  40 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
  41 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double;
  42 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Fieldref;
  43 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Float;
  44 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Integer;
  45 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InterfaceMethodref;
  46 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Long;
  47 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodHandle;
  48 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
  49 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Methodref;
  50 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_String;
  51 import static com.sun.tools.javac.jvm.UninitializedType.*;
  52 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
  53 import java.util.Arrays;
  54 
  55 /** An internal structure that corresponds to the code attribute of
  56  *  methods in a classfile. The class also provides some utility operations to
  57  *  generate bytecode instructions.
  58  *
  59  *  <p><b>This is NOT part of any supported API.
  60  *  If you write code that depends on this, you do so at your own risk.
  61  *  This code and its internal interfaces are subject to change or
  62  *  deletion without notice.</b>
  63  */
  64 public class Code {
  65 
  66     public final boolean debugCode;
  67     public final boolean needStackMap;
  68 
  69     public enum StackMapFormat {
  70         NONE,

 382             if (pendingStatPos != Position.NOPOS)
 383                 markStatBegin();
 384             if (pendingStackMap) {
 385                 pendingStackMap = false;
 386                 emitStackMap();
 387             }
 388             if (debugCode)
 389                 System.err.println("emit@" + cp + " stack=" +
 390                                    state.stacksize + ": " +
 391                                    mnem(op));
 392             emit1(op);
 393         }
 394     }
 395 
 396     void postop() {
 397         Assert.check(alive || isStatementStart());
 398     }
 399 
 400     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 401     */











 402     public void emitLdc(LoadableConstant constant) {
 403         int od = poolWriter.putConstant(constant);
 404         if (od <= 255) {
 405             emitop1(ldc1, od, constant);
 406         }
 407         else {
 408             emitop2(ldc2, od, constant);
 409         }
 410     }
 411 
 412     /** Emit a multinewarray instruction.
 413      */
 414     public void emitMultianewarray(int ndims, int type, Type arrayType) {
 415         emitop(multianewarray);
 416         if (!alive) return;
 417         emit2(type);
 418         emit1(ndims);
 419         state.pop(ndims);
 420         state.push(arrayType);
 421     }

1003         emitop2(op, od, constant);
1004     }
1005 
1006     public void emitop2(int op, int od) {
1007         emitop2(op, od, null);
1008     }
1009 
1010     public void emitop2(int op, int od, PoolConstant data) {
1011         emitop(op);
1012         if (!alive) return;
1013         emit2(od);
1014         switch (op) {
1015         case getstatic:
1016             state.push(((Symbol)data).erasure(types));
1017             break;
1018         case putstatic:
1019             state.pop(((Symbol)data).erasure(types));
1020             break;
1021         case new_: {
1022             Type t = (Type)data;
1023             state.push(uninitializedObject(t.tsym.erasure(types), cp-3));





1024             break;
1025         }
1026         case sipush:
1027             state.push(syms.intType);
1028             break;
1029         case if_acmp_null:
1030         case if_acmp_nonnull:
1031         case ifeq:
1032         case ifne:
1033         case iflt:
1034         case ifge:
1035         case ifgt:
1036         case ifle:
1037             state.pop(1);
1038             break;
1039         case if_icmpeq:
1040         case if_icmpne:
1041         case if_icmplt:
1042         case if_icmpge:
1043         case if_icmpgt:
1044         case if_icmple:
1045         case if_acmpeq:
1046         case if_acmpne:
1047             state.pop(2);
1048             break;
1049         case goto_:
1050             markDead();
1051             break;



1052         case putfield:
1053             state.pop(((Symbol)data).erasure(types));
1054             state.pop(1); // object ref
1055             break;
1056         case getfield:
1057             state.pop(1); // object ref
1058             state.push(((Symbol)data).erasure(types));
1059             break;
1060         case checkcast: {
1061             state.pop(1); // object ref
1062             Type t = types.erasure((Type)data);
1063             state.push(t);
1064             break; }
1065         case ldc2w:
1066             state.push(types.constantType((LoadableConstant)data));
1067             break;
1068         case instanceof_:
1069             state.pop(1);
1070             state.push(syms.intType);
1071             break;
1072         case ldc2:
1073             state.push(types.constantType((LoadableConstant)data));
1074             break;
1075         case jsr:
1076             break;
1077         default:
1078             throw new AssertionError(mnem(op));
1079         }
1080         // postop();
1081     }
1082 

1756             if (debugCode) System.err.println("   popping " + n);
1757             while (n > 0) {
1758                 stack[--stacksize] = null;
1759                 n--;
1760             }
1761         }
1762 
1763         void pop(Type t) {
1764             pop(width(t));
1765         }
1766 
1767         /** Force the top of the stack to be treated as this supertype
1768          *  of its current type. */
1769         void forceStackTop(Type t) {
1770             if (!alive) return;
1771             switch (t.getTag()) {
1772             case CLASS:
1773             case ARRAY:
1774                 int width = width(t);
1775                 Type old = stack[stacksize-width];
1776                 Assert.check(types.isSubtype(types.erasure(old),
1777                                        types.erasure(t)));
1778                 stack[stacksize-width] = t;
1779                 break;
1780             default:
1781             }
1782         }
1783 
1784         void markInitialized(UninitializedType old) {
1785             Type newtype = old.initializedType();
1786             for (int i=0; i<stacksize; i++) {
1787                 if (stack[i] == old) stack[i] = newtype;
1788             }
1789             for (int i=0; i<lvar.length; i++) {
1790                 LocalVar lv = lvar[i];
1791                 if (lv != null && lv.sym.type == old) {
1792                     VarSymbol sym = lv.sym;
1793                     sym = sym.clone(sym.owner);
1794                     sym.type = newtype;
1795                     LocalVar newlv = lvar[i] = new LocalVar(sym);
1796                     newlv.aliveRanges = lv.aliveRanges;
1797                 }

2431             mnem[invokespecial] = "invokespecial";
2432             mnem[invokestatic] = "invokestatic";
2433             mnem[invokeinterface] = "invokeinterface";
2434             mnem[invokedynamic] = "invokedynamic";
2435             mnem[new_] = "new_";
2436             mnem[newarray] = "newarray";
2437             mnem[anewarray] = "anewarray";
2438             mnem[arraylength] = "arraylength";
2439             mnem[athrow] = "athrow";
2440             mnem[checkcast] = "checkcast";
2441             mnem[instanceof_] = "instanceof_";
2442             mnem[monitorenter] = "monitorenter";
2443             mnem[monitorexit] = "monitorexit";
2444             mnem[wide] = "wide";
2445             mnem[multianewarray] = "multianewarray";
2446             mnem[if_acmp_null] = "if_acmp_null";
2447             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2448             mnem[goto_w] = "goto_w";
2449             mnem[jsr_w] = "jsr_w";
2450             mnem[breakpoint] = "breakpoint";


2451         }
2452     }
2453 }

  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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;
  29 import com.sun.tools.javac.code.Symbol.*;
  30 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  31 import com.sun.tools.javac.util.*;
  32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  33 
  34 import java.util.function.ToIntBiFunction;

  35 
  36 import static com.sun.tools.javac.code.TypeTag.BOT;
  37 import static com.sun.tools.javac.code.TypeTag.INT;
  38 import static com.sun.tools.javac.jvm.ByteCodes.*;











  39 import static com.sun.tools.javac.jvm.UninitializedType.*;
  40 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
  41 import java.util.Arrays;
  42 
  43 /** An internal structure that corresponds to the code attribute of
  44  *  methods in a classfile. The class also provides some utility operations to
  45  *  generate bytecode instructions.
  46  *
  47  *  <p><b>This is NOT part of any supported API.
  48  *  If you write code that depends on this, you do so at your own risk.
  49  *  This code and its internal interfaces are subject to change or
  50  *  deletion without notice.</b>
  51  */
  52 public class Code {
  53 
  54     public final boolean debugCode;
  55     public final boolean needStackMap;
  56 
  57     public enum StackMapFormat {
  58         NONE,

 370             if (pendingStatPos != Position.NOPOS)
 371                 markStatBegin();
 372             if (pendingStackMap) {
 373                 pendingStackMap = false;
 374                 emitStackMap();
 375             }
 376             if (debugCode)
 377                 System.err.println("emit@" + cp + " stack=" +
 378                                    state.stacksize + ": " +
 379                                    mnem(op));
 380             emit1(op);
 381         }
 382     }
 383 
 384     void postop() {
 385         Assert.check(alive || isStatementStart());
 386     }
 387 
 388     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 389     */
 390     public void emitLdc(LoadableConstant constant, int od) {
 391         if (od <= 255) {
 392             emitop1(ldc1, od, constant);
 393         }
 394         else {
 395             emitop2(ldc2, od, constant);
 396         }
 397     }
 398 
 399     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 400      */
 401     public void emitLdc(LoadableConstant constant) {
 402         int od = poolWriter.putConstant(constant);
 403         if (od <= 255) {
 404             emitop1(ldc1, od, constant);
 405         }
 406         else {
 407             emitop2(ldc2, od, constant);
 408         }
 409     }
 410 
 411     /** Emit a multinewarray instruction.
 412      */
 413     public void emitMultianewarray(int ndims, int type, Type arrayType) {
 414         emitop(multianewarray);
 415         if (!alive) return;
 416         emit2(type);
 417         emit1(ndims);
 418         state.pop(ndims);
 419         state.push(arrayType);
 420     }

1002         emitop2(op, od, constant);
1003     }
1004 
1005     public void emitop2(int op, int od) {
1006         emitop2(op, od, null);
1007     }
1008 
1009     public void emitop2(int op, int od, PoolConstant data) {
1010         emitop(op);
1011         if (!alive) return;
1012         emit2(od);
1013         switch (op) {
1014         case getstatic:
1015             state.push(((Symbol)data).erasure(types));
1016             break;
1017         case putstatic:
1018             state.pop(((Symbol)data).erasure(types));
1019             break;
1020         case new_: {
1021             Type t = (Type)data;
1022             state.push(uninitializedObject(t.tsym.erasure(types), cp - 3));
1023             break;
1024         }
1025         case aconst_init: {
1026             Type t = (Type)data;
1027             state.push(t.tsym.erasure(types));
1028             break;
1029         }
1030         case sipush:
1031             state.push(syms.intType);
1032             break;
1033         case if_acmp_null:
1034         case if_acmp_nonnull:
1035         case ifeq:
1036         case ifne:
1037         case iflt:
1038         case ifge:
1039         case ifgt:
1040         case ifle:
1041             state.pop(1);
1042             break;
1043         case if_icmpeq:
1044         case if_icmpne:
1045         case if_icmplt:
1046         case if_icmpge:
1047         case if_icmpgt:
1048         case if_icmple:
1049         case if_acmpeq:
1050         case if_acmpne:
1051             state.pop(2);
1052             break;
1053         case goto_:
1054             markDead();
1055             break;
1056         case withfield:
1057             state.pop(((Symbol)data).erasure(types));
1058             break;
1059         case putfield:
1060             state.pop(((Symbol)data).erasure(types));
1061             state.pop(1); // object ref
1062             break;
1063         case getfield:
1064             state.pop(1); // object ref
1065             state.push(((Symbol)data).erasure(types));
1066             break;
1067         case checkcast: {
1068             state.pop(1); // object ref
1069             Type t = types.erasure(data instanceof  ConstantPoolQType ? ((ConstantPoolQType)data).type: (Type)data);
1070             state.push(t);
1071             break; }
1072         case ldc2w:
1073             state.push(types.constantType((LoadableConstant)data));
1074             break;
1075         case instanceof_:
1076             state.pop(1);
1077             state.push(syms.intType);
1078             break;
1079         case ldc2:
1080             state.push(types.constantType((LoadableConstant)data));
1081             break;
1082         case jsr:
1083             break;
1084         default:
1085             throw new AssertionError(mnem(op));
1086         }
1087         // postop();
1088     }
1089 

1763             if (debugCode) System.err.println("   popping " + n);
1764             while (n > 0) {
1765                 stack[--stacksize] = null;
1766                 n--;
1767             }
1768         }
1769 
1770         void pop(Type t) {
1771             pop(width(t));
1772         }
1773 
1774         /** Force the top of the stack to be treated as this supertype
1775          *  of its current type. */
1776         void forceStackTop(Type t) {
1777             if (!alive) return;
1778             switch (t.getTag()) {
1779             case CLASS:
1780             case ARRAY:
1781                 int width = width(t);
1782                 Type old = stack[stacksize-width];
1783                 Assert.check(types.isSubtype(types.erasure(old), types.erasure(t)) ||
1784                         (old.isPrimitiveClass() != t.isPrimitiveClass() && types.isConvertible(types.erasure(old), types.erasure(t))));
1785                 stack[stacksize-width] = t;
1786                 break;
1787             default:
1788             }
1789         }
1790 
1791         void markInitialized(UninitializedType old) {
1792             Type newtype = old.initializedType();
1793             for (int i=0; i<stacksize; i++) {
1794                 if (stack[i] == old) stack[i] = newtype;
1795             }
1796             for (int i=0; i<lvar.length; i++) {
1797                 LocalVar lv = lvar[i];
1798                 if (lv != null && lv.sym.type == old) {
1799                     VarSymbol sym = lv.sym;
1800                     sym = sym.clone(sym.owner);
1801                     sym.type = newtype;
1802                     LocalVar newlv = lvar[i] = new LocalVar(sym);
1803                     newlv.aliveRanges = lv.aliveRanges;
1804                 }

2438             mnem[invokespecial] = "invokespecial";
2439             mnem[invokestatic] = "invokestatic";
2440             mnem[invokeinterface] = "invokeinterface";
2441             mnem[invokedynamic] = "invokedynamic";
2442             mnem[new_] = "new_";
2443             mnem[newarray] = "newarray";
2444             mnem[anewarray] = "anewarray";
2445             mnem[arraylength] = "arraylength";
2446             mnem[athrow] = "athrow";
2447             mnem[checkcast] = "checkcast";
2448             mnem[instanceof_] = "instanceof_";
2449             mnem[monitorenter] = "monitorenter";
2450             mnem[monitorexit] = "monitorexit";
2451             mnem[wide] = "wide";
2452             mnem[multianewarray] = "multianewarray";
2453             mnem[if_acmp_null] = "if_acmp_null";
2454             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2455             mnem[goto_w] = "goto_w";
2456             mnem[jsr_w] = "jsr_w";
2457             mnem[breakpoint] = "breakpoint";
2458             mnem[aconst_init] = "aconst_init";
2459             mnem[withfield] = "withfield";
2460         }
2461     }
2462 }
< prev index next >