JDK-5081108 : reflective access to final longs loses uppper 32 bits on some x86 machines
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 6
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_10
  • CPU: x86
  • Submitted: 2004-07-31
  • Updated: 2012-10-08
  • Resolved: 2004-08-03
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 JDK 6
5.0Fixed 6 mustangFixed
Related Reports
Relates :  
Relates :  
Description
This program:

public class Trunc2 {
    private static final long x = 1421746759512286392L;
    public static void main(String[] args) throws Exception {
	long x2 = Trunc2.class.getDeclaredField("x").getLong(null);
	if (x2 != x)
	    throw new Exception(""+x2);
    }
}

should print nothing, and indeed this is what happens on most platforms.
But on some VIA EPIA x86 Solaris machines, this happens:

Exception in thread "main" java.lang.Exception: 558556344
        at Trunc2.main(Trunc2.java:6)

This started happening with Tiger b51 and persists as of b60.

The suspicious bug fixes that may have been introduced are
5037108: Low-byte of Long Truncated Incorrectly by Bitwise AND
5044412: (reflect) if setAccessible(true) has succeeded, allow final fields to be set

If the "final" is removed, no exception is thrown.

This bug is responsible for the failure of Solaris 10 to install on
these machines, documented in
5060088: cd 2of3 won't install on some VIA EPIA systems

One machine where this bug can be reproduced is "small.sfbay".

###@###.### 2004-07-30

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang tiger-rc FIXED IN: mustang tiger-rc INTEGRATED IN: mustang tiger-b62 tiger-rc
08-09-2004

EVALUATION Doug Lea appears to have found the fix, an easy-to-make long/jlong confusion. Someone who understands the VM and the x86 architecture should confirm that the machine "small" is indeed special in that it indeed does not support cx8. ###@###.### 2004-07-31 The bug was put in 2/2004 with this fix: 4986284 Unsafe_CompareAndSwapLong requires an 8-byte hardware CAS instruction According to the putback comments, the non-cx8 case is intended to support SPARC V8 and 80486 chips. Apparently we never test on 486 and V8. Ouch. (I have updated 5081191 with a suggested fix to fence around the the long/jlong pitfall.) ###@###.### 2004-07-31 small.sfbay reports, via the cpuid instruction, that it doesn't support cmpxchg8. Running a debug vm with -XX:+PrintMiscellaneous and -XX:+Verbose produces VM option '+Verbose' VM option '+PrintMiscellaneous' [SafePoint Polling address: 0xc6650000] CPU: family 6, cmov, fxsr, mmx, sse Logical CPUs per package: 1 SSE only (no SSE2) I confirmed that the suggested fix works. ###@###.### 2004-08-02
02-08-2004

SUGGESTED FIX Doug Lea writes: ------------------------------------------------------------------------- I suspect that the error is in hotspot share/vm/prims/unsafe.cpp line 201 in Unsafe_GetLongVolatile, where a "long" should be a "jlong". UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) UnsafeWrapper("Unsafe_GetLongVolatile"); { if (VM_Version::supports_cx8()) { GET_FIELD_VOLATILE(obj, offset, jlong, v); return v; } else { oop p = JNIHandles::resolve(obj); jlong* addr = (jlong*)(index_oop_from_field_offset_long(p, offset)); ObjectLocker ol(p, THREAD); --- long value = *addr; +++ jlong value = *addr; return value; } } UNSAFE_END ------------------------------------------------------------------------- I have tested this fix and it appears to work. ###@###.### 2004-07-31
31-07-2004