loop invariant code motion and the jit

Vitaly Davidovich vitalyd at gmail.com
Wed Jan 18 20:10:13 UTC 2017


No, there's nothing stopping this hoisting, and it happens (as you can
see).  I've seen people get hit by this in practice.

On Wed, Jan 18, 2017 at 3:04 PM, Peter Veentjer <alarmnummer at gmail.com>
wrote:

> I have a related question about loop hoisting, but this case in
> combination with stopping a thread.
>
> private boolean stop;
> private long value;
>
> @Override
> public void run() {
>     while (!stop) {
>         value++;
>     }
> }
>
> In theory the read of stop can be pulled out of the loop since stop isn't
> properly synchronised (volatile would do the trick).
>
> Is there any prevention of this optimisation being applied to protect
> users against improper synchronised code?
>
> When I'm checking the Assembly; the read of stop has being pulled out of
> the loop.
>
> 0x0000000105cad675: inc    QWORD PTR [rbp+0x10]
> 0x0000000105cad679: test   DWORD PTR [rip+0xffffffffff720981],eax
>                             0x0000000105cad67f: jmp    0x0000000105cad675
>
> I have included the full program, its settings and the Assembler below.
>
> public class StopExample {
>
>     public static void main(String[] args) throws InterruptedException {
>         StoppableRunnable runnable = new StoppableRunnable();
>         Thread t = new Thread(runnable);
>         t.start();
>
>         try {
>             SECONDS.sleep(20);
>         } catch (InterruptedException e) {
>         }
>         runnable.stop = true;
>         System.out.println("Stop called");
>         t.join();
>         System.out.println("Done: " + runnable.value);
>     }
>
>     public static class StoppableRunnable implements Runnable {
>         private boolean stop;
>         private long value;
>
>         @Override
>         public void run() {
>             while (!stop) {
>                 value++;
>             }
>         }
>     }
> }
>
>   # {method} {0x000000010dfd6b98} 'run' '()V' in 'com/loop/StopExample$
> StoppableRunnable'
>   0x0000000105cad620: call   0x0000000104828e44  ;   {runtime_call}
>   0x0000000105cad625: data32 data32 nop WORD PTR [rax+rax*1+0x0]
>   0x0000000105cad630: mov    DWORD PTR [rsp-0x14000],eax
>   0x0000000105cad637: push   rbp
>   0x0000000105cad638: sub    rsp,0x10
>   0x0000000105cad63c: mov    rbp,QWORD PTR [rsi]
>   0x0000000105cad63f: mov    rdi,rsi
>   0x0000000105cad642: movabs r10,0x1048826e4
>   0x0000000105cad64c: call   r10
>   0x0000000105cad64f: test   rbp,rbp
>   0x0000000105cad652: je     0x0000000105cad681
>   0x0000000105cad654: mov    r10d,DWORD PTR [rbp+0x8]
>   0x0000000105cad658: cmp    r10d,0xf800c105    ;   {metadata('com/loop/
> StopExample$StoppableRunnable')}
>   0x0000000105cad65f: jne    0x0000000105cad685  ;*aload_0
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 0 (line 28)
>
>   0x0000000105cad661: movzx  r10d,BYTE PTR [rbp+0xc]  ; implicit
> exception: dispatches to 0x0000000105cad6a1
>   0x0000000105cad666: test   r10d,r10d
>   0x0000000105cad669: jne    0x0000000105cad695  ;*ifne
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 4 (line 28)
>
>   0x0000000105cad66b: inc    QWORD PTR [rbp+0x10]  ; OopMap{rbp=Oop off=79}
>                                                 ;*goto
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 17 (line 29)
>
>   0x0000000105cad66f: test   DWORD PTR [rip+0xffffffffff72098b],eax
>  # 0x00000001053ce000
>                                                 ;*goto
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 17 (line 29)
>                                                 ;   {poll}
>   0x0000000105cad675: inc    QWORD PTR [rbp+0x10]  ; OopMap{rbp=Oop off=89}
>                                                 ;*goto
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 17 (line 29)
>
>   0x0000000105cad679: test   DWORD PTR [rip+0xffffffffff720981],eax
>  # 0x00000001053ce000
>                                                 ;*goto
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 17 (line 29)
>                                                 ;   {poll}
>   0x0000000105cad67f: jmp    0x0000000105cad675
>   0x0000000105cad681: xor    ebp,ebp
>   0x0000000105cad683: jmp    0x0000000105cad661
>   0x0000000105cad685: mov    esi,0xffffff9d
>   0x0000000105cad68a: nop
>   0x0000000105cad68b: call   0x0000000105c7b120  ; OopMap{rbp=Oop off=112}
>                                                 ;*aload_0
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 0 (line 28)
>                                                 ;   {runtime_call}
>   0x0000000105cad690: call   0x0000000104828e44  ;   {runtime_call}
>   0x0000000105cad695: add    rsp,0x10
>   0x0000000105cad699: pop    rbp
>   0x0000000105cad69a: test   DWORD PTR [rip+0xffffffffff720960],eax
>  # 0x00000001053ce000
>                                                 ;   {poll_return}
>   0x0000000105cad6a0: ret
>   0x0000000105cad6a1: mov    esi,0xffffff86
>   0x0000000105cad6a6: nop
>   0x0000000105cad6a7: call   0x0000000105c7b120  ; OopMap{rbp=Oop off=140}
>                                                 ;*aload_0
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 0 (line 28)
>                                                 ;   {runtime_call}
>   0x0000000105cad6ac: call   0x0000000104828e44  ;*aload_0
>                                                 ; - com.loop.StopExample$
> StoppableRunnable::run at 0 (line 28)
>                                                 ;   {runtime_call}
>   0x0000000105cad6b1: call   0x0000000104828e44  ;   {runtime_call}
>
> -XX:+UnlockDiagnosticVMOptions
> -XX:PrintAssemblyOptions=intel
> -XX:-TieredCompilation
> -XX:-Inline
> -XX:-BackgroundCompilation
> -XX:CompileCommand=print,*StoppableRunnable.run*
> -XX:LoopUnrollLimit=0
>
>
>
> On Wed, Jan 18, 2017 at 5:52 PM, Roland Westrelin <rwestrel at redhat.com>
> wrote:
>
>>
>> > Roland, would it be possible to have IdealLoopTree reassociate the
>> > operations and then mark the AddNode to tell it to not perform
>> > canonicalization again?
>>
>> Possibly eventhough AFAICT, current c2 code avoids that kind of
>> tricks. Anyway, if that was fixed one way or another, we would also need
>> to verify that it doesn't cause any regression so it's more work than it
>> may appear and in this particular case I'm not sure it's worth the
>> trouble.
>>
>> Roland.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20170118/275e86ee/attachment-0001.html>


More information about the hotspot-compiler-dev mailing list