Mercurial > hg > truffle
comparison graal/com.oracle.max.cri/src/com/sun/cri/bytecode/Bytecodes.java @ 4142:bc8527f3071c
Adjust code base to new level of warnings.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sun, 18 Dec 2011 05:24:06 +0100 |
parents | e233f5660da4 |
children |
comparison
equal
deleted
inserted
replaced
4141:04d21be7a24f | 4142:bc8527f3071c |
---|---|
244 public static final int IFNONNULL = 199; // 0xC7 | 244 public static final int IFNONNULL = 199; // 0xC7 |
245 public static final int GOTO_W = 200; // 0xC8 | 245 public static final int GOTO_W = 200; // 0xC8 |
246 public static final int JSR_W = 201; // 0xC9 | 246 public static final int JSR_W = 201; // 0xC9 |
247 public static final int BREAKPOINT = 202; // 0xCA | 247 public static final int BREAKPOINT = 202; // 0xCA |
248 | 248 |
249 // Start extended bytecodes | |
250 | |
251 /** | |
252 * Native function call. | |
253 * | |
254 * The 'function_address' value on the top of the stack is the result of | |
255 * linking a native function. | |
256 * | |
257 * <pre> | |
258 * Format: { u1 opcode; // JNICALL | |
259 * u2 sig; // Constant pool index of a CONSTANT_Utf8_info representing the signature of the call | |
260 * } | |
261 * | |
262 * Operand Stack: | |
263 * ..., [arg1, [arg2 ... ]] function_address => [return value, ]..., | |
264 * </pre> | |
265 * | |
266 * @see #JNIOP_LINK | |
267 * @see #JNIOP_J2N | |
268 * @see #JNIOP_N2J | |
269 */ | |
270 public static final int JNICALL = 203; | |
271 | |
272 // End extended bytecodes | |
273 | |
274 public static final int ILLEGAL = 255; | 249 public static final int ILLEGAL = 255; |
275 public static final int END = 256; | 250 public static final int END = 256; |
276 | 251 |
277 /** | 252 /** |
278 * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes: | 253 * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes: |
368 | 343 |
369 /** | 344 /** |
370 * A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic. | 345 * A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic. |
371 * This will include the root instruction for the three-byte extended instructions. | 346 * This will include the root instruction for the three-byte extended instructions. |
372 */ | 347 */ |
373 private static final String[] names = new String[256]; | 348 private static final String[] nameArray = new String[256]; |
374 | 349 |
375 /** | 350 /** |
376 * A array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction. | 351 * A array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction. |
377 */ | 352 */ |
378 private static final int[] flags = new int[256]; | 353 private static final int[] flagsArray = new int[256]; |
379 | 354 |
380 /** | 355 /** |
381 * A array that maps from a bytecode value to the length in bytes for the corresponding instruction. | 356 * A array that maps from a bytecode value to the length in bytes for the corresponding instruction. |
382 */ | 357 */ |
383 private static final int[] length = new int[256]; | 358 private static final int[] lengthArray = new int[256]; |
384 | 359 |
385 // Checkstyle: stop | 360 // Checkstyle: stop |
386 static { | 361 static { |
387 def(NOP , "nop" , "b" ); | 362 def(NOP , "nop" , "b" ); |
388 def(ACONST_NULL , "aconst_null" , "b" ); | 363 def(ACONST_NULL , "aconst_null" , "b" ); |
585 def(IFNULL , "ifnull" , "boo" , FALL_THROUGH | BRANCH); | 560 def(IFNULL , "ifnull" , "boo" , FALL_THROUGH | BRANCH); |
586 def(IFNONNULL , "ifnonnull" , "boo" , FALL_THROUGH | BRANCH); | 561 def(IFNONNULL , "ifnonnull" , "boo" , FALL_THROUGH | BRANCH); |
587 def(GOTO_W , "goto_w" , "boooo", STOP | BRANCH); | 562 def(GOTO_W , "goto_w" , "boooo", STOP | BRANCH); |
588 def(JSR_W , "jsr_w" , "boooo", STOP | BRANCH); | 563 def(JSR_W , "jsr_w" , "boooo", STOP | BRANCH); |
589 def(BREAKPOINT , "breakpoint" , "b" , TRAP); | 564 def(BREAKPOINT , "breakpoint" , "b" , TRAP); |
590 | |
591 def(JNICALL , "jnicall" , "bii" , EXTENSION | TRAP); | |
592 } | 565 } |
593 // Checkstyle: resume | 566 // Checkstyle: resume |
594 | 567 |
595 /** | 568 /** |
596 * Determines if an opcode is commutative. | 569 * Determines if an opcode is commutative. |
597 * @param opcode the opcode to check | 570 * @param opcode the opcode to check |
598 * @return {@code true} iff commutative | 571 * @return {@code true} iff commutative |
599 */ | 572 */ |
600 public static boolean isCommutative(int opcode) { | 573 public static boolean isCommutative(int opcode) { |
601 return (flags[opcode & 0xff] & COMMUTATIVE) != 0; | 574 return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0; |
602 } | 575 } |
603 | 576 |
604 /** | 577 /** |
605 * Gets the length of an instruction denoted by a given opcode. | 578 * Gets the length of an instruction denoted by a given opcode. |
606 * | 579 * |
607 * @param opcode an instruction opcode | 580 * @param opcode an instruction opcode |
608 * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a | 581 * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a |
609 * variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned. | 582 * variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned. |
610 */ | 583 */ |
611 public static int lengthOf(int opcode) { | 584 public static int lengthOf(int opcode) { |
612 return length[opcode & 0xff]; | 585 return lengthArray[opcode & 0xff]; |
613 } | 586 } |
614 | 587 |
615 /** | 588 /** |
616 * Gets the length of an instruction at a given position in a given bytecode array. | 589 * Gets the length of an instruction at a given position in a given bytecode array. |
617 * This methods handles variable length and {@linkplain #WIDE widened} instructions. | 590 * This methods handles variable length and {@linkplain #WIDE widened} instructions. |
620 * @param bci the position in {@code code} of an instruction's opcode | 593 * @param bci the position in {@code code} of an instruction's opcode |
621 * @return the length of the instruction at position {@code bci} in {@code code} | 594 * @return the length of the instruction at position {@code bci} in {@code code} |
622 */ | 595 */ |
623 public static int lengthOf(byte[] code, int bci) { | 596 public static int lengthOf(byte[] code, int bci) { |
624 int opcode = Bytes.beU1(code, bci); | 597 int opcode = Bytes.beU1(code, bci); |
625 int length = Bytecodes.length[opcode & 0xff]; | 598 int length = Bytecodes.lengthArray[opcode & 0xff]; |
626 if (length == 0) { | 599 if (length == 0) { |
627 switch (opcode) { | 600 switch (opcode) { |
628 case TABLESWITCH: { | 601 case TABLESWITCH: { |
629 return new BytecodeTableSwitch(code, bci).size(); | 602 return new BytecodeTableSwitch(code, bci).size(); |
630 } | 603 } |
653 * | 626 * |
654 * @param opcode an opcode | 627 * @param opcode an opcode |
655 * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode | 628 * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode |
656 */ | 629 */ |
657 public static String nameOf(int opcode) throws IllegalArgumentException { | 630 public static String nameOf(int opcode) throws IllegalArgumentException { |
658 String name = names[opcode & 0xff]; | 631 String name = nameArray[opcode & 0xff]; |
659 if (name == null) { | 632 if (name == null) { |
660 return "<illegal opcode: " + opcode + ">"; | 633 return "<illegal opcode: " + opcode + ">"; |
661 } | 634 } |
662 return name; | 635 return name; |
663 } | 636 } |
666 * Allocation-free version of {@linkplain #nameOf(int)}. | 639 * Allocation-free version of {@linkplain #nameOf(int)}. |
667 * @param opcode an opcode. | 640 * @param opcode an opcode. |
668 * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode. | 641 * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode. |
669 */ | 642 */ |
670 public static String baseNameOf(int opcode) { | 643 public static String baseNameOf(int opcode) { |
671 String name = names[opcode & 0xff]; | 644 String name = nameArray[opcode & 0xff]; |
672 if (name == null) { | 645 if (name == null) { |
673 return "<illegal opcode>"; | 646 return "<illegal opcode>"; |
674 } | 647 } |
675 return name; | 648 return name; |
676 } | 649 } |
681 * @param name an opcode mnemonic | 654 * @param name an opcode mnemonic |
682 * @return the opcode corresponding to {@code mnemonic} | 655 * @return the opcode corresponding to {@code mnemonic} |
683 * @throws IllegalArgumentException if {@code name} does not denote a valid opcode | 656 * @throws IllegalArgumentException if {@code name} does not denote a valid opcode |
684 */ | 657 */ |
685 public static int valueOf(String name) { | 658 public static int valueOf(String name) { |
686 for (int opcode = 0; opcode < names.length; ++opcode) { | 659 for (int opcode = 0; opcode < nameArray.length; ++opcode) { |
687 if (name.equalsIgnoreCase(names[opcode])) { | 660 if (name.equalsIgnoreCase(nameArray[opcode])) { |
688 return opcode; | 661 return opcode; |
689 } | 662 } |
690 } | 663 } |
691 throw new IllegalArgumentException("No opcode for " + name); | 664 throw new IllegalArgumentException("No opcode for " + name); |
692 } | 665 } |
696 * | 669 * |
697 * @param opcode an opcode to test | 670 * @param opcode an opcode to test |
698 * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise | 671 * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise |
699 */ | 672 */ |
700 public static boolean canTrap(int opcode) { | 673 public static boolean canTrap(int opcode) { |
701 return (flags[opcode & 0xff] & TRAP) != 0; | 674 return (flagsArray[opcode & 0xff] & TRAP) != 0; |
702 } | 675 } |
703 | 676 |
704 /** | 677 /** |
705 * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack. | 678 * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack. |
706 * | 679 * |
707 * @param opcode an opcode to test | 680 * @param opcode an opcode to test |
708 * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise | 681 * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise |
709 */ | 682 */ |
710 public static boolean isLoad(int opcode) { | 683 public static boolean isLoad(int opcode) { |
711 return (flags[opcode & 0xff] & LOAD) != 0; | 684 return (flagsArray[opcode & 0xff] & LOAD) != 0; |
712 } | 685 } |
713 | 686 |
714 /** | 687 /** |
715 * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall | 688 * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall |
716 * through to its lexical successor. | 689 * through to its lexical successor. |
717 * | 690 * |
718 * @param opcode an opcode to test | 691 * @param opcode an opcode to test |
719 * @return {@code true} iff {@code opcode} properly ends a basic block | 692 * @return {@code true} iff {@code opcode} properly ends a basic block |
720 */ | 693 */ |
721 public static boolean isStop(int opcode) { | 694 public static boolean isStop(int opcode) { |
722 return (flags[opcode & 0xff] & STOP) != 0; | 695 return (flagsArray[opcode & 0xff] & STOP) != 0; |
723 } | 696 } |
724 | 697 |
725 /** | 698 /** |
726 * Determines if a given opcode denotes an instruction that stores a value to a local variable | 699 * Determines if a given opcode denotes an instruction that stores a value to a local variable |
727 * after popping it from the operand stack. | 700 * after popping it from the operand stack. |
728 * | 701 * |
729 * @param opcode an opcode to test | 702 * @param opcode an opcode to test |
730 * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise | 703 * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise |
731 */ | 704 */ |
732 public static boolean isInvoke(int opcode) { | 705 public static boolean isInvoke(int opcode) { |
733 return (flags[opcode & 0xff] & INVOKE) != 0; | 706 return (flagsArray[opcode & 0xff] & INVOKE) != 0; |
734 } | 707 } |
735 | 708 |
736 /** | 709 /** |
737 * Determines if a given opcode denotes an instruction that stores a value to a local variable | 710 * Determines if a given opcode denotes an instruction that stores a value to a local variable |
738 * after popping it from the operand stack. | 711 * after popping it from the operand stack. |
739 * | 712 * |
740 * @param opcode an opcode to test | 713 * @param opcode an opcode to test |
741 * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise | 714 * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise |
742 */ | 715 */ |
743 public static boolean isStore(int opcode) { | 716 public static boolean isStore(int opcode) { |
744 return (flags[opcode & 0xff] & STORE) != 0; | 717 return (flagsArray[opcode & 0xff] & STORE) != 0; |
745 } | 718 } |
746 | 719 |
747 /** | 720 /** |
748 * Determines if a given opcode is an instruction that delimits a basic block. | 721 * Determines if a given opcode is an instruction that delimits a basic block. |
749 * | 722 * |
750 * @param opcode an opcode to test | 723 * @param opcode an opcode to test |
751 * @return {@code true} iff {@code opcode} delimits a basic block | 724 * @return {@code true} iff {@code opcode} delimits a basic block |
752 */ | 725 */ |
753 public static boolean isBlockEnd(int opcode) { | 726 public static boolean isBlockEnd(int opcode) { |
754 return (flags[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0; | 727 return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0; |
755 } | 728 } |
756 | 729 |
757 /** | 730 /** |
758 * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another | 731 * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another |
759 * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions. | 732 * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions. |
760 * | 733 * |
761 * @param opcode an opcode to test | 734 * @param opcode an opcode to test |
762 * @return {@code true} iff {@code opcode} is a branch instruction with a single operand | 735 * @return {@code true} iff {@code opcode} is a branch instruction with a single operand |
763 */ | 736 */ |
764 public static boolean isBranch(int opcode) { | 737 public static boolean isBranch(int opcode) { |
765 return (flags[opcode & 0xff] & BRANCH) != 0; | 738 return (flagsArray[opcode & 0xff] & BRANCH) != 0; |
766 } | 739 } |
767 | 740 |
768 /** | 741 /** |
769 * Determines if a given opcode denotes a conditional branch. | 742 * Determines if a given opcode denotes a conditional branch. |
770 * @param opcode | 743 * @param opcode |
771 * @return {@code true} iff {@code opcode} is a conditional branch | 744 * @return {@code true} iff {@code opcode} is a conditional branch |
772 */ | 745 */ |
773 public static boolean isConditionalBranch(int opcode) { | 746 public static boolean isConditionalBranch(int opcode) { |
774 return (flags[opcode & 0xff] & FALL_THROUGH) != 0; | 747 return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0; |
775 } | 748 } |
776 | 749 |
777 /** | 750 /** |
778 * Determines if a given opcode denotes a standard bytecode. A standard bytecode is | 751 * Determines if a given opcode denotes a standard bytecode. A standard bytecode is |
779 * defined in the JVM specification. | 752 * defined in the JVM specification. |
780 * | 753 * |
781 * @param opcode an opcode to test | 754 * @param opcode an opcode to test |
782 * @return {@code true} iff {@code opcode} is a standard bytecode | 755 * @return {@code true} iff {@code opcode} is a standard bytecode |
783 */ | 756 */ |
784 public static boolean isStandard(int opcode) { | 757 public static boolean isStandard(int opcode) { |
785 return (flags[opcode & 0xff] & EXTENSION) == 0; | 758 return (flagsArray[opcode & 0xff] & EXTENSION) == 0; |
786 } | 759 } |
787 | 760 |
788 /** | 761 /** |
789 * Determines if a given opcode denotes an extended bytecode. | 762 * Determines if a given opcode denotes an extended bytecode. |
790 * | 763 * |
791 * @param opcode an opcode to test | 764 * @param opcode an opcode to test |
792 * @return {@code true} if {@code opcode} is an extended bytecode | 765 * @return {@code true} if {@code opcode} is an extended bytecode |
793 */ | 766 */ |
794 public static boolean isExtended(int opcode) { | 767 public static boolean isExtended(int opcode) { |
795 return (flags[opcode & 0xff] & EXTENSION) != 0; | 768 return (flagsArray[opcode & 0xff] & EXTENSION) != 0; |
796 } | 769 } |
797 | 770 |
798 /** | 771 /** |
799 * Determines if a given opcode is a three-byte extended bytecode. | 772 * Determines if a given opcode is a three-byte extended bytecode. |
800 * | 773 * |
859 /** | 832 /** |
860 * Defines a bytecode by entering it into the arrays that record its name, length and flags. | 833 * Defines a bytecode by entering it into the arrays that record its name, length and flags. |
861 * | 834 * |
862 * @param name instruction name (should be lower case) | 835 * @param name instruction name (should be lower case) |
863 * @param format encodes the length of the instruction | 836 * @param format encodes the length of the instruction |
864 * @param flags the set of {@link Flags} associated with the instruction | 837 * @param flagsArray the set of {@link Flags} associated with the instruction |
865 */ | 838 */ |
866 private static void def(int opcode, String name, String format) { | 839 private static void def(int opcode, String name, String format) { |
867 def(opcode, name, format, 0); | 840 def(opcode, name, format, 0); |
868 } | 841 } |
869 | 842 |
873 * @param name instruction name (lower case) | 846 * @param name instruction name (lower case) |
874 * @param format encodes the length of the instruction | 847 * @param format encodes the length of the instruction |
875 * @param flags the set of {@link Flags} associated with the instruction | 848 * @param flags the set of {@link Flags} associated with the instruction |
876 */ | 849 */ |
877 private static void def(int opcode, String name, String format, int flags) { | 850 private static void def(int opcode, String name, String format, int flags) { |
878 assert names[opcode] == null : "opcode " + opcode + " is already bound to name " + names[opcode]; | 851 assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode]; |
879 names[opcode] = name; | 852 nameArray[opcode] = name; |
880 int instructionLength = format.length(); | 853 int instructionLength = format.length(); |
881 length[opcode] = instructionLength; | 854 lengthArray[opcode] = instructionLength; |
882 Bytecodes.flags[opcode] = flags; | 855 Bytecodes.flagsArray[opcode] = flags; |
883 | 856 |
884 assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch"; | 857 assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch"; |
885 } | 858 } |
886 | 859 |
887 /** | 860 /** |
917 Matcher matcher = opcodeDecl.matcher(line); | 890 Matcher matcher = opcodeDecl.matcher(line); |
918 if (matcher.matches()) { | 891 if (matcher.matches()) { |
919 String name = matcher.group(2); | 892 String name = matcher.group(2); |
920 String value = matcher.group(4); | 893 String value = matcher.group(4); |
921 int opcode = Integer.parseInt(value); | 894 int opcode = Integer.parseInt(value); |
922 if (names[opcode] == null || !names[opcode].equalsIgnoreCase(name)) { | 895 if (nameArray[opcode] == null || !nameArray[opcode].equalsIgnoreCase(name)) { |
923 throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + names[opcode]); | 896 throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + nameArray[opcode]); |
924 } | 897 } |
925 if (opcode != lastExtendedOpcode + 1) { | 898 if (opcode != lastExtendedOpcode + 1) { |
926 System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")"); | 899 System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")"); |
927 opcode = lastExtendedOpcode + 1; | 900 opcode = lastExtendedOpcode + 1; |
928 line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4)); | 901 line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4)); |