United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6968348 Byteswapped memory access can point to wrong location after JIT
6968348 : Byteswapped memory access can point to wrong location after JIT

Details
Type:
Bug
Submit Date:
2010-07-12
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
linux
Sub-Component:
compiler
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6u21
Fixed Versions:
hs20

Related Reports
Backport:
Backport:
Relates:

Sub Tasks

Description
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));

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/52e82a6bedaf
                                     
2010-10-09
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/52e82a6bedaf
                                     
2010-10-05
EVALUATION

6968348: Byteswapped memory access can point to wrong location after JIT
Reviewed-by: twisti, kvn, iveresov

x86_64.ad has match rules for (Store (ReverseBytes val)) but the
definition is buggy since the val can be used in address of the store.
It also doesn't record that it changes the input value.  The fix is to
simply remove these rules since they are no better than what we'd get
otherwise.  x86_32.ad doesn't have these rules.  sparc.ad does but it
can generate better code for these forms because it can use the byte
swapped ASI and doesn't have to modify the register before storing it.
Tested with new test case.
                                     
2010-10-05



Hardware and Software, Engineered to Work Together