# HG changeset patch # User smonteith # Date 1561456259 -3600 # Node ID b7f68ddec66f996ae3aad03291d129ca9f02482d # Parent 688f985f29c3b1c0cd794fbda6c4f9ff9df423a2 8226515: AArch64: float point register corruption in ZBarrierSetAssembler::load_at Reviewed-by: aph diff -r 688f985f29c3 -r b7f68ddec66f src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp Wed Jun 26 01:15:51 2019 +0000 +++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp Tue Jun 25 10:50:59 2019 +0100 @@ -63,27 +63,25 @@ return; } - // rscratch1 can be passed as src or dst, so don't use it. - RegSet savedRegs = RegSet::of(rscratch2, rheapbase); + assert_different_registers(rscratch1, rscratch2, src.base()); + assert_different_registers(rscratch1, rscratch2, dst); + + RegSet savedRegs = RegSet::range(r0,r28) - RegSet::of(dst, rscratch1, rscratch2); Label done; - assert_different_registers(rheapbase, rscratch2, dst); - assert_different_registers(rheapbase, rscratch2, src.base()); - - __ push(savedRegs, sp); // Load bad mask into scratch register. - __ ldr(rheapbase, address_bad_mask_from_thread(rthread)); + __ ldr(rscratch1, address_bad_mask_from_thread(rthread)); __ lea(rscratch2, src); __ ldr(dst, src); // Test reference against bad mask. If mask bad, then we need to fix it up. - __ tst(dst, rheapbase); + __ tst(dst, rscratch1); __ br(Assembler::EQ, done); __ enter(); - __ push(RegSet::range(r0,r28) - RegSet::of(dst), sp); + __ push(savedRegs, sp); if (c_rarg0 != dst) { __ mov(c_rarg0, dst); @@ -91,13 +89,15 @@ __ mov(c_rarg1, rscratch2); int step = 4 * wordSize; - __ mov(rscratch1, -step); + __ mov(rscratch2, -step); __ sub(sp, sp, step); for (int i = 28; i >= 4; i -= 4) { __ st1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2), - as_FloatRegister(i+3), __ T1D, Address(__ post(sp, rscratch1))); + as_FloatRegister(i+3), __ T1D, Address(__ post(sp, rscratch2))); } + __ st1(as_FloatRegister(0), as_FloatRegister(1), as_FloatRegister(2), + as_FloatRegister(3), __ T1D, Address(sp)); __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2); @@ -111,13 +111,10 @@ __ mov(dst, r0); } - __ pop(RegSet::range(r0,r28) - RegSet::of(dst), sp); + __ pop(savedRegs, sp); __ leave(); __ bind(done); - - // Restore tmps - __ pop(savedRegs, sp); } #ifdef ASSERT diff -r 688f985f29c3 -r b7f68ddec66f src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp Wed Jun 26 01:15:51 2019 +0000 +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp Tue Jun 25 10:50:59 2019 +0100 @@ -886,8 +886,8 @@ } // Get mirror and store it in the frame as GC root for this Method* - __ load_mirror(rscratch1, rmethod); - __ stp(rscratch1, zr, Address(sp, 4 * wordSize)); + __ load_mirror(r10, rmethod); + __ stp(r10, zr, Address(sp, 4 * wordSize)); __ ldr(rcpool, Address(rmethod, Method::const_offset())); __ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));