JDK-6898184 : REGRESSION:HotSpot compiler produce different result when run under server and client
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6u18
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2009-11-04
  • Updated: 2010-04-26
  • Resolved: 2009-11-04
Related Reports
Duplicate :  
Description
J2SE Version (please include all output from java -version flag):
java version "1.6.0_18-ea"
Java(TM) SE Runtime Environment (build 1.6.0_18-ea-b04)
Java HotSpot(TM) Server VM (build 16.0-b11, mixed mode, sharing)


Does this problem occur on J2SE 1.4.x, 1.5 or 6?  Yes / No (pick one)
since 6u14
, worked fine with 1.5.0_14 client and server

Operating System Configuration Information (be specific):
We distribute on linux x86, linux amd64, win32, win64,
Solaris amd64, and Solaris SPARC.

Hardware Configuration Information (be specific):

generic

Bug Description:

There is a problem with the Hotspot compiler in Java versions beginning with 1.6u14.  
The same code when run will produce different (incorrect) results when run under
Hotspot server vs. correct results under Hotspot client.

This is extremely serious issue for the CAP member, as they don't know in what other
situations this bug may occur.  They moved to 1.6u14 in their September
product release, and this is used widely in a number of industries, including the financial sector.


Steps to Reproduce (be specific):

Here is a simple class that shows the problem:

//////////////////////////
public class Test
{
public static void main (String[] args)
{
    final int size = 15;
    int[] xIn = new int[size];
    int[] yIn = new int[size];
    int[] xOut = new int[size];
    int[] yOut = new int[size];

    for (int i = 0; i < 10; ++i) {

        for (int j = 0; j < 1000; ++j)
            transformArrays(xIn, yIn, xOut, yOut);

        String msg = i + ". xOut= ";
        for (int x : xOut) 
            msg += x + ",";
        System.out.println(msg);
    }
}

private static void transformArrays (int xIn[], int yIn[],
             int xOut[], int yOut[])
{
    for (int i = 0; i < xIn.length; i++) {
        xOut[i] = xIn[i];
        yOut[i] = yIn[i];
        add11(xOut, yOut, i);
    }
}

static void add11 (int x[], int y[], int i)
{
    x[i] += 11;
    y[i] += 11;
}
}

This class just iterates over a few arrays and adjusts the value of each
element to 11, then prints out one of the arrays. When you run this
class using the 1.6.0_14+ client vm, the output looks correct:

0. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
1. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
2. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
3. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
4. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
5. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
6. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
7. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
8. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
9. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,

However, when you run using the 1.6.0_14+ server vm, you can see that
the output is incorrect - several elements are 0:

0. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
1. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
2. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
3. xOut= 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
4. xOut= 11,0,11,0,11,0,11,0,11,0,11,0,11,11,11,
5. xOut= 11,0,11,0,11,0,11,0,11,0,11,0,11,11,11,
6. xOut= 11,0,11,0,11,0,11,0,11,0,11,0,11,11,11,
7. xOut= 11,0,11,0,11,0,11,0,11,0,11,0,11,11,11,
8. xOut= 11,0,11,0,11,0,11,0,11,0,11,0,11,11,11,
9. xOut= 11,0,11,0,11,0,11,0,11,0,11,0,11,11,11,

This problem goes away if you use the -Xint vm option which disables the
hotspot optimizing compiler. This problem does not show up on 1.5.0_14
client or server.

When draw a polygon, there are 2 arrays, the x points and y
points. Before drawing the polygon, we loop over these arrays, copy the
values to temporary arrays, and add an offset to each point (the offset
is the distance from the 0, 0 point in the display):

protected void pta_xfto (GmsMatrix mat, int xx[], int yy[], int count,
                   int xx2[], int yy2[])
(
      int i;
      for (i = 0; i < count; i++) {
            xx2[i] = xx[i];
            yy2[i] = yy[i];
            if (mat != null) {
                        // adjust the point
                  mat.xfpt(xx2, yy2, i);
            }
      }
}

When you run in -server mode, some of the x values are not being offset,
just like in the rbt above. suspect that the optimizer is confused by
a loop which copies and modifies elements in 2 arrays, so we removed the
code that copies the elements from the loop and replaced it with  2
calls to System.arraycopy(), above the loop. This fixes the problem:

pta_xfto (GmsMatrix mat, int xx[], int yy[], int count,

                   int xx2[], int yy2[])
{
      if (xx2 != xx)
            System.arraycopy(xx, 0, xx2, 0, count);
      if (yy2 != yy)
            System.arraycopy(yy, 0, yy2, 0, count);
      if (mat == null) return;
      for (int i = 0; i < count;i++)
                        // adjust the points
            mat.xfpt(xx2, yy2, i);
}

The problem with this workaround is that it only addresses the symptom
that customer found. We don't know what other loops in our code might be
having the same issue. This bug was easy to spot since it impacted the
rendering, but it's possible that there are other loops where the
problem isn't so obvious. So, we can provide a patch to customer that
will fix the graphics problem, but we cannot guarantee that there are
not other problems due to the jvm bug.

Comments
WORK AROUND -XX:-UseSuperWord
04-11-2009