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