FULL PRODUCT VERSION :
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
java version "1.6.0_21-ea-fastdebug"
Java(TM) SE Runtime Environment (build 1.6.0_21-ea-fastdebug-b05)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b15-fastdebug, mixed mode)
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b76)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b05, mixed mode)
FULL OS VERSION :
Linux hfdv1.aoa.twosigma.com 2.6.30.4-ts10 #4 SMP PREEMPT Thu Jan 14 20:16:13 GMT 2010 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
In a loop using sun.misc.Unsafe to write directly to memory:
for (int i = 0; i < BUF_SIZE; i += 8)
unsafe.putLong(addr + i, Long.reverseBytes(i));
JIT generates this byte code for the inner loop:
03b movq R11, 0x00002b814042b000 # ptr
045 movl RCX, RBX # spill
047 movslq R8, RCX # i2l
04a movq_bswap [R11 + R8], R8
Which translates to these instructions:
0x2b6606210741: mov $0x2b814042b000,%r11
0x2b660621074b: mov %ebx,%ecx
0x2b660621074d: movslq %ecx,%r8
0x2b6606210750: bswap %r8
0x2b6606210753: mov %r8,(%r11,%r8,1)
The movq_bswap swaps R8 and then uses the swapped version for the offset, causing the JVM to segfault.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: memory would be written
Actual: segfault
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
Changing the loop index to a long fixes the problem:
for (long i = 0; i < BUF_SIZE; i += 8)
unsafe.putLong(addr + i, Long.reverseBytes(i));