SPARC ABI says:
http://docs.oracle.com/cd/E26502_01/html/E28387/gentextid-2734.html#scrolltoc
"Integer data types smaller then a slot are passed in the lower part of that slot. For 64-bit code, where a smaller integer type (int, short, char) parameter is passed in a register, the caller must sign extend or zero extend the value to the full 64-bit slot width. Similarly, in 64-bit code where a smaller integer type is returned in a register, the callee must sign extend or zero extend the value to the full 64-bit slot width. In 32-bit code, there is no requirement for sign or zero extensions, and only the lower bits of the values should be used."
Both GCC and SunStudio compilers do that. Unfortunately JITed (and other) code in Hotspot does not do that.
In 8049542 case compiled code reads integer field value -1 (0x00000000ffffffff) using LDUW instruction and then adds +2 which produces huge long value (0x0000000100000001). It is passed then the value in O1 register to runtime method (new_array_C). Without sign extension when expanding INT argument to LONG (as runtime code produced by GCC does) we get huge value (new array length) instead of 0x2.
What saved us before is SunStudio compilers do sign extension of INT arguments in callee method when expanding INT to LONG.
http://docs.oracle.com/cd/E26502_01/html/E28387/gentextid-2734.html#scrolltoc
"Integer data types smaller then a slot are passed in the lower part of that slot. For 64-bit code, where a smaller integer type (int, short, char) parameter is passed in a register, the caller must sign extend or zero extend the value to the full 64-bit slot width. Similarly, in 64-bit code where a smaller integer type is returned in a register, the callee must sign extend or zero extend the value to the full 64-bit slot width. In 32-bit code, there is no requirement for sign or zero extensions, and only the lower bits of the values should be used."
Both GCC and SunStudio compilers do that. Unfortunately JITed (and other) code in Hotspot does not do that.
In 8049542 case compiled code reads integer field value -1 (0x00000000ffffffff) using LDUW instruction and then adds +2 which produces huge long value (0x0000000100000001). It is passed then the value in O1 register to runtime method (new_array_C). Without sign extension when expanding INT argument to LONG (as runtime code produced by GCC does) we get huge value (new array length) instead of 0x2.
What saved us before is SunStudio compilers do sign extension of INT arguments in callee method when expanding INT to LONG.
- relates to
-
JDK-8024342 PPC64 (part 111): Support for C calling conventions that require 64-bit ints.
-
- Resolved
-
-
JDK-8086069 Adapt runtime calls to recent intrinsics to pass ints as long
-
- Resolved
-