Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
|
Relates :
|
Following test case is failing from JDK7 build 20 <testcase> import java.util.*; public class VectorIntegerTest { static Random rnd = new Random(); public static void main(String[] args) throws Exception { List<Integer> list1 = new Vector<Integer>(); AddRandoms(list1, 400); List<Integer> list2 = new Vector<Integer>(); AddRandoms(list2, 400); List<Integer> copyofs2 = new Vector<Integer>(); copyofs2.addAll(list2); if (!list2.equals(copyofs2)) throw new Exception("Exception"); list1.clear(); list1.addAll(0,list2); if (!(list1.equals(list2) && list2.equals(list1))) throw new Exception ("Exception"); if (!(list1.equals(list2) && list2.equals(list1))) throw new Exception("Exception"); List<Integer> l = new Vector<Integer>(); AddRandoms(l,400); Integer [] ia = l.toArray(new Integer[0]); if (!l.equals(Arrays.asList(ia))) throw new Exception("Exception"); } static void AddRandoms(List<Integer> s, int n) throws Exception { for (int i=0; i<n; i++) { int r = rnd.nextInt() % n; Integer e = new Integer(r < 0 ? -r : r); s.add(e); } } } </testcase> <output> bash-3.00$ /net/sqindia/export/disk09/jdk/7/b17/binaries/solsparc/bin/java VectorIntegerTest bash-3.00$ /net/sqindia/export/disk09/jdk/7/b18/binaries/solsparc/bin/java VectorIntegerTest bash-3.00$ /net/sqindia/export/disk09/jdk/7/b19/binaries/solsparc/bin/java VectorIntegerTest **** failing from build 20 ****** bash-3.00$ /net/sqindia/export/disk09/jdk/7/b20/binaries/solsparc/bin/java VectorIntegerTest Exception in thread "main" java.lang.IncompatibleClassChangeError at java.util.AbstractList.equals(AbstractList.java:522) at java.util.Vector.equals(Vector.java:953) at VectorIntegerTest.VectorIntegerTestTest01(VectorIntegerTest.java:63) at VectorIntegerTest.main(VectorIntegerTest.java:9) bash-3.00$ /net/sqindia/export/disk09/jdk/7/b21/binaries/solsparc/bin/java VectorIntegerTest Exception in thread "main" java.lang.IncompatibleClassChangeError at java.util.AbstractList.equals(AbstractList.java:522) at java.util.Vector.equals(Vector.java:953) at VectorIntegerTest.VectorIntegerTestTest01(VectorIntegerTest.java:63) at VectorIntegerTest.main(VectorIntegerTest.java:9) </output> Additional comments and test case from Christian Wimmer (###@###.###) from the C1 collaborative research project (also on the bugs.sun.com public database): I get a similar bug: the "eclipse" benchmark of the DaCapo benchmark suite fails with the latest JDK 7 builds (starting with build b20 which changed the handling of dependencies). In debug builds, a message is printed that a method should have been marked for deoptimization, but was not marked by the optimized dependency checking code. I could reduce the problem to the small testcase that is attached. The Interface has two implementations: the classes Impl1 and Impl2. At first, only Impl1 is loaded, so the method of the interface call can be inlined because there is only one implementation. When the second implementation is loaded, the method must be deoptimized. The second class Impl2 implements the Interface, but the method is already defined in the base class BaseImpl2. The optimized dependency checking code only looks at the methods defined in Impl2, does not see the method, and therefore does not trigger deoptimization. The slow verification code of the debug build detects the inconsistency and prints an error (I would prefer an assertion in such cases). A possible fix would be to also look at methods defined in superclasses. When the line 753 in the file dependencies.cpp is changed from methodOop m = instanceKlass::cast(k)->find_method(_name, _signature); to methodOop m = instanceKlass::cast(k)->uncached_lookup_method(_name, _signature); the dependency checking is correct in my example. However, I do not know if this change causes other problems (it could detect too many conflicts) or is too slow. [Follow-up from Christian: My nightly benchmarks revealed that my possible fix of the bug is too conservative. It literally kills the performance of some benchmarks, e.g. _227_mtrt is more than 50% slower because many accessor methods are no longer inlined. So just forget my suggestion...] public class DependencyBug { public static interface Interface { public void method(); } public static class Impl1 implements Interface { public void method() { // Nothing to do here } } public static class BaseImpl2 { public void method() { System.out.print("#"); } } public static class Impl2 extends BaseImpl2 implements Interface { // Interface method already implemented in base class. } public static void callMethod(Interface obj) { // method() is inlined as long as only class Impl1() is loaded. obj.method(); } public static void main(String[] args) throws Exception { Interface obj = new Impl1(); for (int i = 0; i < 2000; i++) { // Force compilation of the method callMethod() callMethod(obj); } System.out.println("**** Initiating class loading of Impl2 ****"); obj = new Impl2(); callMethod(obj); } } JDK: 7, 6u10 b09 testbase: /net/cady/export/dtf/unified/knight-ws/suites/6.0_cady/libs Failing testcases: java_util/generics/list/LinkedListDoubleTest java_util/generics/list/LinkedListIntegerTest failing cases: java_util/generics/list/VectorIntegerTest java_util/generics/list/VectorDoubleTest java_util/generics/list/ArrayListDoubleTest java_util/generics/list/ArrayListIntegerTest java_util/generics/list/StackDoubleTest java_util/generics/list/StackIntegerTest
|