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