United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6851282 JIT miscompilation results in null entry in array when using CompressedOops
JDK-6851282 : JIT miscompilation results in null entry in array when using CompressedOops

Details
Type:
Bug
Submit Date:
2009-06-15
Status:
Closed
Updated Date:
2011-03-09
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
windows_2003,linux,solaris_10
Sub-Component:
compiler
CPU:
x86,sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u10,6u14
Fixed Versions:
hs16 (b07)

Related Reports
Backport:
Backport:
Backport:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b59)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b03, mixed mode)


FULL OS VERSION :
Linux mac 2.6.29.4-162.fc11.x86_64 #1 SMP Mon May 25 16:51:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When executing the included program, the array will contain null fields after the server JIT recompiles some of the methods even though that should be impossible.

This only happens with -XX:+UseCompressedOops. I tested with JDK6u14 and the latest JDK7 snapshot (b59)

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the included program with JDK6u14 -server -XX:+UseCompressedOops

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected results: nothing gets printed to the console

Actual results: The word "bug" is printed a few times.

Note that the problem does not occur if -XX:+UseCompressedOops is not used.
REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test;

import java.util.ArrayList;
import java.util.List;


public class Hs {
  void foo(A a, A[] as) {
    for (A a1 : as) {
      B[] filtered = a.c(a1);
      for (B b : filtered)
        if (b == null) {
          System.out.println("bug");
        }
    }
  }
  
  public static void main(String[] args) {
    List<A> as = new ArrayList<A>();
    for (int i = 0; i < 5000; i++) {
      List<B> bs = new ArrayList<B>();
      for (int j = i; j < i + 1000; j++)
        bs.add(new B(j));
      as.add(new A(bs.toArray(new B[0])));
    }
    new Hs().foo(as.get(0), as.subList(1, as.size()).toArray(new A[0]));
  }
}

class A {
  final B[] bs;
  
  public A(B[] bs) {
    this.bs = bs;
  }
  
  final B[] c(final A a) {
    return new BoxedArray<B>(bs).filter(new Function<B, Boolean>() {
      public Boolean apply(B arg) {
        for (B b : a.bs) {
          if (b.d == arg.d)
            return true;
        }
        return false;
      }
    });
  }
}

class BoxedArray<T> {
  
  private final T[] array;
  
  BoxedArray(T[] array) {
    this.array = array;
  }
  
  public T[] filter(Function<T, Boolean> function) {
    boolean[] include = new boolean[array.length];
    int len = 0;
    int i = 0;
    while (i < array.length) {
      if (function.apply(array[i])) {
        include[i] = true;
        len += 1;
      }
      i += 1;
    }
    T[] result = (T[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), len);
    len = 0;
    i = 0;
    while (len < result.length) {
      if (include[i]) {
        result[len] = array[i];
        len += 1;
      }
      i += 1;
    }
    return result;
  }
}

interface Function<T, R> {
  R apply(T arg);
}

class B {
  final int d;
  public B(int d) {
    this.d = d;
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Remove -XX:+UseCompressedOops switch.

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/64219d2a6493
                                     
2009-07-17
EVALUATION

PhiNode::Ideal() has optimization which pushes DecodeN node
down through Phi. But it may set incorrect type (TOP) for
new Phi node when it use DecodeN's input on dead path.
                                     
2009-07-17
SUGGESTED FIX

Get type for new Phi from non dead path.
                                     
2009-07-17
PUBLIC COMMENTS

Problem:
PhiNode::Ideal() has optimization which pushes DecodeN node
down through Phi. But it may set incorrect type (TOP) for
new Phi node when it use DecodeN's input on dead path.

Solution:
Get type for new Phi from non dead path.
                                     
2009-07-17
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/64219d2a6493
                                     
2009-07-27



Hardware and Software, Engineered to Work Together