loop invariant code motion and the jit
Peter Veentjer
alarmnummer at gmail.com
Wed Jan 18 20:04:32 UTC 2017
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/5f5cfbbb/attachment-0001.html>
More information about the hotspot-compiler-dev
mailing list