JDK-5037108 : Low-byte of Long Truncated Incorrectly by Bitwise AND
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 1.4.2,5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,solaris_9
  • CPU: x86,sparc
  • Submitted: 2004-04-23
  • Updated: 2004-05-11
  • Resolved: 2004-05-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b51Fixed
Related Reports
Relates :  
Relates :  
Description

Name: tb29552			Date: 04/23/2004


FULL PRODUCT VERSION :
J2SE 1.4.2_04, 1.4.2_01, or 1.5Beta1

FULL OS VERSION :
RedHat 9 2.4.20
RedHat 7.3 2.4.18

A DESCRIPTION OF THE PROBLEM :
After running with -server flag for about a minute the following code emits a value that has a low-byte of 0x00 regardless of the input:

     offset & 0xFFFFFFFFL

The specific context is found in the jCIFS SMB/CIFS client library available at http://jcifs.samba.org/ version 0.8.2 or below jcifs/smb/SmbComWriteAndX.java line ~87.

    writeInt4( offset & 0xFFFFFFFFL, dst, dstIndex );

where offset is a long and writeInt4 is:

    static void writeInt4( long val, byte[] dst, int dstIndex ) {
        dst[dstIndex++] = (byte)((int)(val >>> 0) & 0xFF);
        dst[dstIndex++] = (byte)((int)(val >>> 8) & 0xFF);
        dst[dstIndex++] = (byte)((int)(val >>> 16) & 0xFF);
        dst[dstIndex++] = (byte)((int)(val >>> 24) & 0xFF);
    }

Running without -server or removing the unnecessary mask solves the problem.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Download:

http://jcifs.samba.org/src/jcifs-0.8.21x.jar
http://home.comcast.net/~miallen1/jcifs/testjcifs.jar

And run like:

java -server -cp testjcifs.jar:jcifs-0.8.2x1.jar testjcifs.FullTest smb://server/share/ dom\;user:pass 500

where server is a SMB/CIFS server. After approxamately 45 seconds the output will transition as follows:

Thread-0 creating Z1082335691040.tmp
Thread-0 creating Z1082335691150.tmp
Thread-42 reading X1082335675290.tmp
Thread-0 creating Z1082335691440.tmp
clobbered: 0x5800
clobbered: 0x5800
clobbered: 0x5800
clobbered: 0x5800

This means that the offset field encoded into the SMB_COM_WRITE_ANDX request with an FID of 0x5800 had the low byte "clobbered" to 0x00.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The expression longValue & 0xFFFFFFFFL should not emit a value with a low byte of 0x00 if the input longValue does not have a 0x00 low byte.
ACTUAL -
The expression longValue & 0xFFFFFFFFL emits a value with the low 8 byte set to 0 regardless of whether or not the longValue has a non-0x00 low byte.

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
Do not use the HotSpot -server option or do not mask a long value with 0xFFFFFFFFL in this way.
(Incident Review ID: 254855) 
======================================================================
###@###.### 2004-04-23

For a smaller test case, refer to WI.java, attached to this bug report.

Comments
SUGGESTED FIX The webrev for this fix is: http://analemma.sfbay.sun.com/net/prt-archiver.sfbay/export2/archived_workspaces/main/c2_baseline/2004/20040504140755.steved.c2-new_ws/workspace/webrevs/webrev-2004.05.04/index.html ###@###.### 2005-2-05 05:46:49 GMT
05-02-2005

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b51 tiger-beta2
14-06-2004

EVALUATION The problem is a bug in the optimization of an unsigned right shift of a Java long value when the shift count is known at compile time to be 0. It occurs when the operandof the shift is an add operation which in this case comes from theinlining of java.util.Random.nextLong(). The compiler internally wasdoing a left shift of a 64-bit value by 64 bits, the result of which is undefined in C++. On 64-bit SPARC and Linux x86, the C++ result caused the generated Java code to always produce a result of 0. On 32-bit SPARC and Solaris x86 the C++ result allowed the generated code to produce the correct result in this particular test case but would be incorrect in other cases. In analyzing this bug, I determined that there were other cases where optimization of shifts could produce incorrect results when the shift count is 0 or >= the operand size. The fix was to take the shift count modulus the operand size before checking for optimizations and not trying to do any optimizations except eliminating the shift when the shift count is 0.
11-06-2004

PUBLIC COMMENTS .
10-06-2004