Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6370653

javac does not use iinc opcode for postfix decrement of local variable

XMLWordPrintable

    • b79
    • generic
    • generic
    • Verified

      A DESCRIPTION OF THE FIX :
        Bug Description : javac does not use iinc opcode for postfix decrement of local variable.
      Generally, javac produces code that evaluates postfix decrement correctly. But looking to the sources I found some asymmetry and I think it was not made intentionally.
      Subset of Releases affected : 1.4.2, 1.5.0, Mustang b65.
      Platforms affected : all
      Test case : See Test case section.
      Diff baseline : Mustang b65
      Diff :
      --- j2se/src/share/classes/com/sun/tools/javac/jvm/Gen.java.prev Tue Dec 27 20:43:22 2005
      +++ j2se/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Jan 06 21:42:42 2006
      @@ -1783,41 +1783,42 @@
        case JCTree.PREINC: case JCTree.PREDEC:
        od.duplicate();
        if (od instanceof LocalItem &&
        (operator.opcode == iadd || operator.opcode == isub)) {
        ((LocalItem)od).incr(tree.tag == JCTree.PREINC ? 1 : -1);
        result = od;
        } else {
        od.load();
        code.emitop0(one(od.typecode));
        code.emitop0(operator.opcode);
        // Perform narrowing primitive conversion if byte,
        // char, or short. Fix for 4304655.
        if (od.typecode != INTcode &&
        Code.truncate(od.typecode) == INTcode)
        code.emitop0(int2byte + od.typecode - BYTEcode);
        result = items.makeAssignItem(od);
        }
        break;
        case JCTree.POSTINC: case JCTree.POSTDEC:
        od.duplicate();
      - if (od instanceof LocalItem && operator.opcode == iadd) {
      + if (od instanceof LocalItem &&
      + (operator.opcode == iadd || operator.opcode == isub)) {
        Item res = od.load();
        ((LocalItem)od).incr(tree.tag == JCTree.POSTINC ? 1 : -1);
        result = res;
        } else {
        Item res = od.load();
        od.stash(od.typecode);
        code.emitop0(one(od.typecode));
        code.emitop0(operator.opcode);
        // Perform narrowing primitive conversion if byte,
        // char, or short. Fix for 4304655.
        if (od.typecode != INTcode &&
        Code.truncate(od.typecode) == INTcode)
        code.emitop0(int2byte + od.typecode - BYTEcode);
        od.store();
        result = res;
        }
        break;
        case JCTree.NULLCHK:
        result = od.load();
        code.emitop0(dup);


      JUnit TESTCASE :
      This is not JUnit style test. This is just a proof that patch focuses on the problem.
      Here is sample class:
      // Main.java
      public class Main {
      private static boolean test() {
      int x = 10;
      int y = x--;
      // check whether generated code still works correctly
      return (x == 9) && (y == 10);
      }

      public static void main(String[] args) {
      boolean ok = test();
      System.out.println("ok = " + ok);
      System.exit(ok? 0: 1);
      }
      }
      And generated code for method "test()" differs in such a way:

       private static boolean test();
         Code:
      - Stack=3, Locals=2, Args_size=0
      + Stack=2, Locals=2, Args_size=0
               bipush 10
               istore_0
               iload_0
      - dup
      - iconst_1
      - isub
      - istore_0
      + iinc 0, -1
               istore_1
               iload_0
               bipush 9
               if_icmpne @else
               iload_1
               bipush 10
               if_icmpne @else
               iconst_1
               goto @end
          @else:
               iconst_0
          @end:
               ireturn

            wtaosunw Wei Tao (Inactive)
            tbell Tim Bell
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: