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

Compiler 2 data flow problem, involving longs.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P1 P1
    • 1.3.1
    • 1.3.1
    • hotspot
    • beta
    • generic
    • generic



        Name: kb87695 Date: 12/01/2000


        This bug was verified on a Solaris 7 Machine with the following java:
        %java_g -version
        java version "1.3.0_01"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_01)
        Java HotSpot(TM) Server VM (build 1.3-internal-release, mixed mode)
        (This is from Hotspot 1.3.1 build 10 source)



        Bug Report: This bug is reproducible in HS20 on sparc box. It is a compiler bug in hs20
         server VM.

        The VM was build using the following steps.

        1. Download the source. (hotspot_server-1_3_1-pre-beta-src-b09-solsparc-22_nov_2000.zip)

        2. Build with gnumake debug

          To reproduce the bug use the following command
        Its the server VM with the following version
        $ java_g -version
          java version "1.2.2"
          Java HotSpot(TM) Server VM (mixed mode)
        $ java_g -Xcomp -XX:CompileOnly=Foo.encodeInteger -XX:CompileThreshold=5 Foo

        It is also reproducible with java(product version) with jdk1.2.2, if the limit
        (which is the no. of times encodeInteger is called) is high as 0xfffffff. With
        java_g we can get a lower CompileThreshold which is not available in java.

        The program runs fine with the -Xint option. However, with the above option, a large
        number of errors get printed. The problem as I can see is in the sign extension part
        of the code, which is in the if block following the do-while block. It is not entering
        this piece of code when it should.

        The correct output is nothing.
        $ java_g -Xint Foo
        $

        The incorrect output is as follows.
        $ java_g -Xcomp -XX:CompileOnly=.encodeInteger -XX:CompileThreshold=5 Foo
        VM option 'CompileOnly=.encodeInteger'
        VM option 'CompileThreshold=5'
        ERROR: Encoded int value 128 decoded as -128
        ERROR: Encoded int value 131 decoded as -125
        ERROR: Encoded int value 132 decoded as -124
        ERROR: Encoded int value 133 decoded as -123
        ERROR: Encoded int value 134 decoded as -122
        ERROR: Encoded int value 135 decoded as -121
        ERROR: Encoded int value 136 decoded as -120
        ERROR: Encoded int value 137 decoded as -119
        ERROR: Encoded int value 138 decoded as -118
        ERROR: Encoded int value 139 decoded as -117

        The limit of the value that is passed to encodeInteger must be greater than 128 to get
        the error. The error is not produced unless the encodeInteger method is compiled.


        // Test case
        public class Foo
        {
          protected static void encodeInteger(long value, byte[] coding, int index)
          {
            int end = index;
            long v = value;

            do {
              coding[--index] = (byte)v;
              v >>= 8;
            } while (v != 0 && v != -1); // Until just sign

            // Check if the sign of the end byte and value are different
            if (v == 0 && coding[index] < 0 || v == -1 && coding[index] >= 0){
              //System.out.println("Entered for sign extension");
              coding[--index] = (byte)v; // Sign resolver byte
            }

            int length = (end - index - 1);
            int testIndex = index;
            coding[--index] = (byte)(end - index - 1); // Length: 1-4
            //index = encodeTag(object.getAsnType(), coding, index);

            // reconstitute the value and test to be sure it's what we expected
            long origV = value;
            long testV = ((int)coding[testIndex] >> 8); // Sign extend
            while (length-- >= 0) {
              testV = (testV << 8) | (coding[testIndex++] & 0xff);
            }
            if (testV != origV)
              System.out.println("ERROR: Encoded int value " + origV + " decoded as " + testV);
          }

          public static void main(String[] args)
          {
            byte[] coding = new byte[10];
            //for (long value = 0; value < 0xfffffff; value++) {
            for (long value = 0; value < 140; value++) {
              encodeInteger(value, coding, coding.length);
            }
          }
        }

        ###@###.### 2000-12-01

        (Review ID: 112891)
        ======================================================================

              cclicksunw Clifford Click (Inactive)
              kevibrow Kevin Brown
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: