United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6659207 access violation in CompilerThread0
JDK-6659207 : access violation in CompilerThread0

Details
Type:
Bug
Submit Date:
2008-02-05
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
hotspot
OS:
windows_vista,generic,solaris_10,windows_xp
Sub-Component:
compiler
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs10,6,6u5,6u7-rev
Fixed Versions:
hs12 (b02)

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

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) 64-Bit Server VM (build 10.0-b19, mixed mode)

FULL OS VERSION :
Microsoft Windows [Version 6.0.6000]
(Vista Business 64)

A DESCRIPTION OF THE PROBLEM :
  Program consistently fails in 64-bit jvm (client & server) but works in 32-bit jvm. Get access violation in hotspot compiler thread (but reported as "outside the jvm in native code" - I think incorrectly).

Note that the error report below indicates an error occurred getting the native stack. During one run I attached visual studio and captured the native stack when the access violation occurred, pasted below:
>	jvm.dll!0000000008093cbb()
 	[Frames below may be incorrect and/or missing, no symbols loaded for jvm.dll]
 	jvm.dll!00000000080963c7()
 	jvm.dll!00000000080d8aa1()
 	jvm.dll!00000000080d95e5()
 	jvm.dll!0000000008086d7d()
 	jvm.dll!00000000080dc132()
 	jvm.dll!00000000080dcf8a()
 	jvm.dll!00000000083db2df()
 	jvm.dll!000000000831be59()
 	msvcrt.dll!000007feff5e94e7()
 	msvcrt.dll!000007feff5e967d()
 	kernel32.dll!000000007780cdcd()
 	ntdll.dll!0000000077a2c6e1()

Crash Log is attached seperatly


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 sample code using a 64-bit JVM (may be vista specific? haven't tried on other platforms)

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expect program to exit normally after the loop. Actual behavior is access violation on the last iteration of the loop.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
<snip>
Running test  9998 -> 1220321112
Running test  9999 -> 1468100534
#
# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION[thread 4404 also had an error] (0xc0000005)
 at pc=0x0000000008093cbb, pid=2304, tid=4504
#
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0-b19 mixed mode windows-amd64)
# Problematic frame:
# V  [jvm.dll+0x93cbb]
#
# An error report file with more information is saved as:
# D:\PRWorkspace\PR05-DevTip\AccessViolationTest\hs_err_pid2304.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.ArrayList;
import java.util.Arrays;

public class AV64bit {

	private static AV64bit oFactoryInstance = new AV64bit();
	public static StringBuffer acquire(int requested) {
		return (StringBuffer) oFactoryInstance.acquireObject(requested);
	}

	private final int[] mPoolCapacities = { 32 + 1, 64 + 1, 128 + 1, 256 + 1, 1024 + 1, 2 * 1024 + 1, 4 * 1024 + 1, 6 * 1024 + 1, 10 * 1024 + 1, 32 * 1024 + 1, 60 * 1024 + 1, 100 * 1024 + 1 };
	private final int[] mPerCapacityPoolSize = { 10, 10, 50, 100, 100, 100, 10, 100, 100, 50, 10, 10 };

	@SuppressWarnings("unchecked")
	private ArrayList[] mPoolLists = new ArrayList[mPoolCapacities.length];
	private long[] mCreateCount = new long[mPoolCapacities.length];
	private long[] mReuseCount = new long[mPoolCapacities.length];
	private long[] mTAL = new long[mPoolCapacities.length];
	private int iOverAlloc;
	private AV64bit() {
		Arrays.fill(mTAL, System.currentTimeMillis());
	}
	@SuppressWarnings("unchecked")
	private Object acquireObject(int requested) {
		int which = getWhich(requested);

		int capacity;
		if (which > -1) {
			capacity = mPoolCapacities[which];

			ArrayList list = null;
			synchronized (mPoolLists) {
				if (mPoolLists[which] == null) {
					mPoolLists[which] = new ArrayList(mPerCapacityPoolSize[which]);
				}
				list = mPoolLists[which];
			}

			// remove a Product from the allocations list,
			synchronized (list) {
				int size = list.size();
				if (size > 0) {
					mReuseCount[which]++;
					return list.remove(--size);
				}
			}
		} else {
			capacity = requested;
		}

		// count allocations as we go for reporting
		if (which == -1)
			iOverAlloc++;
		else
			mCreateCount[which]++;

		return newProduct(capacity);
	}
	private int getWhich(int capacity) {
		if (capacity == 0)
			return 0; // return FIRST bucket (zero-based)

		for (int i = 0; i < mPoolCapacities.length; i++)
			if (capacity <= mPoolCapacities[i])
				return i;

		return -1;
	}
	private Object newProduct(int capacity) {
		return new StringBuffer(capacity);
	}

	public static void main(String[] args) {
		for (int i = 0; i < 10000; i++) {
			StringBuffer buffer = AV64bit.acquire(1024);
			System.out.printf("Running test %5d -> %d\n", i, buffer.hashCode());
		}
	}

}

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

CUSTOMER SUBMITTED WORKAROUND :
None found.

                                    

Comments
EVALUATION

After raising the number of iterations to 20000, I can reproduce this crash on sparc 64 bit going all the way back to 1.6.0.

V  [libjvm.so+0x341264];;  __1cMPhaseChaitinQgather_lrg_masks6Mb_v_+0x2a8
V  [libjvm.so+0x1d67d0];;  __1cMPhaseChaitinRRegister_Allocate6M_v_+0x408
V  [libjvm.so+0x1cb754];;  __1cHCompileICode_Gen6M_v_+0x32c
V  [libjvm.so+0x38b88c];;  __1cHCompile2t6MpnFciEnv_pnKC2Compiler_pnIciMethod_ib_v_+0xb24
V  [libjvm.so+0x1ef388];;  __1cKC2CompilerOcompile_method6MpnFciEnv_pnIciMethod_i_v_+0x80
V  [libjvm.so+0x1efbe4];;  __1cNCompileBrokerZinvoke_compiler_on_method6FpnLCompileTask__v_+0x79c
V  [libjvm.so+0x270860];;  __1cNCompileBrokerUcompiler_thread_loop6F_v_+0x5c0
V  [libjvm.so+0x6f5bcc];;  __1cKJavaThreadRthread_main_inner6M_v_+0x4c
V  [libjvm.so+0x6366c4];;  java_start+0x184

In debug mode is asserts in PhaseChaitin::union when it can't find the entry for the source node.  Narrowing it down using the prt archives it appeared with the fix for 6260293 though I don't think that's really the cause.  I think it just unmasks the issue.  The underlying issue appears to be a ConvI2L with a constrained type is pushed through a phi so that it ends up with a -1 input which causes it to be replaced with top.  Clearly using a constrained type in this way is unsafe since it's not connected to any dependence which keeps it from being moved above the control that proves it.  More properly it should probably be an unconstrained ConvI2L with a CastL2L that asserts the restricted range as a result of the control edge but we don't have a CastL2L.  I think the fix for 6260293 allows this optimization to occur in situations where it previously wouldn't since the constrained ConvI2L dates back at least to 1.5.
                                     
2008-02-05
SUGGESTED FIX

repo:       /net/jano2.sfbay/export2/hotspot/hg/hotspot-comp.clean
changeset:  52:8bb88f9877e5
user:       never
date:       Tue Mar 18 23:54:17 2008 -0700
description:
6659207: access violation in CompilerThread0
Summary: split_thru_phi produces top on a non-dead path
Reviewed-by: kvn, rasbold, sgoldman

files:
src/share/vm/opto/loopopts.cpp test/compiler/6659207/Test.java

--- old/src/share/vm/opto/loopopts.cpp	Tue Mar 18 10:41:07 2008
+++ new/src/share/vm/opto/loopopts.cpp	Tue Mar 18 10:41:06 2008
@@ -29,6 +29,11 @@
 //------------------------------split_thru_phi---------------------------------
 // Split Node 'n' through merge point if there is enough win.
 Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
+  if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) {
+    // ConvI2L may have type information on it which is unsafe to push up
+    // so disable this for now
+    return NULL;
+  }
   int wins = 0;
   assert( !n->is_CFG(), "" );
   assert( region->is_Region(), "" );
                                     
2008-03-06



Hardware and Software, Engineered to Work Together