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