1 /*
   2  * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 /**
  26  * @test
  27  * @bug 6851282
  28  * @summary JIT miscompilation results in null entry in array when using CompressedOops
  29  *
  30  * @run main/othervm/timeout=600 -Xmx256m -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops Test
  31  */
  32 
  33 import java.util.ArrayList;
  34 import java.util.List;
  35 
  36 public class Test {
  37   void foo(A a, A[] as) {
  38     for (A a1 : as) {
  39       B[] filtered = a.c(a1);
  40       for (B b : filtered) {
  41         if (b == null) {
  42           System.out.println("bug: b == null");
  43           System.exit(97);
  44         }
  45       }
  46     }
  47   }
  48 
  49   public static void main(String[] args) {
  50     List<A> as = new ArrayList<A>();
  51     for (int i = 0; i < 5000; i++) {
  52       List<B> bs = new ArrayList<B>();
  53       for (int j = i; j < i + 1000; j++)
  54         bs.add(new B(j));
  55       as.add(new A(bs.toArray(new B[0])));
  56     }
  57     new Test().foo(as.get(0), as.subList(1, as.size()).toArray(new A[0]));
  58   }
  59 }
  60 
  61 class A {
  62   final B[] bs;
  63 
  64   public A(B[] bs) {
  65     this.bs = bs;
  66   }
  67 
  68   final B[] c(final A a) {
  69     return new BoxedArray<B>(bs).filter(new Function<B, Boolean>() {
  70       public Boolean apply(B arg) {
  71         for (B b : a.bs) {
  72           if (b.d == arg.d)
  73             return true;
  74         }
  75         return false;
  76       }
  77     });
  78   }
  79 }
  80 
  81 class BoxedArray<T> {
  82 
  83   private final T[] array;
  84 
  85   BoxedArray(T[] array) {
  86     this.array = array;
  87   }
  88 
  89   public T[] filter(Function<T, Boolean> function) {
  90     boolean[] include = new boolean[array.length];
  91     int len = 0;
  92     int i = 0;
  93     while (i < array.length) {
  94       if (function.apply(array[i])) {
  95         include[i] = true;
  96         len += 1;
  97       }
  98       i += 1;
  99     }
 100     T[] result = (T[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), len);
 101     len = 0;
 102     i = 0;
 103     while (len < result.length) {
 104       if (include[i]) {
 105         result[len] = array[i];
 106         len += 1;
 107       }
 108       i += 1;
 109     }
 110     return result;
 111   }
 112 }
 113 
 114 interface Function<T, R> {
 115   R apply(T arg);
 116 }
 117 
 118 class B {
 119   final int d;
 120   public B(int d) {
 121     this.d = d;
 122   }
 123 }
 124