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

hotspot101 problem with optimization

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P1 P1
    • 1.2.2
    • 1.0.1
    • hotspot
    • 1.2.2
    • generic
    • generic



      Name: kb87695 Date: 12/07/2000

      See description after the test case

      I want to report a bug that can be reproduced in SPARC. I am
      using the following Java specs.
      ^X
      java version "1.2.2"
      HotSpot VM (1.0.1, mixed mode)

      The VM was build using the following steps.

      1. Download the source. (hotspot-1_0_1-fcs-src-sol-06_aug_1999.zip)
      2. Build with gnumake optimized ( The bug is easily reproducible with
      the optimized build )
      3. Compile TestVP.java
      4. java -XX:MaxInlineSize=6 -XX:CompileThreshold=5 -XX:-BackgroundCompilation -XX:CompileOnly=TestVP.\<init\> TestVP

      The problem is in the hotspot compiler.

      The optimized build is preferable as we can manipulate some debug flags
      to inline String.length(), which is difficult to reproduce in the debug
      or product versions.

      I am also attaching the Java source code with the mail. Please let me
      know, what my steps should be in order to file the bug.

      The bug output is as follows:
      $ java -XX:MaxInlineSize=6 -XX:CompileThreshold=5 -XX:-BackgroundCompilation -XX:CompileOnly=TestVP.\<init\> TestVP

      Start test

      Loop: 1
      Loop: 2
      Loop: 3
      Exception in thread "main" java.lang.NullPointerException
              <<no stack trace available>>

      The right output should be (which can be got using the following options
      that does not inline the String.length() method)
      $ java -XX:MaxInlineSize=6 -XX:CompileThreshold=5
      -XX:CompileOnly=TestVP.\<init\> TestVP

      Start test

      Loop: 1
      Loop: 2
      Loop: 3
      Loop: 4
      Loop: 5
      Loop: 6
      Loop: 7
      Loop: 8
      Loop: 9
      Loop: 10

      Java Source
      /**
       * 2000/11/07
       * Test case to debug Hotspot compiler bug
       *
       * To run:
       * Using regular JAVA:
       * java -XX:MaxInlineSize=6 -Xcomp -XX:CompileThreshold=5 TestVP
       * Using optimized build:
       * java -XX:MaxInlineSize=6 -Xcomp -XX:CompileThreshold=5 -XX:CompileOnly=TestVP.\<init\> TestVP
       *
       * <IMPORTANT>: The testcase fails when String.length (5 bcs) is being inlined.
       *
       * TestVP constructor is very sensitive. Addition of printlns
       * make problem disappear (String.length won't get inlined).
       */

      class StringUtils
      {
              public static String[] dumbSplitString()
              {
                              String[] mElements = new String [3];
                              mElements[0]="";
                              mElements[1]="hi";
                              mElements[2]="";
                              return mElements;
              }
      }

      public class TestVP
      {
              //-------------------------------------
              // FIELDS
              //-------------------------------------

              /** Set of pathname elements */
              String[] mElements;

              /** offset into mElements at which entry's list of pathnames start */
              int mStart;

              /** number of elements beginning at mElements[mStart] */
              int mLength;

              //-------------------------------------
              // CONSTRUCTOR
              //-------------------------------------
              public TestVP () {
                              mElements = StringUtils.dumbSplitString();
                              mStart = 0;
                              mLength = mElements.length;
                              
                              while (mStart < mLength && mElements[mStart].length() == 0) {
                                      mStart++;
                                      mLength--;
                              }
                              while (mLength > 0 && mElements[mStart + mLength - 1].length() == 0) {
                                      mLength--;
                              }
                              //int length = mElements[mStart].length();
              }

              //-------------------------------------
              //-------------------------------------
              public static void main (String args[]) {
                      System.out.println ("\nStart test\n");
                      for (int i=1; i<=10; i++)
                      {
                          System.out.println ("Loop: " + i);
                              TestVP VP = new TestVP ();
                      }
              }
      }

      ###@###.### 2000-12-07
      This problem was verified on an Ultra 10 running Solaris 7



      (Review ID: 112892)
      ======================================================================
      kevin.brown@eng 2000-12-07

      The problem is in the compiler as I have studied the optoassembly of sparc as well as pa-risc. When you change the method, the intermediate representation of
      the method changes and the bug is no-longer visible. The hs20 optoassembly
      is fine in both sparc and pa-risc, which makes me think that there is a
      bug in the shared part of the compiler code.

      The problem starts immediately after the contructor for TEstVP
      inlines String.length(). At this point the the register that contains the
      array variable enters the loop fine and the first assignment works Ok.
      However, when it returns from the loop, it puts a NULL value into the
      register and this causes the problem.

      attached below is the opto-assembly dump that I got from sparc. I
      have commented the piece of code that I think caused the problem. My
      comments start with (// comment:). Please note that the loop basicblocks
      B10 to B14. The crash probably happens in B11. As I did not have a good
      sparc debugger, I could not verify my hypothesis, although the pa-risc
      debugger showed similar behavior.

            
      OPTO ASSEMBLY

      {method}
       - klass: {other class}
       - method holder: 'TestVP'
       - access: 1 public
       - name: '<init>'
       - signature: '()V'
       - max stack: 3
       - max locals: 1
       - code size: 117
       - constants: {constant pool}
       - exceptions: [I
       - line numbers: [S
       - local vars: [S
       - exception indices: [S
      0 load_local_object #0
      1 invoke_special 0 <<init>> <()V>
      4 load_local_object #0
      5 invoke_static 1 <dumbSplitString> <()[Ljava/lang/String;>
      8 put_field 2 <mElements>
      11 load_local_object #0
      12 push_int 0
      13 put_field 3 <mStart>
      16 load_local_object #0
      17 load_local_object #0
      18 get_field 2 <mElements>
      21 array_length
      22 put_field 4 <mLength>
      25 branch 48
      28 load_local_object #0
      29 dup
      30 get_field 3 <mStart>
      33 push_int 1
      34 arithmetic_int_add
      35 put_field 3 <mStart>
      38 load_local_object #0
      39 dup
      40 get_field 4 <mLength>
      43 push_int 1
      44 arithmetic_int_sub
      45 put_field 4 <mLength>
      48 load_local_object #0
      49 get_field 3 <mStart>
      52 load_local_object #0
      53 get_field 4 <mLength>
      56 branch_if_icmp_ge 87
      59 load_local_object #0
      60 get_field 2 <mElements>
      63 load_local_object #0
      64 get_field 3 <mStart>
      67 load_array_object
      68 invoke_virtual 5 <length> <()I>
      71 branch_if_eq 28
      74 branch 87
      77 load_local_object #0
      78 dup
      79 get_field 4 <mLength>
      82 push_int 1
      83 arithmetic_int_sub
      84 put_field 4 <mLength>
      87 load_local_object #0
      88 get_field 4 <mLength>
      91 branch_if_le 116
      94 load_local_object #0
      95 get_field 2 <mElements>
      98 load_local_object #0
      99 get_field 3 <mStart>
      102 load_local_object #0
      103 get_field 4 <mLength>
      106 arithmetic_int_add
      107 push_int 1
      108 arithmetic_int_sub
      109 load_array_object
      110 invoke_virtual 5 <length> <()I>
      113 branch_if_eq 77
      116 return_void
      #
      # void <init>( TestVP:NotNull * )
      #
      # R_I0 : parm 0: TestVP:NotNull *
      # -- Old R_SP -- Framesize: 72 --
      # R_SP+68: preserve
      # R_SP+64: preserve
      # R_SP+60: preserve
      # R_SP+56: preserve
      # R_SP+52: preserve
      # R_SP+48: preserve
      # R_SP+44: preserve
      # R_SP+40: preserve

      # R_SP+36: preserve
      # R_SP+32: preserve
      # R_SP+28: preserve
      # R_SP+24: preserve
      # R_SP+20: preserve
      # R_SP+16: preserve
      # R_SP+12: preserve
      # R_SP+ 8: preserve
      # R_SP+ 4: preserve
      # R_SP+ 0: preserve
      000 N198: # B1 <- BLOCK HEAD IS JUNK Loop: 0-21#0 IDom: 0/#1 Freq: 1.0e+00
      000 ---- MachUEPNode ----
      01c NOP # Pad for loops
      020
      020 B1: # B17 B2 <- BLOCK HEAD IS JUNK Loop: 0-21#0 IDom: 0/#2 Freq: 1.0e+00
      020 --- MachPrologNode ----
      02c CALL,static ; NOP ==> StringUtils::dumbSplitString
              # TestVP::<init> @ bci:5 L0=R_I0 STK0=R_I0
              # R_I0=Oop
      034
      034 B2: # B20 B3 <- B1 Loop: 0-21#0 IDom: 1/#3 Freq: 1.0e+00
      034 STW R_O0,[[R_I0 + #8]] !ptr
      038 SRL R_I0,#9,R_I1
      03c SET 0xee512000,R_I2 !ptr
      044 STB #0,[[R_I2 + R_I1]] !ptr
      048 MOV #0,R_L0
      04c STW R_L0,[[R_I0 + #12]]
      050 LDUW [R_O0 + #8],R_I1 !range
      054 NullCheck R_O0
      054
      054 B3: # B4 <- B2 Loop: 0-21#0 IDom: 2/#4 Freq: 1.0e+00
      054 STW R_I1,[[R_I0 + #16]]
      058 MOV R_I1,R_I2
      05c NOP # Pad for loops
      060
      060 B4: # B9 B5 <- B3 B8 Loop: 4-8#1 IDom: 3/#5 Freq: 1.0e+01
      060 SUBCC R_L0,R_I2,R_G0
      064 BPCCodege B9 # 0x0b0
      06c
      06c B5: # B19 B6 <- B4 Loop: 4-8#1 IDom: 4/#6 Freq: 9.0e+00
      06c SUBCC R_L0,R_I1,R_G0
      070 BPCuCodege B19 # 0x144
      078
      078 B6: # B20 B7 <- B5 Loop: 4-8#1 IDom: 5/#7 Freq: 9.0e+00
      078 SLL R_L0,#2,R_I3
      07c ADD R_O0,R_I3,R_I3
      080 LD [R_I3 + #12],R_I3 !ptr
      084 LDUW [R_I3 + #16],R_I3
      088 NullCheck R_I3
      088
      088 B7: # B9 B8 <- B6 Loop: 4-8#1 IDom: 6/#8 Freq: 9.0e+00
      088 Safepoint_ # TestVP::<init> @ bci:71 L0=R_I0
              # R_I0=Oop R_O0=Oop
      08c SUBCC R_I3,#0,R_G0
      090 BPCCodene B9 # 0x0b0
      098
      098 B8: # B4 <- B7 Loop: 4-8#1 IDom: 7/#9 Freq: 8.1e+00
      098 ADD R_L0,#1,R_L0
      09c STW R_L0,[[R_I0 + #12]]
      0a0 ADD R_I2,#-1,R_I2
      0a4 STW R_I2,[[R_I0 + #16]]
      0a8 BPA B4 # 0x060
      0b0
      0b0 B9: # B10 <- B7 B4 Loop: 0-21#0 IDom: 4/#6 Freq: 1.9e+00
      0b0 MOV R_O0,R_I1 !ptr
      0b4 NOP # Pad for loops
      0b8 NOP # Pad for loops
      0bc NOP # Pad for loops
      0c0
      0c0 B10: # B16 B11 <- B9 B15 Loop: 10-15#1 IDom: 9/#7 Freq: 1.9e+01
      0c0 LDUW [R_I0 + #16],R_I2
      0c4 SUBCC R_I2,#0,R_G0
      0c8 BPCCodele B16 # 0x11c
      0d0
      0d0 B11: # B20 B12 <- B10 Loop: 10-15#1 IDom: 10/#8 Freq: 1.7e+01
      0d0 LDUW [R_I1 + #8],R_I3 !range // comment !!CRASH
      0d4 NullCheck R_I1
      0d4

      0d4 B12: # B18 B13 <- B11 Loop: 10-15#1 IDom: 11/#9 Freq: 1.7e+01
      0d4 ADD R_L0,R_I2,R_I4
      0d8 ADD R_I4,#-1,R_I5
      0dc SUBCC R_I5,R_I3,R_G0
      0e0 BPCuCodege B18 # 0x134
      0e8
      0e8 B13: # B20 B14 <- B12 Loop: 10-15#1 IDom: 12/#10 Freq: 1.7e+01
      0e8 SLL R_I4,#2,R_I3
      0ec ADD R_I1,R_I3,R_I1
      0f0 LD [R_I1 + #8],R_I1 !ptr
      0f4 LDUW [R_I1 + #16],R_I1
      0f8 NullCheck R_I1
      0f8
      0f8 B14: # B16 B15 <- B13 Loop: 10-15#1 IDom: 13/#11 Freq: 1.7e+01
      0f8 Safepoint_ # TestVP::<init> @ bci:113 L0=R_I0
              # R_I0=Oop
      0fc SUBCC R_I1,#0,R_G0

      100 BPCCodene B16 # 0x11c
      108
      108 B15: # B10 <- B14 Loop: 10-15#1 IDom: 14/#12 Freq: 1.5e+01
      108 ADD R_I2,#-1,R_I1
      10c STW R_I1,[[R_I0 + #16]]
      110 SET NULL,R_I1 !ptr // comment: Setting the NULL value and returning to the loop
      114 BPA B10 # 0x0c0
      11c
      11c B16: # N198 <- B14 B10 Loop: 0-21#0 IDom: 10/#8 Freq: 3.6e+00
      11c RESTORE
      120 RET ; NOP
      128
      128 B17: # B21 <- B1 Loop: 0-21#0 IDom: 1/#3 Freq: 1.0e-06

      128 MOV R_O0,R_I0 !ptr
      12c BPA B21 # 0x160
      134
      134 B18: # N198 <- B12 Loop: 0-21#0 IDom: 12/#10 Freq: 1.7e-05
      134 MOV #-5,R_O0
      138 CALL,static ; NOP ==> wrapper for: uncommon_trap
              # TestVP::<init> @ bci:109 L0=R_I0 STK0=R_I1 STK1=R_I5
              # R_I0=Oop R_I1=Oop
      140 ILLTRAP ; ShouldNotReachHere
      144
      144 B19: # N198 <- B5 Loop: 0-21#0 IDom: 5/#7 Freq: 9.0e-06
      144 MOV R_O0,R_I1 !ptr
      148 MOV #-5,R_O0
      14c CALL,static ; NOP ==> wrapper for: uncommon_trap
              # TestVP::<init> @ bci:67 L0=R_I0 STK0=R_I1 STK1=R_L0
              # R_I0=Oop R_I1=Oop
      154 ILLTRAP ; ShouldNotReachHere
      158
      158 B20: # B21 <- B2 B6 B13 B11 Loop: 0-21#0 IDom: 2/#4 Freq: 4.4e-11
      158 SET java/lang/NullPointerException:0xe9c37328 *,R_I0 !ptr
      160
      160 B21: # N198 <- B20 B17 Loop: 0-21#0 IDom: 1/#3 Freq: 1.0e-12
      160 RESTORE
      164 JMP rethrow_stub
      170

            azeemj Azeem Jiva
            kevibrow Kevin Brown
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: