United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6832293 JIT compiler got wrong result in type checking with -server
6832293 : JIT compiler got wrong result in type checking with -server

Details
Type:
Bug
Submit Date:
2009-04-21
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
windows_xp
Sub-Component:
compiler
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u12
Fixed Versions:
hs16

Related Reports
Backport:
Backport:
Relates:

Sub Tasks

Description
The test case below is based on one jck test case which fails on windows with -server on all version of JDK 6.   I tried to initialize some classes before the "run" method and jit compiler will return the wrong result.

The licensee added a develop-only option in the VM which tries to eagerly initialize a class when compiling a methed. So they can reduce uncommon traps in generated code. Of course some jck cases will fail if the initialize order is important. But in this case, I don't think eagerly initializing a class should cause a problem. So I traced these eagerly initializing class and initialized them in java code. I tested my new case without the develop-only option and it failed again. So I think it's a bug of jit compiler and tested it on windows platform. I tested it against 6u12.  

The test case does not fail on Solaris.

Source code:
/*
 * @(#)conv08301.java	1.8 01/12/07
 *
 * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */




import java.io.PrintStream;


interface SomeInterface {

	int SEVENS = 777;

}


interface AnotherInterface {

	int THIRDS = 33;

}


class SomeClass
implements SomeInterface {

	int i;

	SomeClass(int i) {
		this.i = i;
	}

}


class ImmediateSubclass
extends SomeClass
implements SomeInterface {

	float f;

	ImmediateSubclass(int i, float f) {
		super(i);
		this.f = f;
	}

}


final class FinalSubclass
extends ImmediateSubclass
implements AnotherInterface {

	double d;

 	FinalSubclass(int i, float f, double d) {
		super(i, f);
		this.d = d;
	}

}


public class conv08301 {

	public static void main(String args[]) throws Exception{
		/* try to pre initialize */
		SomeClass[] a=new SomeClass[10];
		Class.forName("ImmediateSubclass");
		Class.forName("FinalSubclass");
		System.exit(run(args, System.out) + 95/*STATUS_TEMP*/); 
	} 
 
	static int errorStatus = 0/*STATUS_PASSED*/;

	static void errorAlert(PrintStream out, int errorLevel) {
		out.println("conv08301: failure #" + errorLevel);
		errorStatus = 2/*STATUS_FAILED*/;
	}

	public static int run(String args[],PrintStream out) { 
		int i [], j [];
		SomeInterface u [], v[] [];
		AnotherInterface w [];
		SomeClass x [] [];

		i = new int [10];
		i[0] = 777;
		j = (int []) i;
		if (j != i)
			errorAlert(out, 2);
		else if (j.length != 10)
			errorAlert(out, 3);
		else if (j[0] != 777)
			errorAlert(out, 4);

		v = new SomeClass [3] [];
		x = (SomeClass [] []) v;
		if (! (x instanceof SomeInterface [] []))
			errorAlert(out, 5);
		else if (! (x instanceof SomeClass [] []))
			errorAlert(out, 6);
		else if (x != v)
			errorAlert(out, 7);

		x[0] = (SomeClass []) new ImmediateSubclass [4];
		if (! (x[0] instanceof ImmediateSubclass []))
			errorAlert(out, 8);
		else if (x[0].length != 4)
			errorAlert(out, 9);

		x[1] = (SomeClass []) new FinalSubclass [4];
		if (! (x[1] instanceof FinalSubclass []))
			errorAlert(out, 10);
		else if (x[1].length != 4)
			errorAlert(out, 11);

		w = (AnotherInterface []) x[1];
		if (! (w instanceof FinalSubclass []))
			errorAlert(out, 12);
		else if (w != x[1])
			errorAlert(out, 13);
		else if (w.length != 4)
			errorAlert(out, 14);

		return errorStatus;
	}

}

Steps to reproduce it (only reproduces on Windows)
JDK Version on Windows:  1.6.0_12
OS: Windows XP Professional
CPU: Intel Pentium M


> javac conv08301.java
> java -server conv08301
> java -server -Xcomp conv08301

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/a9e116455022
                                     
2009-05-12
PUBLIC COMMENTS

Problem:
The code in CmpPNode::sub is broken for arrays of interface types.

Solution:
Check for an object array of interface type.
                                     
2009-05-12
EVALUATION

The code in CmpPNode::sub is broken for arrays of interface types.  You can make a test that fails in 1.7 by replacing this line:

               x[1] = (SomeClass []) new FinalSubclass [4];

with this:

               x[1] = (SomeClass []) v2;

where:

   static SomeClass[] v2 = new FinalSubclass[4];

Otherwise C2 is able to see precise types from the previous store and correctly statically fold the checks.  If you hide it in a static then we get into the CmpPNode::sub code.

The code in CmpPNode::sub either needs to restrict itself to TypeInstPtr or it needs to deal with the covariant subtyping of arrays properly.

*** (#1 of 1): [ UNSAVED ] ###@###.###
                                     
2009-05-06



Hardware and Software, Engineered to Work Together