We've recently encountered a problem with the c2 compiler in hotspot 1.7/1.6 when the method "public native long getAddress(long address)" of class "sun.misc.Unsafe" gets inlined as an intrinsic call on 32-bit platforms. The API documentation of "sun.misc.Unsafe.getAddress" states that "it fetches a native pointer from a given memory address" and that "if the native pointer is less than 64 bits wide, it is extended as an unsigned number to a Java long". Unfortunately, the intrinsic version of this method in hotspot 1.7/1.6 extends the native pointer as a signed number to a Java long, thus resulting in a discrepancy between interpreted execution and compiled execution. Let's consider the following example: import sun.misc.Unsafe; public class UnsafeGetAddressTest { public static void main(String[] args) { Unsafe unsafe = Unsafe.getUnsafe(); long address = unsafe.allocateMemory(unsafe.addressSize()); unsafe.putAddress(address, 0x0000000080000000L); // from sun.misc.Unsafe.getAddress' documentation: // "If the native pointer is less than 64 bits wide, it is // extended as an unsigned number to a Java long." result = unsafe.getAddress(address); System.out.printf("1: was 0x%x, expected 0x%x\n", result, 0x0000000080000000L); for (int i = 0; i < 1000000; i++) { result = unsafe.getAddress(address); } System.out.printf("2: was 0x%x, expected 0x%x\n", result, 0x0000000080000000L); } static volatile long result; } and one execution of the example in interpreted-mode: $ /tmp/jdk1.7.0/bin/java -Xint -showversion -Xbootclasspath/a:UnsafeGetAddressTest.jar -XX:+PrintCompilation UnsafeGetAddressTest java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b24) Java HotSpot(TM) Server VM (build 12.0-b01, interpreted mode) 1: was 0x80000000, expected 0x80000000 2: was 0x80000000, expected 0x80000000 and one execution in mixed-mode: $ /tmp/jdk1.7.0/bin/java -Xmixed -server -showversion -Xbootclasspath/a:UnsafeGetAddressTest.jar -XX:+PrintCompilation UnsafeGetAddressTest java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b24) Java HotSpot(TM) Server VM (build 12.0-b01, mixed mode) 1: was 0x80000000, expected 0x80000000 --- n sun.misc.Unsafe::getAddress 1% UnsafeGetAddressTest::main @ 65 (113 bytes) 2: was 0xffffffff80000000, expected 0x80000000 The mixed-mode execution shows that the native pointer 0x80000000 gets extended as a signed number to the Java long 0xffffffff80000000L after the method has been on-stack-replaced. The interpreted execution always returns 0x80000000L. The problem arises from the deletion of opto's CastP2LNode class and the new usage of CastP2XNode and ConvX2L in "hotspot/src/share/vm/opto/library_call.cpp" in method "LibraryCallKit::inline_unsafe_access" which is not equivalent to the old implementation.
|