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 */ 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.util.*; 31 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 32 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; 37 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 { 48 49 public final boolean debugCode; 50 public final boolean needStackMap; 51 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 } 68 69 final Types types; 70 final Symtab syms; 71 72 /*---------- classfile fields: --------------- */ 73 74 /** The maximum stack size. 75 */ 76 public int max_stack = 0; 77 78 /** The maximum number of local variable slots. 79 */ 80 public int max_locals = 0; 81 82 /** The code buffer. 83 */ 84 public byte[] code = new byte[64]; 85 86 /** the current code pointer. 87 */ 88 public int cp = 0; 89 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 } 108 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[]>(); 113 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 118 119 /** The CharacterRangeTable 120 */ 121 public CRTable crt; 122 123 /*---------- internal fields: --------------- */ 124 125 /** Are we generating code with jumps >= 32K? 126 */ 127 public boolean fatcode; 128 129 /** Code generation enabled? 130 */ 131 private boolean alive = true; 132 133 /** The current machine state (registers and stack). 134 */ 135 State state; 136 137 /** Is it forbidden to compactify code, because something is 138 * pointing to current location? 139 */ 140 private boolean fixedPc = false; 141 142 /** The next available register. 143 */ 144 public int nextreg = 0; 145 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; 150 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; 157 158 /** Set true when a stackMap is needed at the current PC. */ 159 boolean pendingStackMap = false; 160 161 /** The stack map format to be generated. */ 162 StackMapFormat stackMap; 163 164 /** Switch: emit variable debug info. 165 */ 166 boolean varDebugInfo; 167 168 /** Switch: emit line number info. 169 */ 170 boolean lineDebugInfo; 171 172 /** Emit line number info if map supplied 173 */ 174 Position.LineMap lineMap; 175 176 /** The constant pool of the current class. 177 */ 178 final Pool pool; 179 180 final MethodSymbol meth; 181 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 } 217 218 219 /* ************************************************************************** 220 * Typecodes & related stuff 221 ****************************************************************************/ 222 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 FUNCTION: 241 case BOT: 242 case TYPEVAR: 243 case UNINITIALIZED_THIS: 244 case UNINITIALIZED_OBJECT: 245 return OBJECTcode; 246 default: throw new AssertionError("typecode " + type.tag); 247 } 248 } 249 250 /** Collapse type code for subtypes of int to INTcode. 251 */ 252 public static int truncate(int tc) { 253 switch (tc) { 254 case BYTEcode: case SHORTcode: case CHARcode: return INTcode; 255 default: return tc; 256 } 257 } 258 259 /** The width in bytes of objects of the type. 260 */ 261 public static int width(int typecode) { 262 switch (typecode) { 263 case LONGcode: case DOUBLEcode: return 2; 264 case VOIDcode: return 0; 265 default: return 1; 266 } 267 } 268 269 public static int width(Type type) { 270 return type == null ? 1 : width(typecode(type)); 271 } 272 273 /** The total width taken up by a vector of objects. 274 */ 275 public static int width(List<Type> types) { 276 int w = 0; 277 for (List<Type> l = types; l.nonEmpty(); l = l.tail) 278 w = w + width(l.head); 279 return w; 280 } 281 282 /** Given a type, return its code for allocating arrays of that type. 283 */ 284 public static int arraycode(Type type) { 285 switch (type.tag) { 286 case BYTE: return 8; 287 case BOOLEAN: return 4; 288 case SHORT: return 9; 289 case CHAR: return 5; 290 case INT: return 10; 291 case LONG: return 11; 292 case FLOAT: return 6; 293 case DOUBLE: return 7; 294 case CLASS: return 0; 295 case ARRAY: return 1; 296 default: throw new AssertionError("arraycode " + type); 297 } 298 } 299 300 301 /* ************************************************************************** 302 * Emit code 303 ****************************************************************************/ 304 305 /** The current output code pointer. 306 */ 307 public int curPc() { 308 if (pendingJumps != null) resolvePending(); 309 if (pendingStatPos != Position.NOPOS) markStatBegin(); 310 fixedPc = true; 311 return cp; 312 } 313 314 /** Emit a byte of code. 315 */ 316 private void emit1(int od) { 317 if (!alive) return; 318 if (cp == code.length) { 319 byte[] newcode = new byte[cp * 2]; 320 System.arraycopy(code, 0, newcode, 0, cp); 321 code = newcode; 322 } 323 code[cp++] = (byte)od; 324 } 325 326 /** Emit two bytes of code. 327 */ 328 private void emit2(int od) { 329 if (!alive) return; 330 if (cp + 2 > code.length) { 331 emit1(od >> 8); 332 emit1(od); 333 } else { 334 code[cp++] = (byte)(od >> 8); 335 code[cp++] = (byte)od; 336 } 337 } 338 339 /** Emit four bytes of code. 340 */ 341 public void emit4(int od) { 342 if (!alive) return; 343 if (cp + 4 > code.length) { 344 emit1(od >> 24); 345 emit1(od >> 16); 346 emit1(od >> 8); 347 emit1(od); 348 } else { 349 code[cp++] = (byte)(od >> 24); 350 code[cp++] = (byte)(od >> 16); 351 code[cp++] = (byte)(od >> 8); 352 code[cp++] = (byte)od; 353 } 354 } 355 356 /** Emit an opcode. 357 */ 358 private void emitop(int op) { 359 if (pendingJumps != null) resolvePending(); 360 if (alive) { 361 if (pendingStatPos != Position.NOPOS) 362 markStatBegin(); 363 if (pendingStackMap) { 364 pendingStackMap = false; 365 emitStackMap(); 366 } 367 if (debugCode) 368 System.err.println("emit@" + cp + " stack=" + 369 state.stacksize + ": " + 370 mnem(op)); 371 emit1(op); 372 } 373 } 374 375 void postop() { 376 assert alive || state.stacksize == 0; 377 } 378 379 /** Emit a multinewarray instruction. 380 */ 381 public void emitMultianewarray(int ndims, int type, Type arrayType) { 382 emitop(multianewarray); 383 if (!alive) return; 384 emit2(type); 385 emit1(ndims); 386 state.pop(ndims); 387 state.push(arrayType); 388 } 389 390 /** Emit newarray. 391 */ 392 public void emitNewarray(int elemcode, Type arrayType) { 393 emitop(newarray); 394 if (!alive) return; 395 emit1(elemcode); 396 state.pop(1); // count 397 state.push(arrayType); 398 } 399 400 /** Emit anewarray. 401 */ 402 public void emitAnewarray(int od, Type arrayType) { 403 emitop(anewarray); 404 if (!alive) return; 405 emit2(od); 406 state.pop(1); 407 state.push(arrayType); 408 } 409 410 /** Emit an invokeinterface instruction. 411 */ 412 public void emitInvokeinterface(int meth, Type mtype) { 413 int argsize = width(mtype.getParameterTypes()); 414 emitop(invokeinterface); 415 if (!alive) return; 416 emit2(meth); 417 emit1(argsize + 1); 418 emit1(0); 419 state.pop(argsize + 1); 420 state.push(mtype.getReturnType()); 421 } 422 423 /** Emit an invokespecial instruction. 424 */ 425 public void emitInvokespecial(int meth, Type mtype) { 426 int argsize = width(mtype.getParameterTypes()); 427 emitop(invokespecial); 428 if (!alive) return; 429 emit2(meth); 430 Symbol sym = (Symbol)pool.pool[meth]; 431 state.pop(argsize); 432 if (sym.isConstructor()) 433 state.markInitialized((UninitializedType)state.peek()); 434 state.pop(1); 435 state.push(mtype.getReturnType()); 436 } 437 438 /** Emit an invokestatic instruction. 439 */ 440 public void emitInvokestatic(int meth, Type mtype) { 441 int argsize = width(mtype.getParameterTypes()); 442 emitop(invokestatic); 443 if (!alive) return; 444 emit2(meth); 445 state.pop(argsize); 446 state.push(mtype.getReturnType()); 447 } 448 449 /** Emit an invokevirtual instruction. 450 */ 451 public void emitInvokevirtual(int meth, Type mtype) { 452 int argsize = width(mtype.getParameterTypes()); 453 emitop(invokevirtual); 454 if (!alive) return; 455 emit2(meth); 456 state.pop(argsize + 1); 457 state.push(mtype.getReturnType()); 458 } 459 460 /** Emit an invokedynamic instruction. 461 */ 462 public void emitInvokedynamic(int desc, Type mtype) { 463 // N.B. this format is under consideration by the JSR 292 EG 464 int argsize = width(mtype.getParameterTypes()); 465 emitop(invokedynamic); 466 if (!alive) return; 467 emit2(desc); 468 emit2(0); 469 state.pop(argsize); 470 state.push(mtype.getReturnType()); 471 } 472 473 /** Emit an opcode with no operand field. 474 */ 475 public void emitop0(int op) { 476 emitop(op); 477 if (!alive) return; 478 switch (op) { 479 case aaload: { 480 state.pop(1);// index 481 Type a = state.stack[state.stacksize-1]; 482 state.pop(1); 483 state.push(types.erasure(types.elemtype(a))); } 484 break; 485 case goto_: 486 markDead(); 487 break; 488 case nop: 489 case ineg: 490 case lneg: 491 case fneg: 492 case dneg: 493 break; 494 case aconst_null: 495 state.push(syms.botType); 496 break; 497 case iconst_m1: 498 case iconst_0: 499 case iconst_1: 500 case iconst_2: 501 case iconst_3: 502 case iconst_4: 503 case iconst_5: 504 case iload_0: 505 case iload_1: 506 case iload_2: 507 case iload_3: 508 state.push(syms.intType); 509 break; 510 case lconst_0: 511 case lconst_1: 512 case lload_0: 513 case lload_1: 514 case lload_2: 515 case lload_3: 516 state.push(syms.longType); 517 break; 518 case fconst_0: 519 case fconst_1: 520 case fconst_2: 521 case fload_0: 522 case fload_1: 523 case fload_2: 524 case fload_3: 525 state.push(syms.floatType); 526 break; 527 case dconst_0: 528 case dconst_1: 529 case dload_0: 530 case dload_1: 531 case dload_2: 532 case dload_3: 533 state.push(syms.doubleType); 534 break; 535 case aload_0: 536 state.push(lvar[0].sym.type); 537 break; 538 case aload_1: 539 state.push(lvar[1].sym.type); 540 break; 541 case aload_2: 542 state.push(lvar[2].sym.type); 543 break; 544 case aload_3: 545 state.push(lvar[3].sym.type); 546 break; 547 case iaload: 548 case baload: 549 case caload: 550 case saload: 551 state.pop(2); 552 state.push(syms.intType); 553 break; 554 case laload: 555 state.pop(2); 556 state.push(syms.longType); 557 break; 558 case faload: 559 state.pop(2); 560 state.push(syms.floatType); 561 break; 562 case daload: 563 state.pop(2); 564 state.push(syms.doubleType); 565 break; 566 case istore_0: 567 case istore_1: 568 case istore_2: 569 case istore_3: 570 case fstore_0: 571 case fstore_1: 572 case fstore_2: 573 case fstore_3: 574 case astore_0: 575 case astore_1: 576 case astore_2: 577 case astore_3: 578 case pop: 579 case lshr: 580 case lshl: 581 case lushr: 582 state.pop(1); 583 break; 584 case areturn: 585 case ireturn: 586 case freturn: 587 assert state.nlocks == 0; 588 state.pop(1); 589 markDead(); 590 break; 591 case athrow: 592 state.pop(1); 593 markDead(); 594 break; 595 case lstore_0: 596 case lstore_1: 597 case lstore_2: 598 case lstore_3: 599 case dstore_0: 600 case dstore_1: 601 case dstore_2: 602 case dstore_3: 603 case pop2: 604 state.pop(2); 605 break; 606 case lreturn: 607 case dreturn: 608 assert state.nlocks == 0; 609 state.pop(2); 610 markDead(); 611 break; 612 case dup: 613 state.push(state.stack[state.stacksize-1]); 614 break; 615 case return_: 616 assert state.nlocks == 0; 617 markDead(); 618 break; 619 case arraylength: 620 state.pop(1); 621 state.push(syms.intType); 622 break; 623 case isub: 624 case iadd: 625 case imul: 626 case idiv: 627 case imod: 628 case ishl: 629 case ishr: 630 case iushr: 631 case iand: 632 case ior: 633 case ixor: 634 state.pop(1); 635 // state.pop(1); 636 // state.push(syms.intType); 637 break; 638 case aastore: 639 state.pop(3); 640 break; 641 case land: 642 case lor: 643 case lxor: 644 case lmod: 645 case ldiv: 646 case lmul: 647 case lsub: 648 case ladd: 649 state.pop(2); 650 break; 651 case lcmp: 652 state.pop(4); 653 state.push(syms.intType); 654 break; 655 case l2i: 656 state.pop(2); 657 state.push(syms.intType); 658 break; 659 case i2l: 660 state.pop(1); 661 state.push(syms.longType); 662 break; 663 case i2f: 664 state.pop(1); 665 state.push(syms.floatType); 666 break; 667 case i2d: 668 state.pop(1); 669 state.push(syms.doubleType); 670 break; 671 case l2f: 672 state.pop(2); 673 state.push(syms.floatType); 674 break; 675 case l2d: 676 state.pop(2); 677 state.push(syms.doubleType); 678 break; 679 case f2i: 680 state.pop(1); 681 state.push(syms.intType); 682 break; 683 case f2l: 684 state.pop(1); 685 state.push(syms.longType); 686 break; 687 case f2d: 688 state.pop(1); 689 state.push(syms.doubleType); 690 break; 691 case d2i: 692 state.pop(2); 693 state.push(syms.intType); 694 break; 695 case d2l: 696 state.pop(2); 697 state.push(syms.longType); 698 break; 699 case d2f: 700 state.pop(2); 701 state.push(syms.floatType); 702 break; 703 case tableswitch: 704 case lookupswitch: 705 state.pop(1); 706 // the caller is responsible for patching up the state 707 break; 708 case dup_x1: { 709 Type val1 = state.pop1(); 710 Type val2 = state.pop1(); 711 state.push(val1); 712 state.push(val2); 713 state.push(val1); 714 break; 715 } 716 case bastore: 717 state.pop(3); 718 break; 719 case int2byte: 720 case int2char: 721 case int2short: 722 break; 723 case fmul: 724 case fadd: 725 case fsub: 726 case fdiv: 727 case fmod: 728 state.pop(1); 729 break; 730 case castore: 731 case iastore: 732 case fastore: 733 case sastore: 734 state.pop(3); 735 break; 736 case lastore: 737 case dastore: 738 state.pop(4); 739 break; 740 case dup2: 741 if (state.stack[state.stacksize-1] != null) { 742 Type value1 = state.pop1(); 743 Type value2 = state.pop1(); 744 state.push(value2); 745 state.push(value1); 746 state.push(value2); 747 state.push(value1); 748 } else { 749 Type value = state.pop2(); 750 state.push(value); 751 state.push(value); 752 } 753 break; 754 case dup2_x1: 755 if (state.stack[state.stacksize-1] != null) { 756 Type value1 = state.pop1(); 757 Type value2 = state.pop1(); 758 Type value3 = state.pop1(); 759 state.push(value2); 760 state.push(value1); 761 state.push(value3); 762 state.push(value2); 763 state.push(value1); 764 } else { 765 Type value1 = state.pop2(); 766 Type value2 = state.pop1(); 767 state.push(value1); 768 state.push(value2); 769 state.push(value1); 770 } 771 break; 772 case dup2_x2: 773 if (state.stack[state.stacksize-1] != null) { 774 Type value1 = state.pop1(); 775 Type value2 = state.pop1(); 776 if (state.stack[state.stacksize-1] != null) { 777 // form 1 778 Type value3 = state.pop1(); 779 Type value4 = state.pop1(); 780 state.push(value2); 781 state.push(value1); 782 state.push(value4); 783 state.push(value3); 784 state.push(value2); 785 state.push(value1); 786 } else { 787 // form 3 788 Type value3 = state.pop2(); 789 state.push(value2); 790 state.push(value1); 791 state.push(value3); 792 state.push(value2); 793 state.push(value1); 794 } 795 } else { 796 Type value1 = state.pop2(); 797 if (state.stack[state.stacksize-1] != null) { 798 // form 2 799 Type value2 = state.pop1(); 800 Type value3 = state.pop1(); 801 state.push(value1); 802 state.push(value3); 803 state.push(value2); 804 state.push(value1); 805 } else { 806 // form 4 807 Type value2 = state.pop2(); 808 state.push(value1); 809 state.push(value2); 810 state.push(value1); 811 } 812 } 813 break; 814 case dup_x2: { 815 Type value1 = state.pop1(); 816 if (state.stack[state.stacksize-1] != null) { 817 // form 1 818 Type value2 = state.pop1(); 819 Type value3 = state.pop1(); 820 state.push(value1); 821 state.push(value3); 822 state.push(value2); 823 state.push(value1); 824 } else { 825 // form 2 826 Type value2 = state.pop2(); 827 state.push(value1); 828 state.push(value2); 829 state.push(value1); 830 } 831 } 832 break; 833 case fcmpl: 834 case fcmpg: 835 state.pop(2); 836 state.push(syms.intType); 837 break; 838 case dcmpl: 839 case dcmpg: 840 state.pop(4); 841 state.push(syms.intType); 842 break; 843 case swap: { 844 Type value1 = state.pop1(); 845 Type value2 = state.pop1(); 846 state.push(value1); 847 state.push(value2); 848 break; 849 } 850 case dadd: 851 case dsub: 852 case dmul: 853 case ddiv: 854 case dmod: 855 state.pop(2); 856 break; 857 case ret: 858 markDead(); 859 break; 860 case wide: 861 // must be handled by the caller. 862 return; 863 case monitorenter: 864 case monitorexit: 865 state.pop(1); 866 break; 867 868 default: 869 throw new AssertionError(mnem(op)); 870 } 871 postop(); 872 } 873 874 /** Emit an opcode with a one-byte operand field. 875 */ 876 public void emitop1(int op, int od) { 877 emitop(op); 878 if (!alive) return; 879 emit1(od); 880 switch (op) { 881 case bipush: 882 state.push(syms.intType); 883 break; 884 case ldc1: 885 state.push(typeForPool(pool.pool[od])); 886 break; 887 default: 888 throw new AssertionError(mnem(op)); 889 } 890 postop(); 891 } 892 893 /** The type of a constant pool entry. */ 894 private Type typeForPool(Object o) { 895 if (o instanceof Integer) return syms.intType; 896 if (o instanceof Float) return syms.floatType; 897 if (o instanceof String) return syms.stringType; 898 if (o instanceof Long) return syms.longType; 899 if (o instanceof Double) return syms.doubleType; 900 if (o instanceof ClassSymbol) return syms.classType; 901 if (o instanceof Type.ArrayType) return syms.classType; 902 throw new AssertionError(o); 903 } 904 905 /** Emit an opcode with a one-byte operand field; 906 * widen if field does not fit in a byte. 907 */ 908 public void emitop1w(int op, int od) { 909 if (od > 0xFF) { 910 emitop(wide); 911 emitop(op); 912 emit2(od); 913 } else { 914 emitop(op); 915 emit1(od); 916 } 917 if (!alive) return; 918 switch (op) { 919 case iload: 920 state.push(syms.intType); 921 break; 922 case lload: 923 state.push(syms.longType); 924 break; 925 case fload: 926 state.push(syms.floatType); 927 break; 928 case dload: 929 state.push(syms.doubleType); 930 break; 931 case aload: 932 state.push(lvar[od].sym.type); 933 break; 934 case lstore: 935 case dstore: 936 state.pop(2); 937 break; 938 case istore: 939 case fstore: 940 case astore: 941 state.pop(1); 942 break; 943 case ret: 944 markDead(); 945 break; 946 default: 947 throw new AssertionError(mnem(op)); 948 } 949 postop(); 950 } 951 952 /** Emit an opcode with two one-byte operand fields; 953 * widen if either field does not fit in a byte. 954 */ 955 public void emitop1w(int op, int od1, int od2) { 956 if (od1 > 0xFF || od2 < -128 || od2 > 127) { 957 emitop(wide); 958 emitop(op); 959 emit2(od1); 960 emit2(od2); 961 } else { 962 emitop(op); 963 emit1(od1); 964 emit1(od2); 965 } 966 if (!alive) return; 967 switch (op) { 968 case iinc: 969 break; 970 default: 971 throw new AssertionError(mnem(op)); 972 } 973 } 974 975 /** Emit an opcode with a two-byte operand field. 976 */ 977 public void emitop2(int op, int od) { 978 emitop(op); 979 if (!alive) return; 980 emit2(od); 981 switch (op) { 982 case getstatic: 983 state.push(((Symbol)(pool.pool[od])).erasure(types)); 984 break; 985 case putstatic: 986 state.pop(((Symbol)(pool.pool[od])).erasure(types)); 987 break; 988 case new_: 989 state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3)); 990 break; 991 case sipush: 992 state.push(syms.intType); 993 break; 994 case if_acmp_null: 995 case if_acmp_nonnull: 996 case ifeq: 997 case ifne: 998 case iflt: 999 case ifge: 1000 case ifgt: 1001 case ifle: 1002 state.pop(1); 1003 break; 1004 case if_icmpeq: 1005 case if_icmpne: 1006 case if_icmplt: 1007 case if_icmpge: 1008 case if_icmpgt: 1009 case if_icmple: 1010 case if_acmpeq: 1011 case if_acmpne: 1012 state.pop(2); 1013 break; 1014 case goto_: 1015 markDead(); 1016 break; 1017 case putfield: 1018 state.pop(((Symbol)(pool.pool[od])).erasure(types)); 1019 state.pop(1); // object ref 1020 break; 1021 case getfield: 1022 state.pop(1); // object ref 1023 state.push(((Symbol)(pool.pool[od])).erasure(types)); 1024 break; 1025 case checkcast: { 1026 state.pop(1); // object ref 1027 Object o = pool.pool[od]; 1028 Type t = (o instanceof Symbol) 1029 ? ((Symbol)o).erasure(types) 1030 : types.erasure(((Type)o)); 1031 state.push(t); 1032 break; } 1033 case ldc2w: 1034 state.push(typeForPool(pool.pool[od])); 1035 break; 1036 case instanceof_: 1037 state.pop(1); 1038 state.push(syms.intType); 1039 break; 1040 case ldc2: 1041 state.push(typeForPool(pool.pool[od])); 1042 break; 1043 case jsr: 1044 break; 1045 default: 1046 throw new AssertionError(mnem(op)); 1047 } 1048 // postop(); 1049 } 1050 1051 /** Emit an opcode with a four-byte operand field. 1052 */ 1053 public void emitop4(int op, int od) { 1054 emitop(op); 1055 if (!alive) return; 1056 emit4(od); 1057 switch (op) { 1058 case goto_w: 1059 markDead(); 1060 break; 1061 case jsr_w: 1062 break; 1063 default: 1064 throw new AssertionError(mnem(op)); 1065 } 1066 // postop(); 1067 } 1068 1069 /** Align code pointer to next `incr' boundary. 1070 */ 1071 public void align(int incr) { 1072 if (alive) 1073 while (cp % incr != 0) emitop0(nop); 1074 } 1075 1076 /** Place a byte into code at address pc. Pre: pc + 1 <= cp. 1077 */ 1078 private void put1(int pc, int op) { 1079 code[pc] = (byte)op; 1080 } 1081 1082 /** Place two bytes into code at address pc. Pre: pc + 2 <= cp. 1083 */ 1084 private void put2(int pc, int od) { 1085 // pre: pc + 2 <= cp 1086 put1(pc, od >> 8); 1087 put1(pc+1, od); 1088 } 1089 1090 /** Place four bytes into code at address pc. Pre: pc + 4 <= cp. 1091 */ 1092 public void put4(int pc, int od) { 1093 // pre: pc + 4 <= cp 1094 put1(pc , od >> 24); 1095 put1(pc+1, od >> 16); 1096 put1(pc+2, od >> 8); 1097 put1(pc+3, od); 1098 } 1099 1100 /** Return code byte at position pc as an unsigned int. 1101 */ 1102 private int get1(int pc) { 1103 return code[pc] & 0xFF; 1104 } 1105 1106 /** Return two code bytes at position pc as an unsigned int. 1107 */ 1108 private int get2(int pc) { 1109 return (get1(pc) << 8) | get1(pc+1); 1110 } 1111 1112 /** Return four code bytes at position pc as an int. 1113 */ 1114 public int get4(int pc) { 1115 // pre: pc + 4 <= cp 1116 return 1117 (get1(pc) << 24) | 1118 (get1(pc+1) << 16) | 1119 (get1(pc+2) << 8) | 1120 (get1(pc+3)); 1121 } 1122 1123 /** Is code generation currently enabled? 1124 */ 1125 public boolean isAlive() { 1126 return alive || pendingJumps != null; 1127 } 1128 1129 /** Switch code generation on/off. 1130 */ 1131 public void markDead() { 1132 alive = false; 1133 } 1134 1135 /** Declare an entry point; return current code pointer 1136 */ 1137 public int entryPoint() { 1138 int pc = curPc(); 1139 alive = true; 1140 pendingStackMap = needStackMap; 1141 return pc; 1142 } 1143 1144 /** Declare an entry point with initial state; 1145 * return current code pointer 1146 */ 1147 public int entryPoint(State state) { 1148 int pc = curPc(); 1149 alive = true; 1150 this.state = state.dup(); 1151 assert state.stacksize <= max_stack; 1152 if (debugCode) System.err.println("entry point " + state); 1153 pendingStackMap = needStackMap; 1154 return pc; 1155 } 1156 1157 /** Declare an entry point with initial state plus a pushed value; 1158 * return current code pointer 1159 */ 1160 public int entryPoint(State state, Type pushed) { 1161 int pc = curPc(); 1162 alive = true; 1163 this.state = state.dup(); 1164 assert state.stacksize <= max_stack; 1165 this.state.push(pushed); 1166 if (debugCode) System.err.println("entry point " + state); 1167 pendingStackMap = needStackMap; 1168 return pc; 1169 } 1170 1171 1172 /************************************************************************** 1173 * Stack map generation 1174 *************************************************************************/ 1175 1176 /** An entry in the stack map. */ 1177 static class StackMapFrame { 1178 int pc; 1179 Type[] locals; 1180 Type[] stack; 1181 } 1182 1183 /** A buffer of cldc stack map entries. */ 1184 StackMapFrame[] stackMapBuffer = null; 1185 1186 /** A buffer of compressed StackMapTable entries. */ 1187 StackMapTableFrame[] stackMapTableBuffer = null; 1188 int stackMapBufferSize = 0; 1189 1190 /** The last PC at which we generated a stack map. */ 1191 int lastStackMapPC = -1; 1192 1193 /** The last stack map frame in StackMapTable. */ 1194 StackMapFrame lastFrame = null; 1195 1196 /** The stack map frame before the last one. */ 1197 StackMapFrame frameBeforeLast = null; 1198 1199 /** Emit a stack map entry. */ 1200 public void emitStackMap() { 1201 int pc = curPc(); 1202 if (!needStackMap) return; 1203 1204 1205 1206 switch (stackMap) { 1207 case CLDC: 1208 emitCLDCStackMap(pc, getLocalsSize()); 1209 break; 1210 case JSR202: 1211 emitStackMapFrame(pc, getLocalsSize()); 1212 break; 1213 default: 1214 throw new AssertionError("Should have chosen a stackmap format"); 1215 } 1216 // DEBUG code follows 1217 if (debugCode) state.dump(pc); 1218 } 1219 1220 private int getLocalsSize() { 1221 int nextLocal = 0; 1222 for (int i=max_locals-1; i>=0; i--) { 1223 if (state.defined.isMember(i) && lvar[i] != null) { 1224 nextLocal = i + width(lvar[i].sym.erasure(types)); 1225 break; 1226 } 1227 } 1228 return nextLocal; 1229 } 1230 1231 /** Emit a CLDC stack map frame. */ 1232 void emitCLDCStackMap(int pc, int localsSize) { 1233 if (lastStackMapPC == pc) { 1234 // drop existing stackmap at this offset 1235 stackMapBuffer[--stackMapBufferSize] = null; 1236 } 1237 lastStackMapPC = pc; 1238 1239 if (stackMapBuffer == null) { 1240 stackMapBuffer = new StackMapFrame[20]; 1241 } else if (stackMapBuffer.length == stackMapBufferSize) { 1242 StackMapFrame[] newStackMapBuffer = 1243 new StackMapFrame[stackMapBufferSize << 1]; 1244 System.arraycopy(stackMapBuffer, 0, newStackMapBuffer, 1245 0, stackMapBufferSize); 1246 stackMapBuffer = newStackMapBuffer; 1247 } 1248 StackMapFrame frame = 1249 stackMapBuffer[stackMapBufferSize++] = new StackMapFrame(); 1250 frame.pc = pc; 1251 1252 frame.locals = new Type[localsSize]; 1253 for (int i=0; i<localsSize; i++) { 1254 if (state.defined.isMember(i) && lvar[i] != null) { 1255 Type vtype = lvar[i].sym.type; 1256 if (!(vtype instanceof UninitializedType)) 1257 vtype = types.erasure(vtype); 1258 frame.locals[i] = vtype; 1259 } 1260 } 1261 frame.stack = new Type[state.stacksize]; 1262 for (int i=0; i<state.stacksize; i++) 1263 frame.stack[i] = state.stack[i]; 1264 } 1265 1266 void emitStackMapFrame(int pc, int localsSize) { 1267 if (lastFrame == null) { 1268 // first frame 1269 lastFrame = getInitialFrame(); 1270 } else if (lastFrame.pc == pc) { 1271 // drop existing stackmap at this offset 1272 stackMapTableBuffer[--stackMapBufferSize] = null; 1273 lastFrame = frameBeforeLast; 1274 frameBeforeLast = null; 1275 } 1276 1277 StackMapFrame frame = new StackMapFrame(); 1278 frame.pc = pc; 1279 1280 int localCount = 0; 1281 Type[] locals = new Type[localsSize]; 1282 for (int i=0; i<localsSize; i++, localCount++) { 1283 if (state.defined.isMember(i) && lvar[i] != null) { 1284 Type vtype = lvar[i].sym.type; 1285 if (!(vtype instanceof UninitializedType)) 1286 vtype = types.erasure(vtype); 1287 locals[i] = vtype; 1288 if (width(vtype) > 1) i++; 1289 } 1290 } 1291 frame.locals = new Type[localCount]; 1292 for (int i=0, j=0; i<localsSize; i++, j++) { 1293 assert(j < localCount); 1294 frame.locals[j] = locals[i]; 1295 if (width(locals[i]) > 1) i++; 1296 } 1297 1298 int stackCount = 0; 1299 for (int i=0; i<state.stacksize; i++) { 1300 if (state.stack[i] != null) { 1301 stackCount++; 1302 } 1303 } 1304 frame.stack = new Type[stackCount]; 1305 stackCount = 0; 1306 for (int i=0; i<state.stacksize; i++) { 1307 if (state.stack[i] != null) { 1308 frame.stack[stackCount++] = state.stack[i]; 1309 } 1310 } 1311 1312 if (stackMapTableBuffer == null) { 1313 stackMapTableBuffer = new StackMapTableFrame[20]; 1314 } else if (stackMapTableBuffer.length == stackMapBufferSize) { 1315 StackMapTableFrame[] newStackMapTableBuffer = 1316 new StackMapTableFrame[stackMapBufferSize << 1]; 1317 System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer, 1318 0, stackMapBufferSize); 1319 stackMapTableBuffer = newStackMapTableBuffer; 1320 } 1321 stackMapTableBuffer[stackMapBufferSize++] = 1322 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types); 1323 1324 frameBeforeLast = lastFrame; 1325 lastFrame = frame; 1326 } 1327 1328 StackMapFrame getInitialFrame() { 1329 StackMapFrame frame = new StackMapFrame(); 1330 List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes; 1331 int len = arg_types.length(); 1332 int count = 0; 1333 if (!meth.isStatic()) { 1334 Type thisType = meth.owner.type; 1335 frame.locals = new Type[len+1]; 1336 if (meth.isConstructor() && thisType != syms.objectType) { 1337 frame.locals[count++] = UninitializedType.uninitializedThis(thisType); 1338 } else { 1339 frame.locals[count++] = types.erasure(thisType); 1340 } 1341 } else { 1342 frame.locals = new Type[len]; 1343 } 1344 for (Type arg_type : arg_types) { 1345 frame.locals[count++] = types.erasure(arg_type); 1346 } 1347 frame.pc = -1; 1348 frame.stack = null; 1349 return frame; 1350 } 1351 1352 1353 /************************************************************************** 1354 * Operations having to do with jumps 1355 *************************************************************************/ 1356 1357 /** A chain represents a list of unresolved jumps. Jump locations 1358 * are sorted in decreasing order. 1359 */ 1360 public static class Chain { 1361 1362 /** The position of the jump instruction. 1363 */ 1364 public final int pc; 1365 1366 /** The machine state after the jump instruction. 1367 * Invariant: all elements of a chain list have the same stacksize 1368 * and compatible stack and register contents. 1369 */ 1370 Code.State state; 1371 1372 /** The next jump in the list. 1373 */ 1374 public final Chain next; 1375 1376 /** Construct a chain from its jump position, stacksize, previous 1377 * chain, and machine state. 1378 */ 1379 public Chain(int pc, Chain next, Code.State state) { 1380 this.pc = pc; 1381 this.next = next; 1382 this.state = state; 1383 } 1384 } 1385 1386 /** Negate a branch opcode. 1387 */ 1388 public static int negate(int opcode) { 1389 if (opcode == if_acmp_null) return if_acmp_nonnull; 1390 else if (opcode == if_acmp_nonnull) return if_acmp_null; 1391 else return ((opcode + 1) ^ 1) - 1; 1392 } 1393 1394 /** Emit a jump instruction. 1395 * Return code pointer of instruction to be patched. 1396 */ 1397 public int emitJump(int opcode) { 1398 if (fatcode) { 1399 if (opcode == goto_ || opcode == jsr) { 1400 emitop4(opcode + goto_w - goto_, 0); 1401 } else { 1402 emitop2(negate(opcode), 8); 1403 emitop4(goto_w, 0); 1404 alive = true; 1405 pendingStackMap = needStackMap; 1406 } 1407 return cp - 5; 1408 } else { 1409 emitop2(opcode, 0); 1410 return cp - 3; 1411 } 1412 } 1413 1414 /** Emit a branch with given opcode; return its chain. 1415 * branch differs from jump in that jsr is treated as no-op. 1416 */ 1417 public Chain branch(int opcode) { 1418 Chain result = null; 1419 if (opcode == goto_) { 1420 result = pendingJumps; 1421 pendingJumps = null; 1422 } 1423 if (opcode != dontgoto && isAlive()) { 1424 result = new Chain(emitJump(opcode), 1425 result, 1426 state.dup()); 1427 fixedPc = fatcode; 1428 if (opcode == goto_) alive = false; 1429 } 1430 return result; 1431 } 1432 1433 /** Resolve chain to point to given target. 1434 */ 1435 public void resolve(Chain chain, int target) { 1436 boolean changed = false; 1437 State newState = state; 1438 for (; chain != null; chain = chain.next) { 1439 assert state != chain.state; 1440 assert target > chain.pc || state.stacksize == 0; 1441 if (target >= cp) { 1442 target = cp; 1443 } else if (get1(target) == goto_) { 1444 if (fatcode) target = target + get4(target + 1); 1445 else target = target + get2(target + 1); 1446 } 1447 if (get1(chain.pc) == goto_ && 1448 chain.pc + 3 == target && target == cp && !fixedPc) { 1449 // If goto the next instruction, the jump is not needed: 1450 // compact the code. 1451 cp = cp - 3; 1452 target = target - 3; 1453 if (chain.next == null) { 1454 // This is the only jump to the target. Exit the loop 1455 // without setting new state. The code is reachable 1456 // from the instruction before goto_. 1457 alive = true; 1458 break; 1459 } 1460 } else { 1461 if (fatcode) 1462 put4(chain.pc + 1, target - chain.pc); 1463 else if (target - chain.pc < Short.MIN_VALUE || 1464 target - chain.pc > Short.MAX_VALUE) 1465 fatcode = true; 1466 else 1467 put2(chain.pc + 1, target - chain.pc); 1468 assert !alive || 1469 chain.state.stacksize == newState.stacksize && 1470 chain.state.nlocks == newState.nlocks; 1471 } 1472 fixedPc = true; 1473 if (cp == target) { 1474 changed = true; 1475 if (debugCode) 1476 System.err.println("resolving chain state=" + chain.state); 1477 if (alive) { 1478 newState = chain.state.join(newState); 1479 } else { 1480 newState = chain.state; 1481 alive = true; 1482 } 1483 } 1484 } 1485 assert !changed || state != newState; 1486 if (state != newState) { 1487 setDefined(newState.defined); 1488 state = newState; 1489 pendingStackMap = needStackMap; 1490 } 1491 } 1492 1493 /** Resolve chain to point to current code pointer. 1494 */ 1495 public void resolve(Chain chain) { 1496 assert 1497 !alive || 1498 chain==null || 1499 state.stacksize == chain.state.stacksize && 1500 state.nlocks == chain.state.nlocks; 1501 pendingJumps = mergeChains(chain, pendingJumps); 1502 } 1503 1504 /** Resolve any pending jumps. 1505 */ 1506 public void resolvePending() { 1507 Chain x = pendingJumps; 1508 pendingJumps = null; 1509 resolve(x, cp); 1510 } 1511 1512 /** Merge the jumps in of two chains into one. 1513 */ 1514 public static Chain mergeChains(Chain chain1, Chain chain2) { 1515 // recursive merge sort 1516 if (chain2 == null) return chain1; 1517 if (chain1 == null) return chain2; 1518 assert 1519 chain1.state.stacksize == chain2.state.stacksize && 1520 chain1.state.nlocks == chain2.state.nlocks; 1521 if (chain1.pc < chain2.pc) 1522 return new Chain( 1523 chain2.pc, 1524 mergeChains(chain1, chain2.next), 1525 chain2.state); 1526 return new Chain( 1527 chain1.pc, 1528 mergeChains(chain1.next, chain2), 1529 chain1.state); 1530 } 1531 1532 1533 /* ************************************************************************** 1534 * Catch clauses 1535 ****************************************************************************/ 1536 1537 /** Add a catch clause to code. 1538 */ 1539 public void addCatch( 1540 char startPc, char endPc, char handlerPc, char catchType) { 1541 catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType}); 1542 } 1543 1544 1545 /* ************************************************************************** 1546 * Line numbers 1547 ****************************************************************************/ 1548 1549 /** Add a line number entry. 1550 */ 1551 public void addLineNumber(char startPc, char lineNumber) { 1552 if (lineDebugInfo) { 1553 if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc) 1554 lineInfo = lineInfo.tail; 1555 if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber) 1556 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber}); 1557 } 1558 } 1559 1560 /** Mark beginning of statement. 1561 */ 1562 public void statBegin(int pos) { 1563 if (pos != Position.NOPOS) { 1564 pendingStatPos = pos; 1565 } 1566 } 1567 1568 /** Force stat begin eagerly 1569 */ 1570 public void markStatBegin() { 1571 if (alive && lineDebugInfo) { 1572 int line = lineMap.getLineNumber(pendingStatPos); 1573 char cp1 = (char)cp; 1574 char line1 = (char)line; 1575 if (cp1 == cp && line1 == line) 1576 addLineNumber(cp1, line1); 1577 } 1578 pendingStatPos = Position.NOPOS; 1579 } 1580 1581 1582 /* ************************************************************************** 1583 * Simulated VM machine state 1584 ****************************************************************************/ 1585 1586 class State implements Cloneable { 1587 /** The set of registers containing values. */ 1588 Bits defined; 1589 1590 /** The (types of the) contents of the machine stack. */ 1591 Type[] stack; 1592 1593 /** The first stack position currently unused. */ 1594 int stacksize; 1595 1596 /** The numbers of registers containing locked monitors. */ 1597 int[] locks; 1598 int nlocks; 1599 1600 State() { 1601 defined = new Bits(); 1602 stack = new Type[16]; 1603 } 1604 1605 State dup() { 1606 try { 1607 State state = (State)super.clone(); 1608 state.defined = defined.dup(); 1609 state.stack = stack.clone(); 1610 if (locks != null) state.locks = locks.clone(); 1611 if (debugCode) { 1612 System.err.println("duping state " + this); 1613 dump(); 1614 } 1615 return state; 1616 } catch (CloneNotSupportedException ex) { 1617 throw new AssertionError(ex); 1618 } 1619 } 1620 1621 void lock(int register) { 1622 if (locks == null) { 1623 locks = new int[20]; 1624 } else if (locks.length == nlocks) { 1625 int[] newLocks = new int[locks.length << 1]; 1626 System.arraycopy(locks, 0, newLocks, 0, locks.length); 1627 locks = newLocks; 1628 } 1629 locks[nlocks] = register; 1630 nlocks++; 1631 } 1632 1633 void unlock(int register) { 1634 nlocks--; 1635 assert locks[nlocks] == register; 1636 locks[nlocks] = -1; 1637 } 1638 1639 void push(Type t) { 1640 if (debugCode) System.err.println(" pushing " + t); 1641 switch (t.tag) { 1642 case TypeTags.VOID: 1643 return; 1644 case TypeTags.BYTE: 1645 case TypeTags.CHAR: 1646 case TypeTags.SHORT: 1647 case TypeTags.BOOLEAN: 1648 t = syms.intType; 1649 break; 1650 default: 1651 break; 1652 } 1653 if (stacksize+2 >= stack.length) { 1654 Type[] newstack = new Type[2*stack.length]; 1655 System.arraycopy(stack, 0, newstack, 0, stack.length); 1656 stack = newstack; 1657 } 1658 stack[stacksize++] = t; 1659 switch (width(t)) { 1660 case 1: 1661 break; 1662 case 2: 1663 stack[stacksize++] = null; 1664 break; 1665 default: 1666 throw new AssertionError(t); 1667 } 1668 if (stacksize > max_stack) 1669 max_stack = stacksize; 1670 } 1671 1672 Type pop1() { 1673 if (debugCode) System.err.println(" popping " + 1); 1674 stacksize--; 1675 Type result = stack[stacksize]; 1676 stack[stacksize] = null; 1677 assert result != null && width(result) == 1; 1678 return result; 1679 } 1680 1681 Type peek() { 1682 return stack[stacksize-1]; 1683 } 1684 1685 Type pop2() { 1686 if (debugCode) System.err.println(" popping " + 2); 1687 stacksize -= 2; 1688 Type result = stack[stacksize]; 1689 stack[stacksize] = null; 1690 assert stack[stacksize+1] == null; 1691 assert result != null && width(result) == 2; 1692 return result; 1693 } 1694 1695 void pop(int n) { 1696 if (debugCode) System.err.println(" popping " + n); 1697 while (n > 0) { 1698 stack[--stacksize] = null; 1699 n--; 1700 } 1701 } 1702 1703 void pop(Type t) { 1704 pop(width(t)); 1705 } 1706 1707 /** Force the top of the stack to be treated as this supertype 1708 * of its current type. */ 1709 void forceStackTop(Type t) { 1710 if (!alive) return; 1711 switch (t.tag) { 1712 case CLASS: 1713 case ARRAY: 1714 int width = width(t); 1715 Type old = stack[stacksize-width]; 1716 assert types.isSubtype(types.erasure(old), 1717 types.erasure(t)); 1718 stack[stacksize-width] = t; 1719 break; 1720 default: 1721 } 1722 } 1723 1724 void markInitialized(UninitializedType old) { 1725 Type newtype = old.initializedType(); 1726 for (int i=0; i<stacksize; i++) 1727 if (stack[i] == old) stack[i] = newtype; 1728 for (int i=0; i<lvar.length; i++) { 1729 LocalVar lv = lvar[i]; 1730 if (lv != null && lv.sym.type == old) { 1731 VarSymbol sym = lv.sym; 1732 sym = sym.clone(sym.owner); 1733 sym.type = newtype; 1734 LocalVar newlv = lvar[i] = new LocalVar(sym); 1735 // should the following be initialized to cp? 1736 newlv.start_pc = lv.start_pc; 1737 } 1738 } 1739 } 1740 1741 State join(State other) { 1742 defined = defined.andSet(other.defined); 1743 assert stacksize == other.stacksize; 1744 assert nlocks == other.nlocks; 1745 for (int i=0; i<stacksize; ) { 1746 Type t = stack[i]; 1747 Type tother = other.stack[i]; 1748 Type result = 1749 t==tother ? t : 1750 types.isSubtype(t, tother) ? tother : 1751 types.isSubtype(tother, t) ? t : 1752 error(); 1753 int w = width(result); 1754 stack[i] = result; 1755 if (w == 2) assert stack[i+1] == null; 1756 i += w; 1757 } 1758 return this; 1759 } 1760 1761 Type error() { 1762 throw new AssertionError("inconsistent stack types at join point"); 1763 } 1764 1765 void dump() { 1766 dump(-1); 1767 } 1768 1769 void dump(int pc) { 1770 System.err.print("stackMap for " + meth.owner + "." + meth); 1771 if (pc == -1) 1772 System.out.println(); 1773 else 1774 System.out.println(" at " + pc); 1775 System.err.println(" stack (from bottom):"); 1776 for (int i=0; i<stacksize; i++) 1777 System.err.println(" " + i + ": " + stack[i]); 1778 1779 int lastLocal = 0; 1780 for (int i=max_locals-1; i>=0; i--) { 1781 if (defined.isMember(i)) { 1782 lastLocal = i; 1783 break; 1784 } 1785 } 1786 if (lastLocal >= 0) 1787 System.err.println(" locals:"); 1788 for (int i=0; i<=lastLocal; i++) { 1789 System.err.print(" " + i + ": "); 1790 if (defined.isMember(i)) { 1791 LocalVar var = lvar[i]; 1792 if (var == null) { 1793 System.err.println("(none)"); 1794 } else if (var.sym == null) 1795 System.err.println("UNKNOWN!"); 1796 else 1797 System.err.println("" + var.sym + " of type " + 1798 var.sym.erasure(types)); 1799 } else { 1800 System.err.println("undefined"); 1801 } 1802 } 1803 if (nlocks != 0) { 1804 System.err.print(" locks:"); 1805 for (int i=0; i<nlocks; i++) { 1806 System.err.print(" " + locks[i]); 1807 } 1808 System.err.println(); 1809 } 1810 } 1811 } 1812 1813 static Type jsrReturnValue = new Type(TypeTags.INT, null); 1814 1815 1816 /* ************************************************************************** 1817 * Local variables 1818 ****************************************************************************/ 1819 1820 /** A live range of a local variable. */ 1821 static class LocalVar { 1822 final VarSymbol sym; 1823 final char reg; 1824 char start_pc = Character.MAX_VALUE; 1825 char length = Character.MAX_VALUE; 1826 LocalVar(VarSymbol v) { 1827 this.sym = v; 1828 this.reg = (char)v.adr; 1829 } 1830 public LocalVar dup() { 1831 return new LocalVar(sym); 1832 } 1833 public String toString() { 1834 return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length); 1835 } 1836 }; 1837 1838 /** Local variables, indexed by register. */ 1839 LocalVar[] lvar; 1840 1841 /** Add a new local variable. */ 1842 private void addLocalVar(VarSymbol v) { 1843 int adr = v.adr; 1844 if (adr+1 >= lvar.length) { 1845 int newlength = lvar.length << 1; 1846 if (newlength <= adr) newlength = adr + 10; 1847 LocalVar[] new_lvar = new LocalVar[newlength]; 1848 System.arraycopy(lvar, 0, new_lvar, 0, lvar.length); 1849 lvar = new_lvar; 1850 } 1851 assert lvar[adr] == null; 1852 if (pendingJumps != null) resolvePending(); 1853 lvar[adr] = new LocalVar(v); 1854 state.defined.excl(adr); 1855 } 1856 1857 /** Set the current variable defined state. */ 1858 public void setDefined(Bits newDefined) { 1859 if (alive && newDefined != state.defined) { 1860 Bits diff = state.defined.dup().xorSet(newDefined); 1861 for (int adr = diff.nextBit(0); 1862 adr >= 0; 1863 adr = diff.nextBit(adr+1)) { 1864 if (adr >= nextreg) 1865 state.defined.excl(adr); 1866 else if (state.defined.isMember(adr)) 1867 setUndefined(adr); 1868 else 1869 setDefined(adr); 1870 } 1871 } 1872 } 1873 1874 /** Mark a register as being (possibly) defined. */ 1875 public void setDefined(int adr) { 1876 LocalVar v = lvar[adr]; 1877 if (v == null) { 1878 state.defined.excl(adr); 1879 } else { 1880 state.defined.incl(adr); 1881 if (cp < Character.MAX_VALUE) { 1882 if (v.start_pc == Character.MAX_VALUE) 1883 v.start_pc = (char)cp; 1884 } 1885 } 1886 } 1887 1888 /** Mark a register as being undefined. */ 1889 public void setUndefined(int adr) { 1890 state.defined.excl(adr); 1891 if (adr < lvar.length && 1892 lvar[adr] != null && 1893 lvar[adr].start_pc != Character.MAX_VALUE) { 1894 LocalVar v = lvar[adr]; 1895 char length = (char)(curPc() - v.start_pc); 1896 if (length > 0 && length < Character.MAX_VALUE) { 1897 lvar[adr] = v.dup(); 1898 v.length = length; 1899 putVar(v); 1900 } else { 1901 v.start_pc = Character.MAX_VALUE; 1902 } 1903 } 1904 } 1905 1906 /** End the scope of a variable. */ 1907 private void endScope(int adr) { 1908 LocalVar v = lvar[adr]; 1909 if (v != null) { 1910 lvar[adr] = null; 1911 if (v.start_pc != Character.MAX_VALUE) { 1912 char length = (char)(curPc() - v.start_pc); 1913 if (length < Character.MAX_VALUE) { 1914 v.length = length; 1915 putVar(v); 1916 fillLocalVarPosition(v); 1917 } 1918 } 1919 } 1920 state.defined.excl(adr); 1921 } 1922 1923 private void fillLocalVarPosition(LocalVar lv) { 1924 if (lv == null || lv.sym == null 1925 || lv.sym.typeAnnotations == null) 1926 return; 1927 for (Attribute.TypeCompound ta : lv.sym.typeAnnotations) { 1928 TypeAnnotationPosition p = ta.position; 1929 while (p != null) { 1930 p.lvarOffset[0] = (int)lv.start_pc; 1931 p.lvarLength[0] = (int)lv.length; 1932 p.lvarIndex[0] = (int)lv.reg; 1933 p.isValidOffset = true; 1934 p = p.wildcard_position; 1935 } 1936 } 1937 } 1938 1939 /** Put a live variable range into the buffer to be output to the 1940 * class file. 1941 */ 1942 void putVar(LocalVar var) { 1943 if (!varDebugInfo) return; 1944 if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return; 1945 if (varBuffer == null) 1946 varBuffer = new LocalVar[20]; 1947 else if (varBufferSize >= varBuffer.length) { 1948 LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2]; 1949 System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length); 1950 varBuffer = newVarBuffer; 1951 } 1952 varBuffer[varBufferSize++] = var; 1953 } 1954 1955 /** Previously live local variables, to be put into the variable table. */ 1956 LocalVar[] varBuffer; 1957 int varBufferSize; 1958 1959 /** Create a new local variable address and return it. 1960 */ 1961 private int newLocal(int typecode) { 1962 int reg = nextreg; 1963 int w = width(typecode); 1964 nextreg = reg + w; 1965 if (nextreg > max_locals) max_locals = nextreg; 1966 return reg; 1967 } 1968 1969 private int newLocal(Type type) { 1970 return newLocal(typecode(type)); 1971 } 1972 1973 public int newLocal(VarSymbol v) { 1974 int reg = v.adr = newLocal(v.erasure(types)); 1975 addLocalVar(v); 1976 return reg; 1977 } 1978 1979 /** Start a set of fresh registers. 1980 */ 1981 public void newRegSegment() { 1982 nextreg = max_locals; 1983 } 1984 1985 /** End scopes of all variables with registers >= first. 1986 */ 1987 public void endScopes(int first) { 1988 int prevNextReg = nextreg; 1989 nextreg = first; 1990 for (int i = nextreg; i < prevNextReg; i++) endScope(i); 1991 } 1992 1993 /************************************************************************** 1994 * static tables 1995 *************************************************************************/ 1996 1997 public static String mnem(int opcode) { 1998 return Mneumonics.mnem[opcode]; 1999 } 2000 2001 private static class Mneumonics { 2002 private final static String[] mnem = new String[ByteCodeCount]; 2003 static { 2004 mnem[nop] = "nop"; 2005 mnem[aconst_null] = "aconst_null"; 2006 mnem[iconst_m1] = "iconst_m1"; 2007 mnem[iconst_0] = "iconst_0"; 2008 mnem[iconst_1] = "iconst_1"; 2009 mnem[iconst_2] = "iconst_2"; 2010 mnem[iconst_3] = "iconst_3"; 2011 mnem[iconst_4] = "iconst_4"; 2012 mnem[iconst_5] = "iconst_5"; 2013 mnem[lconst_0] = "lconst_0"; 2014 mnem[lconst_1] = "lconst_1"; 2015 mnem[fconst_0] = "fconst_0"; 2016 mnem[fconst_1] = "fconst_1"; 2017 mnem[fconst_2] = "fconst_2"; 2018 mnem[dconst_0] = "dconst_0"; 2019 mnem[dconst_1] = "dconst_1"; 2020 mnem[bipush] = "bipush"; 2021 mnem[sipush] = "sipush"; 2022 mnem[ldc1] = "ldc1"; 2023 mnem[ldc2] = "ldc2"; 2024 mnem[ldc2w] = "ldc2w"; 2025 mnem[iload] = "iload"; 2026 mnem[lload] = "lload"; 2027 mnem[fload] = "fload"; 2028 mnem[dload] = "dload"; 2029 mnem[aload] = "aload"; 2030 mnem[iload_0] = "iload_0"; 2031 mnem[lload_0] = "lload_0"; 2032 mnem[fload_0] = "fload_0"; 2033 mnem[dload_0] = "dload_0"; 2034 mnem[aload_0] = "aload_0"; 2035 mnem[iload_1] = "iload_1"; 2036 mnem[lload_1] = "lload_1"; 2037 mnem[fload_1] = "fload_1"; 2038 mnem[dload_1] = "dload_1"; 2039 mnem[aload_1] = "aload_1"; 2040 mnem[iload_2] = "iload_2"; 2041 mnem[lload_2] = "lload_2"; 2042 mnem[fload_2] = "fload_2"; 2043 mnem[dload_2] = "dload_2"; 2044 mnem[aload_2] = "aload_2"; 2045 mnem[iload_3] = "iload_3"; 2046 mnem[lload_3] = "lload_3"; 2047 mnem[fload_3] = "fload_3"; 2048 mnem[dload_3] = "dload_3"; 2049 mnem[aload_3] = "aload_3"; 2050 mnem[iaload] = "iaload"; 2051 mnem[laload] = "laload"; 2052 mnem[faload] = "faload"; 2053 mnem[daload] = "daload"; 2054 mnem[aaload] = "aaload"; 2055 mnem[baload] = "baload"; 2056 mnem[caload] = "caload"; 2057 mnem[saload] = "saload"; 2058 mnem[istore] = "istore"; 2059 mnem[lstore] = "lstore"; 2060 mnem[fstore] = "fstore"; 2061 mnem[dstore] = "dstore"; 2062 mnem[astore] = "astore"; 2063 mnem[istore_0] = "istore_0"; 2064 mnem[lstore_0] = "lstore_0"; 2065 mnem[fstore_0] = "fstore_0"; 2066 mnem[dstore_0] = "dstore_0"; 2067 mnem[astore_0] = "astore_0"; 2068 mnem[istore_1] = "istore_1"; 2069 mnem[lstore_1] = "lstore_1"; 2070 mnem[fstore_1] = "fstore_1"; 2071 mnem[dstore_1] = "dstore_1"; 2072 mnem[astore_1] = "astore_1"; 2073 mnem[istore_2] = "istore_2"; 2074 mnem[lstore_2] = "lstore_2"; 2075 mnem[fstore_2] = "fstore_2"; 2076 mnem[dstore_2] = "dstore_2"; 2077 mnem[astore_2] = "astore_2"; 2078 mnem[istore_3] = "istore_3"; 2079 mnem[lstore_3] = "lstore_3"; 2080 mnem[fstore_3] = "fstore_3"; 2081 mnem[dstore_3] = "dstore_3"; 2082 mnem[astore_3] = "astore_3"; 2083 mnem[iastore] = "iastore"; 2084 mnem[lastore] = "lastore"; 2085 mnem[fastore] = "fastore"; 2086 mnem[dastore] = "dastore"; 2087 mnem[aastore] = "aastore"; 2088 mnem[bastore] = "bastore"; 2089 mnem[castore] = "castore"; 2090 mnem[sastore] = "sastore"; 2091 mnem[pop] = "pop"; 2092 mnem[pop2] = "pop2"; 2093 mnem[dup] = "dup"; 2094 mnem[dup_x1] = "dup_x1"; 2095 mnem[dup_x2] = "dup_x2"; 2096 mnem[dup2] = "dup2"; 2097 mnem[dup2_x1] = "dup2_x1"; 2098 mnem[dup2_x2] = "dup2_x2"; 2099 mnem[swap] = "swap"; 2100 mnem[iadd] = "iadd"; 2101 mnem[ladd] = "ladd"; 2102 mnem[fadd] = "fadd"; 2103 mnem[dadd] = "dadd"; 2104 mnem[isub] = "isub"; 2105 mnem[lsub] = "lsub"; 2106 mnem[fsub] = "fsub"; 2107 mnem[dsub] = "dsub"; 2108 mnem[imul] = "imul"; 2109 mnem[lmul] = "lmul"; 2110 mnem[fmul] = "fmul"; 2111 mnem[dmul] = "dmul"; 2112 mnem[idiv] = "idiv"; 2113 mnem[ldiv] = "ldiv"; 2114 mnem[fdiv] = "fdiv"; 2115 mnem[ddiv] = "ddiv"; 2116 mnem[imod] = "imod"; 2117 mnem[lmod] = "lmod"; 2118 mnem[fmod] = "fmod"; 2119 mnem[dmod] = "dmod"; 2120 mnem[ineg] = "ineg"; 2121 mnem[lneg] = "lneg"; 2122 mnem[fneg] = "fneg"; 2123 mnem[dneg] = "dneg"; 2124 mnem[ishl] = "ishl"; 2125 mnem[lshl] = "lshl"; 2126 mnem[ishr] = "ishr"; 2127 mnem[lshr] = "lshr"; 2128 mnem[iushr] = "iushr"; 2129 mnem[lushr] = "lushr"; 2130 mnem[iand] = "iand"; 2131 mnem[land] = "land"; 2132 mnem[ior] = "ior"; 2133 mnem[lor] = "lor"; 2134 mnem[ixor] = "ixor"; 2135 mnem[lxor] = "lxor"; 2136 mnem[iinc] = "iinc"; 2137 mnem[i2l] = "i2l"; 2138 mnem[i2f] = "i2f"; 2139 mnem[i2d] = "i2d"; 2140 mnem[l2i] = "l2i"; 2141 mnem[l2f] = "l2f"; 2142 mnem[l2d] = "l2d"; 2143 mnem[f2i] = "f2i"; 2144 mnem[f2l] = "f2l"; 2145 mnem[f2d] = "f2d"; 2146 mnem[d2i] = "d2i"; 2147 mnem[d2l] = "d2l"; 2148 mnem[d2f] = "d2f"; 2149 mnem[int2byte] = "int2byte"; 2150 mnem[int2char] = "int2char"; 2151 mnem[int2short] = "int2short"; 2152 mnem[lcmp] = "lcmp"; 2153 mnem[fcmpl] = "fcmpl"; 2154 mnem[fcmpg] = "fcmpg"; 2155 mnem[dcmpl] = "dcmpl"; 2156 mnem[dcmpg] = "dcmpg"; 2157 mnem[ifeq] = "ifeq"; 2158 mnem[ifne] = "ifne"; 2159 mnem[iflt] = "iflt"; 2160 mnem[ifge] = "ifge"; 2161 mnem[ifgt] = "ifgt"; 2162 mnem[ifle] = "ifle"; 2163 mnem[if_icmpeq] = "if_icmpeq"; 2164 mnem[if_icmpne] = "if_icmpne"; 2165 mnem[if_icmplt] = "if_icmplt"; 2166 mnem[if_icmpge] = "if_icmpge"; 2167 mnem[if_icmpgt] = "if_icmpgt"; 2168 mnem[if_icmple] = "if_icmple"; 2169 mnem[if_acmpeq] = "if_acmpeq"; 2170 mnem[if_acmpne] = "if_acmpne"; 2171 mnem[goto_] = "goto_"; 2172 mnem[jsr] = "jsr"; 2173 mnem[ret] = "ret"; 2174 mnem[tableswitch] = "tableswitch"; 2175 mnem[lookupswitch] = "lookupswitch"; 2176 mnem[ireturn] = "ireturn"; 2177 mnem[lreturn] = "lreturn"; 2178 mnem[freturn] = "freturn"; 2179 mnem[dreturn] = "dreturn"; 2180 mnem[areturn] = "areturn"; 2181 mnem[return_] = "return_"; 2182 mnem[getstatic] = "getstatic"; 2183 mnem[putstatic] = "putstatic"; 2184 mnem[getfield] = "getfield"; 2185 mnem[putfield] = "putfield"; 2186 mnem[invokevirtual] = "invokevirtual"; 2187 mnem[invokespecial] = "invokespecial"; 2188 mnem[invokestatic] = "invokestatic"; 2189 mnem[invokeinterface] = "invokeinterface"; 2190 mnem[invokedynamic] = "invokedynamic"; 2191 mnem[new_] = "new_"; 2192 mnem[newarray] = "newarray"; 2193 mnem[anewarray] = "anewarray"; 2194 mnem[arraylength] = "arraylength"; 2195 mnem[athrow] = "athrow"; 2196 mnem[checkcast] = "checkcast"; 2197 mnem[instanceof_] = "instanceof_"; 2198 mnem[monitorenter] = "monitorenter"; 2199 mnem[monitorexit] = "monitorexit"; 2200 mnem[wide] = "wide"; 2201 mnem[multianewarray] = "multianewarray"; 2202 mnem[if_acmp_null] = "if_acmp_null"; 2203 mnem[if_acmp_nonnull] = "if_acmp_nonnull"; 2204 mnem[goto_w] = "goto_w"; 2205 mnem[jsr_w] = "jsr_w"; 2206 mnem[breakpoint] = "breakpoint"; 2207 } 2208 } 2209 }