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