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

code fails with impossible ArrayIndexOutOfBounds Exception

XMLWordPrintable

    • b91
    • sparc
    • solaris_10

        FULL PRODUCT VERSION :
        The code fails on the server compiler for 1.4.2, 1.5.0 and all the mustang builds I have, including
        Java(TM) SE Runtime Environment (build 1.6.0-beta2-b85)
        Java HotSpot(TM) Server VM (build 1.6.0-beta2-b85, mixed mode)


        FULL OS VERSION :
        SunOS eyas 5.9 Generic_118558-11 sun4u sparc SUNW,Sun-Fire-480R
        SunOS noisy 5.10 Generic_118833-03 sun4u sparc SUNW,Sun-Fire-V490
        Linux hoopoe 2.6.11.4-21.11-default #1 Thu Feb 2 20:54:26 UTC 2006 i686 i686 i386 GNU/Linux
        Windows XP

        This failure happens on every linux and Solaris version I've tried

        A DESCRIPTION OF THE PROBLEM :
        The attached code fails when run with the -server compiler. It fails on Solaris+sparc and linux+x86 for the 1.4.2, 1.5 and 1.6 server JVMs. The -client compiler runs the code fine.

        The code fails immediately once the target function f() is compiled by HotSpot (I'm running with -XX:+PrintCompilation).

        If I lower the CompileThreshold down to ~500, then the error no longer happens.

        I'm guessing this is a loop unrolling problem.

        The test case is a bit twisted; it was part of a much larger application which would fail intermitently because of this problem, but we were never able to reproduce the error.

        THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

        THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        compile and run the test code with the server compiler

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        The results I expect:

        hoopoe$ jdk1.6.0/bin/java -client Loop
        done...


        The results I get with the server compiler

        hoopoe$ jdk1.6.0/bin/java -server Loop
        i=2
        index=252
        w.length=2
        ol.length=253
        nl.length=2
        java.lang.ArrayIndexOutOfBoundsException: 2
                at Loop.f(Loop.java:29)
                at Loop.main(Loop.java:5)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------

        public class Loop {
            
            public static void main(String[] args) throws Exception {
                for (int i = 0; i < 1000000; i++)
                    f();
                System.out.println("done...");
            }
            
            
        // a fake function to always return 2, but to prevent the optimizer from knowing this...
            private static int length() {
                double x = Math.random();
                if (x < 2)
                    return 2;
                else
                    return 10;
            }
            
            
            private static void f() {
                final int lag = 3;
                
                double[] nl = new double[length()];
                double[] ol = new double[253];
                double[] w = new double[nl.length];
                
                for(int i = 0; i < nl.length; i++) {
                    try {
                        if (i < lag)
                            w[i] = ol[ol.length - lag + i];
                        else
                            w[i] = nl[i-lag];
                    } catch (Exception e) {
        // the index i is 2, eve though that shouldn't be possible
        // because the array length of nl is always 2.
        // we're failing on the indexing of w[2]
                        System.err.println("i="+i);
                        System.err.println("index="+(ol.length - lag + i));
                        System.err.println("w.length="+w.length);
                        System.err.println("ol.length="+ol.length);
                        System.err.println("nl.length="+nl.length);
                        e.printStackTrace();
                        System.exit(1);
                    }
                }
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        I can work around this by using the client compiler, which isn't acceptable on our large systems. The server compiler does give a nice performance boost.

        I can also defeat the (loop-unrolling?) optimization by adding a check for
        if (i >= nl.length)
            throw new Exception();
        which should never be taken.


        So, even while I have a workaround in place, this has been a major problem for us. While the test case here is trivial, this is part of a big application which would fail in random ways because of this problem. In fact, we were never able to reproduce the problem until recently, and even then it would take hours of running each time to help isolate the problem.

        I'm flagging this as a severe error (even though I have a workaround) because it is a severe error. Now that the -server compiler is the default on larger systems, it's important to not have these errors.

              rknippelsunw Ross Knippel (Inactive)
              rmandalasunw Ranjith Mandala (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: