-
Bug
-
Resolution: Fixed
-
P4
-
11, 17, 18
-
b13
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
A part of relevant code is in java/hotspot/cpu/x86.
A DESCRIPTION OF THE PROBLEM :
Hi,
I'm not sure this is the appropriate place to report this bug. If not please let me know where to report.
The method CardTableBarrierSetC1::post_barrier generates a move LIR when TwoOperandLIRForm flag is true to move the address to be marked in the card table to a temporary register.
> __ move(addr, tmp);
This seems valid because the method computes the effective address so that `addr` must be a register operand beforehand. However, the this code only guarantees that `addr` is a valid register for LIR, which can be a virtual register. If the virtual register for `addr` is spilled to the stack by chance, the `move(addr, tmp)`
is compiled to a memory-to-register move, ie., `move [stack:xx|L], [rxxrxx|J]`. This causes an assertion failure because a memory-to-register move requires their arguments to have the same size.
The following replace may fix:
- __move(addr, tmp);
+ if (addr->is_oop()) {
+ LIR_Opr tmp2 = gen->new_register(T_OBJECT);
+ __ move(addr, tmp2);
+ __ move(tmp2, tmp);
+ } else
+ __ move(addr, tmp);
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
This assertion failure happened in reality when I extended the CardTableBarrierSetC1 and called a runtime function, clobbering registers, before calling post_barrier.
FREQUENCY : always
A part of relevant code is in java/hotspot/cpu/x86.
A DESCRIPTION OF THE PROBLEM :
Hi,
I'm not sure this is the appropriate place to report this bug. If not please let me know where to report.
The method CardTableBarrierSetC1::post_barrier generates a move LIR when TwoOperandLIRForm flag is true to move the address to be marked in the card table to a temporary register.
> __ move(addr, tmp);
This seems valid because the method computes the effective address so that `addr` must be a register operand beforehand. However, the this code only guarantees that `addr` is a valid register for LIR, which can be a virtual register. If the virtual register for `addr` is spilled to the stack by chance, the `move(addr, tmp)`
is compiled to a memory-to-register move, ie., `move [stack:xx|L], [rxxrxx|J]`. This causes an assertion failure because a memory-to-register move requires their arguments to have the same size.
The following replace may fix:
- __move(addr, tmp);
+ if (addr->is_oop()) {
+ LIR_Opr tmp2 = gen->new_register(T_OBJECT);
+ __ move(addr, tmp2);
+ __ move(tmp2, tmp);
+ } else
+ __ move(addr, tmp);
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
This assertion failure happened in reality when I extended the CardTableBarrierSetC1 and called a runtime function, clobbering registers, before calling post_barrier.
FREQUENCY : always