RFR(XS): 8148353: [linux-sparc] Crash in libawt.so on Linux SPARC
roland.westrelin at oracle.com
Tue Feb 23 09:25:25 UTC 2016
Thanks for looking at this, Vladimir.
> Use macroassembler instruction signx() for sign extension. Otherwise it is good.
> Do you know where move32_64() is called from in this case? Compiled code should clean upper bits for int arguments.
If you look at the jtreg test case, c2 compiles the “compiled” method as:
000 B1: # B3 B2 <- BLOCK HEAD IS JUNK Freq: 1
000 ! stack bang (272 bytes)
014 SLL R_I0,#2,R_O0
018 CALL,static ; NOP ==> TestDirtyInt::test
# TestDirtyInt::compiled @ bci:3 L=_
020 B2: # N1 <- B1 Freq: 0.99998
# Block is sole successor of call
020 + MOV R_O0,R_I0 ! spill
024 + SETHI #PollAddr,L0 ! Load Polling address
LDX [L0],G0 !Poll for Safepointing
038 + ! return
038 B3: # N1 <- B1 Freq: 1e-05
038 ! exception oop is in R_O0; no code emitted
038 + MOV R_O0,R_I0 ! spill
03c + RESTORE
040 + Jmp rethrow_stub
so c2 doesn't clean the upper bits before the native call. move32_64 is then called by the compiled native wrapper on the int method argument.
> On 2/22/16 2:05 AM, Roland Westrelin wrote:
>> Native code is passed an int (in a 64 bit register) which has some bits set in the upper 32 bit half. The native code uses that value for an address computation. That results in a wrong memory access. From a few experiments with code generated by gcc, it seems it expects values to be clean on function entry. The fix cleans the 32 bit value before the native call.
More information about the hotspot-compiler-dev