JDK-8165766 : TieredCompilation will change primitive autoboxing value on loop method call occasionally
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u101
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-09-09
  • Updated: 2016-09-15
  • Resolved: 2016-09-15
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment 1.8.0_101-b13 Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.101-b13

FULL OS VERSION :
OS: Windows 10 10.0 amd64
Java(TM) SE Runtime Environment 1.8.0_101-b13 Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.101-b13

A DESCRIPTION OF THE PROBLEM :
Once TieredCompilation is ongoing, it will change primitive autoboxing value on method call  occasionally and it causes the application computation error on Windows x64.



THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

REGRESSION.  Last worked in version 8u101

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
					if (tktLeft > 0D) { // CALL OBJECT SETTER WHEN GREATER THAN
						assert (tktLeft > 0) : "(tktLeft >0) ? " + tktLeft;
						double w = tktLeft;
						double p = tktLeft;
						askrec.setW(w);
						askrec.setP(p);
						askrec.setD(System.currentTimeMillis());
					}


EXPECTED VERSUS ACTUAL BEHAVIOR :
p <=0 
Exception in thread "main" java.lang.AssertionError: p : 0.0 > 0 (?) 
	at my.own.AskRecord.setP(AskRecord.java:81)
	at my.trade.TM1.case8(TM1.java:102)
	at my.trade.TM1.mainTest(TM1.java:127)
	at my.trade.TM1.main(TM1.java:144)
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.AssertionError: p : 0.0 > 0 (?) 

REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
package my.own;


public class AskRecord { //implements java.io.Serializable {

//private static final long serialVersionUID = 2429769253245743208L;

	private Long b;
	private Double w;
	private Double p;
	private Double amt;
	private Double lw;
	private Double lp;
	private Long dateA;

	/*
	private Integer r;
	private Integer h;
	public Long lvl;
	private Integer lv;

	private String u;
	private String cr;
	private String rt;
	private String rd;
	private String rto;
	private String rrt;
	private Double sw;
	private Double sp;
	private Integer pt;
	private String ort;
	private Integer lct;
	private String ip;
	private String pts;
	private String ptx;

	private Double tm_5;
	private Double tm_10;
	private Double tm_15;
	private Double tm_20;
	private Double tm_25;
	private Double tm_30;
	private Double tm_60;
	private Double tm_9999;
	*/

	public AskRecord(Long bid, int a, int b, double c, double d, double e, double f,
		double g, String h, String i, String j, String k, double l,
		double m, Long n, int o) {
		super();
		this.b = bid;
		this.w = c;
		this.p = d;

		this.amt = e;
		this.lw = f;
		this.lp = g;
		
	}

	public Long getB() {
		return b;
	}

	public double getW() {
		return w;
	}

	public void setW(Double w) {
		this.w = w;
	}

	public double getP() {
		return p;
	}

	public void setP(Double p) {
		if (p <= 0){
			System.out.println("p <=0 ");
		}
		assert p > 0 : "p : " + p + " > 0 (?) ";
		this.p = p;
	}

	public double getA() {
		return amt;
	}

	public double getLW() {
		return lw;
	}

	public double getLP() {
		return lp;
	}

	public Long getD() {
		return dateA;
	}

	public void setD(Long dateA) {
		this.dateA = dateA;
	}

	public String toString() {
		return String.format("AskRecord [b=%s, w=%s, p=%s, amt=%s, lw=%s, lp=%s, dateA=%s]", b, w, p, amt,
			lw, lp, dateA);
	}

}
package my.own;


public class BidRecord {

	public BidRecord() {
		// TODO Auto-generated constructor stub
	}

}

package my.trade;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;

import my.own.BidRecord;


public class BEngine {

	private static Logger logger = Logger.getLogger(BEngine.class.toString());
	
	
	private BEngine() {
		init();
	}
	
	public static BEngine getInstance() {
		return new BEngine();
	}


	public Map<Long, BidRecord> getCache() {
		return null;
	}

	public void init()  {
	
	}

	
	public List<Entry<Long, BidRecord>> matchObjectQuery( double a, double b, double c,
		int d) {

		return new ArrayList<Entry<Long, BidRecord>>();

	}




	public double trade(double a, double b, double c, final double d) {
	
		long t0 = System.nanoTime();
	
		List<Entry<Long, BidRecord>> rl = matchObjectQuery(a, b, c, (int) d);
	
		long t1 = System.nanoTime();
	
		double ta = d;

		if (rl.size() > 0) {
	
		}
	
		return ta;
	
	}
}
package my.trade;

import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;

import my.own.AskRecord;

/*
 * 
 * */
 

public class TM1 {

	final public static int BID_COUNT = 10_000_000;	
	public static Logger logger = Logger.getLogger(TM1.class.toString());

	private AtomicLong bqn = new AtomicLong();
	
	private BEngine bideng  = BEngine.getInstance();
	
	final public static double[] AMOUNT_SEGMENT= 
	{
		3.8, 3.81, 3.82, 3.83, 3.84,3.85, 3.86, 3.87, 3.88, 3.89,
		3.9, 3.95, 
		4.0, 4.05, 4.1, 4.15, 4.2, 4.25, 4.3, 4.35, 4.4, 4.45,
		4.5, 4.55, 4.6, 4.65, 4.7, 4.75, 4.8, 4.85, 4.9, 4.95, 
		5.0, 5.05, 5.1
	};

	final public static int AMOUNT_SEG_SIZE = AMOUNT_SEGMENT.length;
	

	public  AskRecord genAR(int a, int b, double c, double d,
		double f, double g, double h, String i, String j, String k,
		String l, double m, double n, long o, int p) {

		return new AskRecord(bqn.getAndIncrement(), a, b, c, d, f, g, h, i, j,
			k, l, m, n, o, p);
	}
	
	
	private void case8() {
		final int len = BID_COUNT;
		long min = Long.MAX_VALUE;
		long max = Long.MIN_VALUE;
		Random random = new Random();

		long tm0 = 0;
		long tm1 = 0;



		AskRecord[] aArr = new AskRecord[len];
		int aIx = 0;

		for (long i = 0; i < BID_COUNT; i++) {
			// LOOP FOR 1000_000 TIMES

			int rc = 1;
			int hr = 1;
			double w, p;
			w = 1 + random.nextInt(5);
			p = w;
			double am = AMOUNT_SEGMENT[random.nextInt(AMOUNT_SEG_SIZE)];
			double lw = 10 + random.nextInt(30) * 10;
			double lp = Math.max(5, random.nextInt(10) * 10);
			lp = Math.min(lw, lp);
			String ua = "abcd" + String.valueOf(i % 100);
			String cr = "GSP";
			String rt = "HH";
			String rd = "2016-09-09";
			double sw = 0;
			double sp = 0;
			long da = System.currentTimeMillis();

			aArr[aIx++] = genAR(rc, hr, w, p, am, lw,
				lp, ua, cr, rt, rd, sw, sp, da, 0);
		}

		int aIx1 = 0;

		for (long i = 0; i < BID_COUNT; i++) {
			try  {
					AskRecord askrec = aArr[aIx1++];
					// TODO
					double w0 = askrec.getW();
					double a0 = askrec.getA();
					double p0 = askrec.getP();
					double lw = askrec.getLW();
					double lp = askrec.getLP();

					tm0 = System.nanoTime();
					final double tktLeft = bideng.trade(a0, lw, lp, w0);
					if (tktLeft > 0D) { // CALL OBJECT SETTER WHEN GREATER THAN
						assert (tktLeft > 0) : "(tktLeft >0) ? " + tktLeft;
						double w = tktLeft;
						double p = tktLeft;
						askrec.setW(w);
						askrec.setP(p);
						askrec.setD(System.currentTimeMillis());
					}
					tm1 = System.nanoTime() - tm0;

			}
			finally {

			}

			if (tm1 != 0) {
				min = Math.min(tm1, min);
				max = Math.max(tm1, max);
			}

		}
		String minfo = String.format("Max: %,d ; Min: %,d", max, min);
		print(minfo);

	}

	public void mainTest() {

		try{
			long t0 = System.nanoTime();
			case8();
			long t1 = System.nanoTime() - t0;
			print("end: taken : " + t1 / BID_COUNT + " ms.");
		} catch (Exception e) {
			e.printStackTrace();
			logger.log(Level.WARNING, e.toString(), e);
		}

	}

	private static void print(String msg) {
		logger.info(msg);
		System.out.println(msg);
	}
	
	public static void main(String[] args) {
		TM1 tm = new TM1();
		tm.mainTest();
	}


}

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

CUSTOMER SUBMITTED WORKAROUND :
-XX:-TieredCompilation


Comments
Verified on 9 ea b-135 this issue is not reproducible.
15-09-2016

This looks like JDK-8148175 - will be fixed in 8u122.
15-09-2016

Issue is reproducible on 8u92 and 8u101, below is the result ==8u92=== C:\Users\fmatte.ORADEV\Downloads>"d:\Program Files\Java\jdk1.8.0_92\bin\java.exe" -cp java99.jar -ea -XX:+TieredCompilation -server -XX:+UseG1GC -verbose:gc -XX:+PrintGCDateStamps -Xms1g -Xmx1g -Xss228k my.trade.TM 2016-09-15T12:12:05.358+0530: [GC pause (G1 Evacuation Pause) (young) 54M->27M(1024M), 0.0468760 secs] 2016-09-15T12:12:05.452+0530: [GC pause (G1 Evacuation Pause) (young) 71M->49M(1024M), 0.0399276 secs] 2016-09-15T12:12:05.530+0530: [GC pause (G1 Evacuation Pause) (young) 93M->73M(1024M), 0.0421142 secs] 2016-09-15T12:12:05.608+0530: [GC pause (G1 Evacuation Pause) (young) 117M->96M(1024M), 0.0417081 secs] 2016-09-15T12:12:05.686+0530: [GC pause (G1 Evacuation Pause) (young) 140M->120M(1024M), 0.0515396 secs] 2016-09-15T12:12:05.764+0530: [GC pause (G1 Evacuation Pause) (young) 167M->146M(1024M), 0.0553514 secs] p <=0 Exception in thread "main" java.lang.AssertionError: p : 0.0 > 0 (?) at my.own.AskRecord.setP(AskRecord.java:81) at my.trade.TM1.case8(TM1.java:102) at my.trade.TM1.mainTest(TM1.java:128) at my.trade.TM1.main(TM1.java:145) ==8u101== C:\Users\fmatte.ORADEV\Downloads>"c:\Program Files\Java\jre1.8.0_101\bin\java.exe" -cp java99.jar -ea -XX:+TieredCompilation -server -XX:+UseG1GC -verbose:gc -XX:+PrintGCDateStamps -Xms1g -Xmx1g -Xss228k my.trade.TM1 2016-09-15T12:13:44.740+0530: [GC pause (G1 Evacuation Pause) (young) 54M->27M(1024M), 0.0422288 secs] 2016-09-15T12:13:44.818+0530: [GC pause (G1 Evacuation Pause) (young) 71M->50M(1024M), 0.0386281 secs] 2016-09-15T12:13:44.881+0530: [GC pause (G1 Evacuation Pause) (young) 94M->74M(1024M), 0.0445216 secs] 2016-09-15T12:13:44.959+0530: [GC pause (G1 Evacuation Pause) (young) 118M->97M(1024M), 0.0419722 secs] 2016-09-15T12:13:45.021+0530: [GC pause (G1 Evacuation Pause) (young) 141M->121M(1024M), 0.0469228 secs] 2016-09-15T12:13:45.099+0530: [GC pause (G1 Evacuation Pause) (young) 169M->146M(1024M), 0.0451637 secs] p <=0 Exception in thread "main" java.lang.AssertionError: p : 0.0 > 0 (?) at my.own.AskRecord.setP(AskRecord.java:81) at my.trade.TM1.case8(TM1.java:102) at my.trade.TM1.mainTest(TM1.java:128) at my.trade.TM1.main(TM1.java:145)
15-09-2016

Received response from submitter, == Please use -XX:+G1GC -Xms1g -Xmx2g also. or copy this jar && follow the description https://github.com/WENPIN1/BreakJava8TierComp/blob/master/java99.jar ==
15-09-2016

Requested submitter to verify the steps. == I am unable to reproduce the issue, please could you correct the steps below 1. javac.exe my\own\AskRecord.java 2. javac my\own\BidRecord.java 3. javac my\trade\BEngine.java 4. javac my\trade\TM1.java 5. java -ea -XX:+TieredCompilation my.trade.TM1 I always get the proper result == Sep 09, 2016 4:48:37 PM my.trade.TM1 print INFO: Max: 658,738,365 ; Min: 446 Max: 658,738,365 ; Min: 446 Sep 09, 2016 4:48:37 PM my.trade.TM1 print INFO: end: taken : 4655 ms. end: taken : 4655 ms. Do let me know, in case I am missing something. ==
09-09-2016

I am unable to reproduce this issue, given the instructions == javac.exe my\own\AskRecord.java javac my\own\BidRecord.java javac my\trade\BEngine.java javac my\trade\TM1.java java -ea -XX:+TieredCompilation my.trade.TM1 Below is the result == Sep 09, 2016 4:48:37 PM my.trade.TM1 print INFO: Max: 658,738,365 ; Min: 446 Max: 658,738,365 ; Min: 446 Sep 09, 2016 4:48:37 PM my.trade.TM1 print INFO: end: taken : 4655 ms. end: taken : 4655 ms.
09-09-2016