RFR: Fix ExtendedDTraceProbes with Shenandoah
Roland Westrelin
rwestrel at redhat.com
Thu Sep 20 20:35:08 UTC 2018
Hi Zhengyu,
> we are not sure about it is right fix (offline chat discussion). This
> patch might just kill the symptom that described in attached "before fix
> LIR", since G1 generates similar LIR, but happens to use different
> register for loading 0x10 @146, so it does not destroy base.
>
> Unfortunately, it is not the case for Shenandoah, load @146 destroys the
> base ... could it be register allocator's bug?
I don't think the fix is the right one. Here is HIR+LIR of a section of
the method where the crash occurs:
. 3 1 a99 UnsafeGetObject.(a71, l94)
move [R584|L] [R594|L]
cmp [EQ] [R594|L] [obj:0x0000000000000000|L]
branch [EQ] [label:0x00007fe0e81b86a8]
move [Base:[R594|L] Disp: -8|^@] [R594|L]
label [label:0x00007fe0e81b86a8]
move [Base:[R594|L] Index:[R591|J] Disp: 0|L] [R593|L]
membar_acquire
move [lng:12|J] [R595|J]
cmp [NE] [R591|J] [R595|J]
branch [NE] [label:0x00007fe0e81b8a48]
cmp [EQ] [R584|L] [obj:0x0000000000000000|L]
branch [EQ] [label:0x00007fe0e81b8a48]
move [Base:[R584|L] Disp: 8|^@] [R596|M]
move [Base:[R596|M] Disp: 395|B] [R597|I]
cmp [EQ] [R597|I] [int:0|I]
branch [EQ] [label:0x00007fe0e81b8a48]
move [Base:[r15r15|J] Disp: 56|Z] [R598|I]
cmp [NE] [R598|I] [int:0|I]
branch [NE] [ShenandoahPreBarrierStub: 0x00007fe0e81b92c0]
label [label:0x00007fe0e81b9360]
label [label:0x00007fe0e81b8a48]
And now LIR+Assembly:
152 move [stack:16|L] [rdi|L]
0x00007fe114aac427: mov 0xc0(%rsp),%rdi
154 cmp [EQ] [rdi|L] [obj:0x0000000000000000|L]
0x00007fe114aac42f: cmp $0x0,%rdi
156 branch [EQ] [label:0x00007fe0e81b86a8]
0x00007fe114aac433: je 0x00007fe114aac439
158 move [Base:[rdi|L] Disp: -8|^@] [rdi|L]
0x00007fe114aac439: mov -0x8(%rdi),%rdi
160 label [label:0x00007fe0e81b86a8]
move [dbl_stack:18|J] [rbxrbx|J]
0x00007fe114aac43d: mov 0xc8(%rsp),%rbx
162 move [Base:[rdi|L] Index:[rbxrbx|J] Disp: 0|L] [rax|L]
0x00007fe114aac445: mov (%rdi,%rbx,1),%eax
164 membar_acquire
166 move [lng:12|J] [rdirdi|J]
0x00007fe114aac448: movabs $0xc,%rdi
168 cmp [NE] [rbxrbx|J] [rdirdi|J]
0x00007fe114aac452: cmp %rdi,%rbx
170 branch [NE] [label:0x00007fe0e81b8a48]
0x00007fe114aac455: jne 0x00007fe114aac45b
move [stack:16|L] [rdi|L]
0x00007fe114aac45b: mov 0xc0(%rsp),%rdi
172 cmp [EQ] [rdi|L] [obj:0x0000000000000000|L]
0x00007fe114aac463: cmp $0x0,%rdi
174 branch [EQ] [label:0x00007fe0e81b8a48]
0x00007fe114aac467: je 0x00007fe114aac46d
176 move [Base:[rdi|L] Disp: 8|^@] [rsi|M]
0x00007fe114aac46d: mov 0x8(%rdi),%esi
0x00007fe114aac470: shl $0x3,%rsi
178 move [Base:[rsi|M] Disp: 395|B] [rsi|I]
0x00007fe114aac474: movsbl 0x18b(%rsi),%esi
180 cmp [EQ] [rsi|I] [int:0|I]
0x00007fe114aac47b: cmp $0x0,%esi
182 branch [EQ] [label:0x00007fe0e81b8a48]
0x00007fe114aac47e: je 0x00007fe114aac484
184 move [Base:[r15r15|J] Disp: 56|Z] [rsi|I]
0x00007fe114aac484: movsbl 0x38(%r15),%esi
186 cmp [NE] [rsi|I] [int:0|I]
0x00007fe114aac489: cmp $0x0,%esi
188 branch [NE] [ShenandoahPreBarrierStub: 0x00007fe0e81b92c0]
0x00007fe114aac48c: jne 0x00007fe114aac492
190 label [label:0x00007fe0e81b9360]
192 label [label:0x00007fe0e81b8a48]
R595 is short lived (only for the move + cmp) and assigned rdi. R584 was
lived before this piece of code and is used right after R595 goes
dead. R584 was spilled, is assigned rdi and is reloaded from the
stack. The problem is that there's control flow here that's invisible to
the register allocator. The register allocator only knows about control
flow that connects basic blocks. The control flow here is within a
block. So as far as the register allocator is concerned the code above
is a linear sequence of instructions all of which are all executed: so
once R584 is live by restoring the value from the stack into rdi, that
value in rdi is live too at the end of the code sequence above. Of
course, it's not true, the code sequence has branches, if branch at LIR
instruction 170 is taken, the value is not restored in rdi as expected
and that's why we have the crash.
So it's not a register allocator bug. The problem is hidden control flow
in basic blocks. The right fix I think is to move all of that code in
the backend (c1_LIRAssembler). That's quite a bit of work so I'll see if
I can think of a work around. Note that this is an upstream bug.
Roland.
More information about the shenandoah-dev
mailing list