前言
最近看到这篇例子的时候, [讨论] 内存可见性问题, 吧其中的 demo 拿到本地来跑
居然 和楼主一样, testBasicType 这里面的这个子线程 居然 不结束了, 卧槽 我还以为 只是可能 用的时间稍微长一点
哪知道 直接 无限期执行下去了, 然后 另外还有一个情况就是 加上了 -Xint, -Xcomp 都能够 完成 testBasicType 里面的线程的执行
默认 啥都不加的情况 testBasicType 一直无限期的执行下去了 (-Xmixed)
呵呵 反正还是有很多神奇的地方, 也有很多 超出了我认知范畴的事情啊
呵呵 不过还是需要记录一些东西, 毕竟有一些 直观的收货
擦另外一件关键的事情就是, 我擦 尝试过使用 clion 来调试, 呵呵 结果 testBasicType 循环结束了
然后 今早想到了这个 vm 执行模式 的相关的东西的时候, 我去掉了 -Xint 又尝试了一次, 擦 就能够复现了, 这样的话 那就更好了, 可以运行时 看下上下文的东西了 ^_^
在此之前是 使用 lldb 来调试, 中断的方式是通过 信号
环境如下
master:~ jerry$ uname -a
Darwin master.local 18.5.0 Darwin Kernel Version 18.5.0: Mon Mar 11 22:26:31 PDT 2019; root:xnu-4903.251.3~5/RELEASE_X86_64 x86_64
master:~ jerry$ java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
master:~ jerry$
测试用例
package com.hx.test05;
import java.util.HashMap;
/**
* Test22VisibleToStop
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2020-05-04 17:33
*/
public class Test22VisibleToStop {
private static boolean stop = false;
private static volatile boolean v2stop = false;
private static HashMap<String, Boolean> map2stop = new HashMap<String, Boolean>();
// Test22VisibleToStop
// 卧槽 显式加上 -Xint, -Xcomp 都能够停止, 啥都不加 停止不了,, 呵呵 好神奇啊
// -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=dontinline,*Test22VisibleToStop$3.run -XX:CompileCommand=compileonly,*Test22VisibleToStop$3.run
// 呵呵增加了一下 参数之后 直接就退出了
// refer : https://hllvm-group.iteye.com/group/topic/39675
public static void main(String[] args) throws Exception {
testMap();
testVolatile();
testBasicType();
testBasicTypeWithSync();
}
//程序正常结束
public static void testMap() throws InterruptedException{
map2stop.put("stop", Boolean.FALSE);
new Thread(){
@Override
public void run(){
int i=0;
while (!map2stop.get("stop") ){
i++;
}
System.out.println("map loop finish:"+i);
}
}.start();
Thread.sleep(1000);
map2stop.put("stop", Boolean.TRUE);
Thread.sleep(1000);
System.out.println("map main stop");
}
//说明了volatile的开销
public static void testVolatile() throws InterruptedException{
new Thread(){
@Override
public void run(){
int i=0;
while(!v2stop){
i++;
}
System.out.println("volatile loop finish:"+i);
}
}.start();
Thread.sleep(1000);
v2stop=true;
Thread.sleep(1000);
System.out.println("volatile main stop");
}
//不可见,发生死循环
public static void testBasicType() throws InterruptedException{
new Thread(){
@Override
public void run(){
int i=0;
while(!stop){
i++;
}
System.out.println("basic type loop finish:"+i);
}
}.start();
Thread.sleep(1000);
stop=true;
Thread.sleep(1000);
System.out.println("basic type main stop");
}
//不可见,发生死循环
public static void testBasicTypeWithSync() throws InterruptedException{
Object lock = new Object();
new Thread(){
@Override
public void run(){
int i=0;
while(!stop){
synchronized (lock) {
i++;
}
}
System.out.println("basic type with sync loop finish:"+i);
}
}.start();
Thread.sleep(1000);
synchronized (lock) {
stop = true;
}
Thread.sleep(1000);
System.out.println("basic type with sync main stop");
}
}
基于 lldb 的调试
(lldb) thread list
Process 862 stopped
* thread #1: tid = 0x57c2, 0x00007fff7ef2622a libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread', stop reason = signal SIGQUIT
thread #2: tid = 0x5832, 0x00007fff7ef289de libsystem_kernel.dylib`__ulock_wait + 10
thread #4: tid = 0x5834, 0x00007fff7ef27bfe libsystem_kernel.dylib`__workq_kernreturn + 10
thread #5: tid = 0x5835, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #7: tid = 0x5840, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #8: tid = 0x5841, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #9: tid = 0x5842, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #10: tid = 0x5843, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #11: tid = 0x5844, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #12: tid = 0x5845, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #13: tid = 0x5846, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #14: tid = 0x5847, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #15: tid = 0x5848, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #16: tid = 0x5849, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: Reference Handler'
thread #17: tid = 0x584a, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: Finalizer'
thread #18: tid = 0x584b, 0x00007fff7ef26266 libsystem_kernel.dylib`semaphore_wait_trap + 10, name = 'Java: Signal Dispatcher'
thread #19: tid = 0x584c, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: C2 CompilerThread0'
thread #20: tid = 0x584d, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: C2 CompilerThread1'
thread #21: tid = 0x584e, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: C2 CompilerThread2'
thread #22: tid = 0x584f, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: C1 CompilerThread3'
thread #23: tid = 0x5850, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'Java: Service Thread'
thread #24: tid = 0x5851, 0x00007fff7ef2986a libsystem_kernel.dylib`__psynch_cvwait + 10
thread #26: tid = 0x587c, 0x00000001048d2daa, name = 'Java: Thread-2'
(lldb) thread select 26
* thread #26, name = 'Java: Thread-2'
frame #0: 0x00000001048d2daa
-> 0x1048d2daa: jmp 0x1048d2da2
0x1048d2dac: movl $0xffffff86, %esi ; imm = 0xFFFFFF86
0x1048d2db1: nop
0x1048d2db3: callq 0x1047fe6a0
(lldb) bt
* thread #26, name = 'Java: Thread-2'
* frame #0: 0x00000001048d2daa
(lldb) re r
General Purpose Registers:
rax = 0x0000000000000e0b
rbx = 0x00000000000000b8
rcx = 0x0000000000000000
rdx = 0x00000000000e65f0
rdi = 0x0000000000000000
rsi = 0x0000000100100000
rbp = 0x00000000e71bf269
rsp = 0x0000700005b54960
r8 = 0x0000000000000002
r9 = 0x0000000000000000
r10 = 0x0000000000000000
r11 = 0x0000000000000003
r12 = 0x0000000000000000
r13 = 0x00000001048d2c10
r14 = 0x0000700005b54980
r15 = 0x0000000100847000
rip = 0x00000001048d2daa
rflags = 0x0000000000000246
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) dis -s 0x1048d2d82 -c 0x20
0x1048d2d82: movl $0x3ce9b52, %edx ; imm = 0x3CE9B52
0x1048d2d87: addl %eax, (%rax)
0x1048d2d89: addb %al, (%rax)
0x1048d2d8b: callq *%r10
0x1048d2d8e: movabsq $0x7955f36e0, %r10 ; imm = 0x7955F36E0
0x1048d2d98: movzbl 0x6c(%r10), %r10d
0x1048d2d9d: testl %r10d, %r10d
0x1048d2da0: jne 0x1048d2dac
0x1048d2da2: incl %ebp
0x1048d2da4: testl %eax, -0x47d7daa(%rip)
-> 0x1048d2daa: jmp 0x1048d2da2
0x1048d2dac: movl $0xffffff86, %esi ; imm = 0xFFFFFF86
0x1048d2db1: nop
0x1048d2db3: callq 0x1047fe6a0
0x1048d2db8: callq 0x103c8a904 ; os::breakpoint()
0x1048d2dbd: callq 0x103c8a904 ; os::breakpoint()
0x1048d2dc2: hlt
0x1048d2dc3: hlt
0x1048d2dc4: hlt
这里的核心的代码 就比较直观了, 主要在箭头处 三行代码, 一行累增, 一行 safepoint 轮询, 一行 jump(死循环)
incl ebp, 卧槽 bp 寄存器居然被分配来作为 计算的寄存器了, 哈哈 好神奇
test %eax 0x1000FB000, safepoint 轮询
jmp 0x1048d2da2, 直接无条件的跳转到了 第一条指令, 构成了 死循环
然后观察下 上面的 四条指令, 不就是类似于 if(!xxx.xx) goto $addr; 这种形式么?
那么 0x7955f36e0 是啥呢?, 根据猜测 应该是 Test22VisibleToStop.class, 从业务代码的角度来看
哎 但是这里只能查看 内存大的信息, 要去解码内存里面的信息 又太麻烦了, 呵呵 怎么办呢 ?
用 clion 来吧, 或者 基于 fastdebug 版本的 jdk9 来进行 lldb 的调试
基于clion的调试
以下调试 基于 jdk9
呵呵 看到了 类似的代码, 那么 我们这里 来看下 0x7bf7ae340 是什么吧?
java.lang.Class
{0x00000007bf7ae340} - klass: 'java/lang/Class'
- ---- fields (total size 15 words):
- private volatile transient strict 'cachedConstructor' 'Ljava/lang/reflect/Constructor;' @12 NULL (0 0)
- private volatile transient strict 'newInstanceCallerCache' 'Ljava/lang/Class;' @16 NULL (0 f7ef5c79)
- private transient 'name' 'Ljava/lang/String;' @20 "com.hx.test05.Test22VisibleToStop"{0x00000007bf7ae3c8} (f7ef5c79 f7f2770f)
- private transient 'module' 'Ljava/lang/Module;' @24 a 'java/lang/Module'{0x00000007bf93b878} (f7f2770f f7f24ba8)
- private final 'classLoader' 'Ljava/lang/ClassLoader;' @28 a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x00000007bf925d40} (f7f24ba8 f7ef52cc)
- private transient 'packageName' 'Ljava/lang/String;' @32 "com.hx.test05"{0x00000007bf7a9660} (f7ef52cc 0)
- private final strict 'componentType' 'Ljava/lang/Class;' @36 NULL (0 f7ef5c9a)
- private volatile transient strict 'reflectionData' 'Ljava/lang/ref/SoftReference;' @40 a 'java/lang/ref/SoftReference'{0x00000007bf7ae4d0} (f7ef5c9a 0)
- private volatile transient 'genericInfo' 'Lsun/reflect/generics/repository/ClassRepository;' @44 NULL (0 0)
- private volatile transient strict 'enumConstants' '[Ljava/lang/Object;' @48 NULL (0 0)
- private volatile transient strict 'enumConstantDirectory' 'Ljava/util/Map;' @52 NULL (0 0)
- private volatile transient 'annotationData' 'Ljava/lang/Class$AnnotationData;' @56 NULL (0 0)
- private volatile transient 'annotationType' 'Lsun/reflect/annotation/AnnotationType;' @60 NULL (0 0)
- transient 'classValueMap' 'Ljava/lang/ClassValue$ClassValueMap;' @64 NULL (0 f7ef5ba3)
- private volatile transient 'classRedefinedCount' 'I' @96 0
- signature: Lcom/hx/test05/Test22VisibleToStop;
- fake entry for mirror: 'com/hx/test05/Test22VisibleToStop'
- fake entry for array: NULL
- fake entry for oop_size: 15
- fake entry for static_oop_field_count: 1
- private static 'stop' 'Z' @116 true
- private static volatile 'v2stop' 'Z' @117 true
- private static strict 'map2stop' 'Ljava/util/HashMap;' @112 a 'java/util/HashMap'{0x00000007bf7aee58} (f7ef5dcb 101)
呵呵 结合这一系列的 运行时的数据, 这可能就是 R大 所说的 循环不变量外提 的优化吧
引用一下 R大 的原文
楼上试试用JDK8(jdk1.8.0 build 132)的Client VM在同一环境下跑这个测试再看看如何?
在打开-Xcomp之后就能看到不同的效果 ^_^
这是因为JDK8的HotSpot VM的Client Compiler(C1)实现了循环不变量外提(loop invariant code motion)优化,所以在正常编译该例子的run()方法时能把stop的检查提到循环外面,这样就跟C2的状况一样了。
不打开-Xcomp看不到效果是因为这样跑该例子会让run()方法触发OSR编译而不是正常编译,正好干扰到C1实现的LICM优化了,于是stop的检查就还在循环里,于是还是能让循环结束。
PrintAssembly 的输出结果
当添加了 PrintAssembly 的相关选项之后, 复现不了 Thread-2 进入死循环的效果了
这里贴一下 PrintAssembly 的输出结果
Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
CompilerOracle: dontinline *Test22VisibleToStop$3.run
CompilerOracle: compileonly *Test22VisibleToStop$3.run
Connected to the target VM, address: '127.0.0.1:58727', transport: 'socket'
map loop finish:2495652
map main stop
volatile loop finish:18327820
volatile main stop
Loaded disassembler from /Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/hsdis-amd64.dylib
Decoding compiled method 0x0000000112e20850:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Constants]
# {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3'
# [sp+0x60] (sp of caller)
0x0000000112e20a20: mov 0x8(%rsi),%r10d
0x0000000112e20a24: shl $0x3,%r10
0x0000000112e20a28: cmp %rax,%r10
0x0000000112e20a2b: jne 0x0000000112d64e60 ; {runtime_call}
0x0000000112e20a31: data32 data32 nopw 0x0(%rax,%rax,1)
0x0000000112e20a3c: data32 data32 xchg %ax,%ax
[Verified Entry Point]
0x0000000112e20a40: mov %eax,-0x14000(%rsp)
0x0000000112e20a47: push %rbp
0x0000000112e20a48: sub $0x50,%rsp
0x0000000112e20a4c: mov %rsi,0x28(%rsp)
0x0000000112e20a51: movabs $0x1265316d0,%rdi ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20a5b: mov 0xdc(%rdi),%ebx
0x0000000112e20a61: add $0x8,%ebx
0x0000000112e20a64: mov %ebx,0xdc(%rdi)
0x0000000112e20a6a: movabs $0x1265314c8,%rdi ; {metadata({method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20a74: and $0x0,%ebx
0x0000000112e20a77: cmp $0x0,%ebx
0x0000000112e20a7a: je 0x0000000112e20de8 ;*iconst_0
; - com.hx.test05.Test22VisibleToStop$3::run@0 (line 74)
0x0000000112e20a80: mov $0x0,%edi
0x0000000112e20a85: jmpq 0x0000000112e20ade ;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
0x0000000112e20a8a: nopw 0x0(%rax,%rax,1)
0x0000000112e20a90: mov 0x20(%rsp),%edi
0x0000000112e20a94: inc %edi
0x0000000112e20a96: movabs $0x1265316d0,%rdx ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20aa0: mov 0xe0(%rdx),%esi
0x0000000112e20aa6: add $0x8,%esi
0x0000000112e20aa9: mov %esi,0xe0(%rdx)
0x0000000112e20aaf: movabs $0x1265314c8,%rdx ; {metadata({method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20ab9: and $0xfff8,%esi
0x0000000112e20abf: cmp $0x0,%esi
0x0000000112e20ac2: je 0x0000000112e20dff ; OopMap{[40]=Oop off=168}
;*goto
; - com.hx.test05.Test22VisibleToStop$3::run@11 (line 76)
0x0000000112e20ac8: test %eax,-0x30799ce(%rip) # 0x000000010fda7100
; {poll}
0x0000000112e20ace: movabs $0x1265316d0,%rdx ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20ad8: incl 0x138(%rdx) ;*goto
; - com.hx.test05.Test22VisibleToStop$3::run@11 (line 76)
0x0000000112e20ade: mov %edi,0x20(%rsp)
0x0000000112e20ae2: movabs $0x1265316d0,%rbx ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20aec: addq $0x1,0x108(%rbx)
0x0000000112e20af4: nop
0x0000000112e20af5: nop
0x0000000112e20af6: nop
0x0000000112e20af7: callq 0x0000000112d65520 ; OopMap{[40]=Oop off=220}
;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
; {static_call}
0x0000000112e20afc: cmp $0x0,%eax
0x0000000112e20aff: movabs $0x1265316d0,%rdx ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20b09: movabs $0x118,%rsi
0x0000000112e20b13: jne 0x0000000112e20b23
0x0000000112e20b19: movabs $0x128,%rsi
0x0000000112e20b23: mov (%rdx,%rsi,1),%rdi
0x0000000112e20b27: lea 0x1(%rdi),%rdi
0x0000000112e20b2b: mov %rdi,(%rdx,%rsi,1)
0x0000000112e20b2f: je 0x0000000112e20a90 ;*ifne
; - com.hx.test05.Test22VisibleToStop$3::run@5 (line 75)
0x0000000112e20b35: movabs $0x795580c78,%rdx ; {oop(a 'java/lang/Class' = 'java/lang/System')}
0x0000000112e20b3f: mov 0x6c(%rdx),%ebx
0x0000000112e20b42: shl $0x3,%rbx ;*getstatic out
; - com.hx.test05.Test22VisibleToStop$3::run@14 (line 78)
0x0000000112e20b46: xchg %ax,%ax
0x0000000112e20b48: jmpq 0x0000000112e20e25 ; {no_reloc}
0x0000000112e20b4d: add %al,(%rax)
0x0000000112e20b4f: add %al,(%rax)
0x0000000112e20b51: add %cl,-0x75(%rcx)
0x0000000112e20b54: rex.RXB (bad)
0x0000000112e20b56: lea 0x18(%rax),%rdi
0x0000000112e20b5a: cmp 0x70(%r15),%rdi
0x0000000112e20b5e: ja 0x0000000112e20e2f
0x0000000112e20b64: mov %rdi,0x60(%r15)
0x0000000112e20b68: mov 0xa8(%rdx),%rcx
0x0000000112e20b6f: mov %rcx,(%rax)
0x0000000112e20b72: mov %rdx,%rcx
0x0000000112e20b75: shr $0x3,%rcx
0x0000000112e20b79: mov %ecx,0x8(%rax)
0x0000000112e20b7c: xor %rcx,%rcx
0x0000000112e20b7f: mov %ecx,0xc(%rax)
0x0000000112e20b82: xor %rcx,%rcx
0x0000000112e20b85: mov %rcx,0x10(%rax) ;*new ; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
0x0000000112e20b89: mov %rax,%rsi
0x0000000112e20b8c: movabs $0x1265316d0,%rdi ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20b96: addq $0x1,0x150(%rdi)
0x0000000112e20b9e: mov %rax,%rsi ;*invokespecial <init>
; - com.hx.test05.Test22VisibleToStop$3::run@21 (line 78)
0x0000000112e20ba1: mov %rbx,0x38(%rsp)
0x0000000112e20ba6: mov %rax,0x30(%rsp)
0x0000000112e20bab: nop
0x0000000112e20bac: nop
0x0000000112e20bad: nop
0x0000000112e20bae: nop
0x0000000112e20baf: callq 0x0000000112d650a0 ; OopMap{[48]=Oop [40]=Oop [56]=Oop off=404}
;*invokespecial <init>
; - com.hx.test05.Test22VisibleToStop$3::run@21 (line 78)
; {optimized virtual_call}
0x0000000112e20bb4: mov 0x30(%rsp),%rax
0x0000000112e20bb9: movabs $0x1265316d0,%rdx ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20bc3: mov 0x8(%rax),%eax
0x0000000112e20bc6: shl $0x3,%rax
0x0000000112e20bca: cmp 0x168(%rdx),%rax
0x0000000112e20bd1: jne 0x0000000112e20be0
0x0000000112e20bd3: addq $0x1,0x170(%rdx)
0x0000000112e20bdb: jmpq 0x0000000112e20c46
0x0000000112e20be0: cmp 0x178(%rdx),%rax
0x0000000112e20be7: jne 0x0000000112e20bf6
0x0000000112e20be9: addq $0x1,0x180(%rdx)
0x0000000112e20bf1: jmpq 0x0000000112e20c46
0x0000000112e20bf6: cmpq $0x0,0x168(%rdx)
0x0000000112e20c01: jne 0x0000000112e20c1a
0x0000000112e20c03: mov %rax,0x168(%rdx)
0x0000000112e20c0a: movq $0x1,0x170(%rdx)
0x0000000112e20c15: jmpq 0x0000000112e20c46
0x0000000112e20c1a: cmpq $0x0,0x178(%rdx)
0x0000000112e20c25: jne 0x0000000112e20c3e
0x0000000112e20c27: mov %rax,0x178(%rdx)
0x0000000112e20c2e: movq $0x1,0x180(%rdx)
0x0000000112e20c39: jmpq 0x0000000112e20c46
0x0000000112e20c3e: addq $0x1,0x160(%rdx)
0x0000000112e20c46: movabs $0x795c0cfb0,%rdx ; {oop("basic type loop finish:")}
0x0000000112e20c50: mov 0x30(%rsp),%rsi ;*invokevirtual append
; - com.hx.test05.Test22VisibleToStop$3::run@26 (line 78)
0x0000000112e20c55: nop
0x0000000112e20c56: nop
0x0000000112e20c57: callq 0x0000000112d650a0 ; OopMap{[40]=Oop [56]=Oop off=572}
;*invokevirtual append
; - com.hx.test05.Test22VisibleToStop$3::run@26 (line 78)
; {optimized virtual_call}
0x0000000112e20c5c: cmp (%rax),%rax ; implicit exception: dispatches to 0x0000000112e20e3c
0x0000000112e20c5f: mov %rax,%rdx
0x0000000112e20c62: movabs $0x1265316d0,%rsi ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20c6c: mov 0x8(%rdx),%edx
0x0000000112e20c6f: shl $0x3,%rdx
0x0000000112e20c73: cmp 0x198(%rsi),%rdx
0x0000000112e20c7a: jne 0x0000000112e20c89
0x0000000112e20c7c: addq $0x1,0x1a0(%rsi)
0x0000000112e20c84: jmpq 0x0000000112e20cef
0x0000000112e20c89: cmp 0x1a8(%rsi),%rdx
0x0000000112e20c90: jne 0x0000000112e20c9f
0x0000000112e20c92: addq $0x1,0x1b0(%rsi)
0x0000000112e20c9a: jmpq 0x0000000112e20cef
0x0000000112e20c9f: cmpq $0x0,0x198(%rsi)
0x0000000112e20caa: jne 0x0000000112e20cc3
0x0000000112e20cac: mov %rdx,0x198(%rsi)
0x0000000112e20cb3: movq $0x1,0x1a0(%rsi)
0x0000000112e20cbe: jmpq 0x0000000112e20cef
0x0000000112e20cc3: cmpq $0x0,0x1a8(%rsi)
0x0000000112e20cce: jne 0x0000000112e20ce7
0x0000000112e20cd0: mov %rdx,0x1a8(%rsi)
0x0000000112e20cd7: movq $0x1,0x1b0(%rsi)
0x0000000112e20ce2: jmpq 0x0000000112e20cef
0x0000000112e20ce7: addq $0x1,0x190(%rsi)
0x0000000112e20cef: mov 0x20(%rsp),%edx
0x0000000112e20cf3: mov %rax,%rsi ;*invokevirtual append
; - com.hx.test05.Test22VisibleToStop$3::run@30 (line 78)
0x0000000112e20cf6: nop
0x0000000112e20cf7: callq 0x0000000112d650a0 ; OopMap{[40]=Oop [56]=Oop off=732}
;*invokevirtual append
; - com.hx.test05.Test22VisibleToStop$3::run@30 (line 78)
; {optimized virtual_call}
0x0000000112e20cfc: cmp (%rax),%rax ; implicit exception: dispatches to 0x0000000112e20e41
0x0000000112e20cff: mov %rax,%rsi
0x0000000112e20d02: movabs $0x1265316d0,%rdi ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20d0c: mov 0x8(%rsi),%esi
0x0000000112e20d0f: shl $0x3,%rsi
0x0000000112e20d13: cmp 0x1c8(%rdi),%rsi
0x0000000112e20d1a: jne 0x0000000112e20d29
0x0000000112e20d1c: addq $0x1,0x1d0(%rdi)
0x0000000112e20d24: jmpq 0x0000000112e20d8f
0x0000000112e20d29: cmp 0x1d8(%rdi),%rsi
0x0000000112e20d30: jne 0x0000000112e20d3f
0x0000000112e20d32: addq $0x1,0x1e0(%rdi)
0x0000000112e20d3a: jmpq 0x0000000112e20d8f
0x0000000112e20d3f: cmpq $0x0,0x1c8(%rdi)
0x0000000112e20d4a: jne 0x0000000112e20d63
0x0000000112e20d4c: mov %rsi,0x1c8(%rdi)
0x0000000112e20d53: movq $0x1,0x1d0(%rdi)
0x0000000112e20d5e: jmpq 0x0000000112e20d8f
0x0000000112e20d63: cmpq $0x0,0x1d8(%rdi)
0x0000000112e20d6e: jne 0x0000000112e20d87
0x0000000112e20d70: mov %rsi,0x1d8(%rdi)
0x0000000112e20d77: movq $0x1,0x1e0(%rdi)
0x0000000112e20d82: jmpq 0x0000000112e20d8f
0x0000000112e20d87: addq $0x1,0x1c0(%rdi)
0x0000000112e20d8f: mov %rax,%rsi ;*invokevirtual toString
; - com.hx.test05.Test22VisibleToStop$3::run@33 (line 78)
0x0000000112e20d92: nop
0x0000000112e20d93: nop
0x0000000112e20d94: nop
0x0000000112e20d95: nop
0x0000000112e20d96: nop
0x0000000112e20d97: callq 0x0000000112d650a0 ; OopMap{[40]=Oop [56]=Oop off=892}
;*invokevirtual toString
; - com.hx.test05.Test22VisibleToStop$3::run@33 (line 78)
; {optimized virtual_call}
0x0000000112e20d9c: mov 0x38(%rsp),%rbx
0x0000000112e20da1: cmp (%rbx),%rax ; implicit exception: dispatches to 0x0000000112e20e46
0x0000000112e20da4: mov %rbx,%rdx
0x0000000112e20da7: movabs $0x1265316d0,%rsi ; {metadata(method data for {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e20db1: movabs $0x7c0027950,%r10 ; {metadata('java/io/PrintStream')}
0x0000000112e20dbb: mov %r10,0x1f8(%rsi)
0x0000000112e20dc2: addq $0x1,0x200(%rsi)
0x0000000112e20dca: mov %rax,%rdx
0x0000000112e20dcd: mov %rbx,%rsi ;*invokevirtual println
; - com.hx.test05.Test22VisibleToStop$3::run@36 (line 78)
0x0000000112e20dd0: nop
0x0000000112e20dd1: nop
0x0000000112e20dd2: nop
0x0000000112e20dd3: nop
0x0000000112e20dd4: nop
0x0000000112e20dd5: nop
0x0000000112e20dd6: nop
0x0000000112e20dd7: callq 0x0000000112d650a0 ; OopMap{[40]=Oop off=956}
;*invokevirtual println
; - com.hx.test05.Test22VisibleToStop$3::run@36 (line 78)
; {optimized virtual_call}
0x0000000112e20ddc: add $0x50,%rsp
0x0000000112e20de0: pop %rbp
0x0000000112e20de1: test %eax,-0x3079ce7(%rip) # 0x000000010fda7100
; {poll_return}
0x0000000112e20de7: retq
0x0000000112e20de8: mov %rdi,0x8(%rsp)
0x0000000112e20ded: movq $0xffffffffffffffff,(%rsp)
0x0000000112e20df5: callq 0x0000000112e1f5a0 ; OopMap{rsi=Oop [40]=Oop off=986}
;*synchronization entry
; - com.hx.test05.Test22VisibleToStop$3::run@-1 (line 74)
; {runtime_call}
0x0000000112e20dfa: jmpq 0x0000000112e20a80
0x0000000112e20dff: mov %rdx,0x8(%rsp)
0x0000000112e20e04: movq $0xb,(%rsp)
0x0000000112e20e0c: callq 0x0000000112e1f5a0 ; OopMap{[40]=Oop off=1009}
;*goto
; - com.hx.test05.Test22VisibleToStop$3::run@11 (line 76)
; {runtime_call}
0x0000000112e20e11: jmpq 0x0000000112e20ac8
0x0000000112e20e16: movabs $0x0,%rdx ; {metadata(NULL)}
0x0000000112e20e20: mov $0xa050f00,%eax
0x0000000112e20e25: callq 0x0000000112e1e460 ; OopMap{[40]=Oop rbx=Oop off=1034}
;*new ; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
; {runtime_call}
0x0000000112e20e2a: jmpq 0x0000000112e20b48
0x0000000112e20e2f: mov %rdx,%rdx
0x0000000112e20e32: callq 0x0000000112e1b560 ; OopMap{rbx=Oop [40]=Oop off=1047}
;*new ; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
; {runtime_call}
0x0000000112e20e37: jmpq 0x0000000112e20b89
0x0000000112e20e3c: callq 0x0000000112e1ae00 ; OopMap{[40]=Oop [56]=Oop rax=Oop off=1057}
;*invokevirtual append
; - com.hx.test05.Test22VisibleToStop$3::run@30 (line 78)
; {runtime_call}
0x0000000112e20e41: callq 0x0000000112e1ae00 ; OopMap{[40]=Oop [56]=Oop rax=Oop off=1062}
;*invokevirtual toString
; - com.hx.test05.Test22VisibleToStop$3::run@33 (line 78)
; {runtime_call}
0x0000000112e20e46: callq 0x0000000112e1ae00 ; OopMap{[40]=Oop rax=Oop rbx=Oop off=1067}
;*invokevirtual println
; - com.hx.test05.Test22VisibleToStop$3::run@36 (line 78)
; {runtime_call}
0x0000000112e20e4b: nop
0x0000000112e20e4c: nop
0x0000000112e20e4d: mov 0x2a8(%r15),%rax
0x0000000112e20e54: movabs $0x0,%r10
0x0000000112e20e5e: mov %r10,0x2a8(%r15)
0x0000000112e20e65: movabs $0x0,%r10
0x0000000112e20e6f: mov %r10,0x2b0(%r15)
0x0000000112e20e76: add $0x50,%rsp
0x0000000112e20e7a: pop %rbp
0x0000000112e20e7b: jmpq 0x0000000112d8d960 ; {runtime_call}
[Stub Code]
0x0000000112e20e80: nop ; {no_reloc}
0x0000000112e20e81: nop
0x0000000112e20e82: nop
0x0000000112e20e83: nop
0x0000000112e20e84: nop
0x0000000112e20e85: movabs $0x0,%rbx ; {static_stub}
0x0000000112e20e8f: jmpq 0x0000000112e20e8f ; {runtime_call}
0x0000000112e20e94: nop
0x0000000112e20e95: movabs $0x0,%rbx ; {static_stub}
0x0000000112e20e9f: jmpq 0x0000000112e20e9f ; {runtime_call}
0x0000000112e20ea4: nop
0x0000000112e20ea5: movabs $0x0,%rbx ; {static_stub}
0x0000000112e20eaf: jmpq 0x0000000112e20eaf ; {runtime_call}
0x0000000112e20eb4: nop
0x0000000112e20eb5: movabs $0x0,%rbx ; {static_stub}
0x0000000112e20ebf: jmpq 0x0000000112e20ebf ; {runtime_call}
0x0000000112e20ec4: nop
0x0000000112e20ec5: movabs $0x0,%rbx ; {static_stub}
0x0000000112e20ecf: jmpq 0x0000000112e20ecf ; {runtime_call}
0x0000000112e20ed4: nop
0x0000000112e20ed5: movabs $0x0,%rbx ; {static_stub}
0x0000000112e20edf: jmpq 0x0000000112e20edf ; {runtime_call}
[Exception Handler]
0x0000000112e20ee4: callq 0x0000000112e1cca0 ; {runtime_call}
0x0000000112e20ee9: mov %rsp,-0x28(%rsp)
0x0000000112e20eee: sub $0x80,%rsp
0x0000000112e20ef5: mov %rax,0x78(%rsp)
0x0000000112e20efa: mov %rcx,0x70(%rsp)
0x0000000112e20eff: mov %rdx,0x68(%rsp)
0x0000000112e20f04: mov %rbx,0x60(%rsp)
0x0000000112e20f09: mov %rbp,0x50(%rsp)
0x0000000112e20f0e: mov %rsi,0x48(%rsp)
0x0000000112e20f13: mov %rdi,0x40(%rsp)
0x0000000112e20f18: mov %r8,0x38(%rsp)
0x0000000112e20f1d: mov %r9,0x30(%rsp)
0x0000000112e20f22: mov %r10,0x28(%rsp)
0x0000000112e20f27: mov %r11,0x20(%rsp)
0x0000000112e20f2c: mov %r12,0x18(%rsp)
0x0000000112e20f31: mov %r13,0x10(%rsp)
0x0000000112e20f36: mov %r14,0x8(%rsp)
0x0000000112e20f3b: mov %r15,(%rsp)
0x0000000112e20f3f: movabs $0x1113de684,%rdi ; {external_word}
0x0000000112e20f49: movabs $0x112e20ee9,%rsi ; {internal_word}
0x0000000112e20f53: mov %rsp,%rdx
0x0000000112e20f56: and $0xfffffffffffffff0,%rsp
0x0000000112e20f5a: callq 0x00000001112071f6 ; {runtime_call}
0x0000000112e20f5f: hlt
[Deopt Handler Code]
0x0000000112e20f60: movabs $0x112e20f60,%r10 ; {section_word}
0x0000000112e20f6a: push %r10
0x0000000112e20f6c: jmpq 0x0000000112d66500 ; {runtime_call}
0x0000000112e20f71: hlt
0x0000000112e20f72: hlt
0x0000000112e20f73: hlt
0x0000000112e20f74: hlt
0x0000000112e20f75: hlt
0x0000000112e20f76: hlt
0x0000000112e20f77: hlt
Decoding compiled method 0x0000000112e2cb50:
Code:
[Entry Point]
[Constants]
# {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3'
# [sp+0x30] (sp of caller)
0x0000000112e2cca0: mov 0x8(%rsi),%r10d
0x0000000112e2cca4: shl $0x3,%r10
0x0000000112e2cca8: cmp %r10,%rax
0x0000000112e2ccab: jne 0x0000000112d64e60 ; {runtime_call}
0x0000000112e2ccb1: data32 xchg %ax,%ax
0x0000000112e2ccb4: nopl 0x0(%rax,%rax,1)
0x0000000112e2ccbc: data32 data32 xchg %ax,%ax
[Verified Entry Point]
0x0000000112e2ccc0: mov %eax,-0x14000(%rsp)
0x0000000112e2ccc7: push %rbp
0x0000000112e2ccc8: sub $0x20,%rsp ;*synchronization entry
; - com.hx.test05.Test22VisibleToStop$3::run@-1 (line 74)
0x0000000112e2cccc: mov %rsi,(%rsp)
0x0000000112e2ccd0: data32 xchg %ax,%ax
0x0000000112e2ccd3: callq 0x0000000112d65520 ; OopMap{[0]=Oop off=56}
;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
; {static_call}
0x0000000112e2ccd8: test %eax,%eax
0x0000000112e2ccda: jne 0x0000000112e2cd25 ;*ifne
; - com.hx.test05.Test22VisibleToStop$3::run@5 (line 75)
0x0000000112e2ccdc: mov $0x1,%r11d
0x0000000112e2cce2: mov %r11d,0x8(%rsp)
0x0000000112e2cce7: jmp 0x0000000112e2ccfd
0x0000000112e2cce9: nopl 0x0(%rax)
0x0000000112e2ccf0: mov 0x8(%rsp),%r10d
0x0000000112e2ccf5: inc %r10d
0x0000000112e2ccf8: mov %r10d,0x8(%rsp) ;*iinc
; - com.hx.test05.Test22VisibleToStop$3::run@8 (line 76)
0x0000000112e2ccfd: xchg %ax,%ax
0x0000000112e2ccff: callq 0x0000000112d65520 ; OopMap{[0]=Oop off=100}
;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
; {static_call}
0x0000000112e2cd04: test %eax,%eax
0x0000000112e2cd06: je 0x0000000112e2ccf0 ;*ifne
; - com.hx.test05.Test22VisibleToStop$3::run@5 (line 75)
0x0000000112e2cd08: mov $0x4,%esi
0x0000000112e2cd0d: movabs $0x795580c78,%r10 ; {oop(a 'java/lang/Class' = 'java/lang/System')}
0x0000000112e2cd17: mov 0x6c(%r10),%ebp
0x0000000112e2cd1b: callq 0x0000000112d646a0 ; OopMap{rbp=NarrowOop [0]=Oop off=128}
;*new ; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
; {runtime_call}
0x0000000112e2cd20: callq 0x000000011128a904 ;*new
; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
; {runtime_call}
0x0000000112e2cd25: xor %r10d,%r10d
0x0000000112e2cd28: mov %r10d,0x8(%rsp)
0x0000000112e2cd2d: jmp 0x0000000112e2cd08
0x0000000112e2cd2f: mov %rax,%rsi
0x0000000112e2cd32: jmp 0x0000000112e2cd37
0x0000000112e2cd34: mov %rax,%rsi ;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
0x0000000112e2cd37: add $0x20,%rsp
0x0000000112e2cd3b: pop %rbp
0x0000000112e2cd3c: jmpq 0x0000000112e21820 ; {runtime_call}
0x0000000112e2cd41: hlt
0x0000000112e2cd42: hlt
0x0000000112e2cd43: hlt
0x0000000112e2cd44: hlt
0x0000000112e2cd45: hlt
0x0000000112e2cd46: hlt
0x0000000112e2cd47: hlt
0x0000000112e2cd48: hlt
0x0000000112e2cd49: hlt
0x0000000112e2cd4a: hlt
0x0000000112e2cd4b: hlt
0x0000000112e2cd4c: hlt
0x0000000112e2cd4d: hlt
0x0000000112e2cd4e: hlt
0x0000000112e2cd4f: hlt
0x0000000112e2cd50: hlt
0x0000000112e2cd51: hlt
0x0000000112e2cd52: hlt
0x0000000112e2cd53: hlt
0x0000000112e2cd54: hlt
0x0000000112e2cd55: hlt
0x0000000112e2cd56: hlt
0x0000000112e2cd57: hlt
0x0000000112e2cd58: hlt
0x0000000112e2cd59: hlt
0x0000000112e2cd5a: hlt
0x0000000112e2cd5b: hlt
0x0000000112e2cd5c: hlt
0x0000000112e2cd5d: hlt
0x0000000112e2cd5e: hlt
0x0000000112e2cd5f: hlt
[Stub Code]
0x0000000112e2cd60: movabs $0x0,%rbx ; {no_reloc}
0x0000000112e2cd6a: jmpq 0x0000000112e2cd6a ; {runtime_call}
0x0000000112e2cd6f: movabs $0x0,%rbx ; {static_stub}
0x0000000112e2cd79: jmpq 0x0000000112e2cd79 ; {runtime_call}
[Exception Handler]
0x0000000112e2cd7e: jmpq 0x0000000112d76da0 ; {runtime_call}
[Deopt Handler Code]
0x0000000112e2cd83: callq 0x0000000112e2cd88
0x0000000112e2cd88: subq $0x5,(%rsp)
0x0000000112e2cd8d: jmpq 0x0000000112d66500 ; {runtime_call}
0x0000000112e2cd92: hlt
0x0000000112e2cd93: hlt
0x0000000112e2cd94: hlt
0x0000000112e2cd95: hlt
0x0000000112e2cd96: hlt
0x0000000112e2cd97: hlt
Decoding compiled method 0x0000000112e2c7d0:
Code:
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} {0x00000001265314c8} 'run' '()V' in 'com/hx/test05/Test22VisibleToStop$3'
0x0000000112e2c920: callq 0x000000011128a904 ; {runtime_call}
0x0000000112e2c925: data32 data32 nopw 0x0(%rax,%rax,1)
0x0000000112e2c930: mov %eax,-0x14000(%rsp)
0x0000000112e2c937: push %rbp
0x0000000112e2c938: sub $0x20,%rsp
0x0000000112e2c93c: mov (%rsi),%ebx
0x0000000112e2c93e: mov 0x8(%rsi),%rbp
0x0000000112e2c942: mov %rsi,%rdi
0x0000000112e2c945: movabs $0x1112e9b52,%r10
0x0000000112e2c94f: callq *%r10
0x0000000112e2c952: test %rbp,%rbp
0x0000000112e2c955: je 0x0000000112e2c9ad
0x0000000112e2c957: mov 0x8(%rbp),%r10d
0x0000000112e2c95b: cmp $0xf800c461,%r10d ; {metadata('com/hx/test05/Test22VisibleToStop$3')}
0x0000000112e2c962: jne 0x0000000112e2c9b1 ;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
0x0000000112e2c964: jmp 0x0000000112e2c97c
0x0000000112e2c966: data32 nopw 0x0(%rax,%rax,1)
0x0000000112e2c970: mov 0x8(%rsp),%ebx
0x0000000112e2c974: inc %ebx ; OopMap{rbp=Oop off=86}
;*goto
; - com.hx.test05.Test22VisibleToStop$3::run@11 (line 76)
0x0000000112e2c976: test %eax,-0x308597c(%rip) # 0x000000010fda7000
; {poll}
0x0000000112e2c97c: mov %rbp,(%rsp)
0x0000000112e2c980: mov %ebx,0x8(%rsp)
0x0000000112e2c984: data32 xchg %ax,%ax
0x0000000112e2c987: callq 0x0000000112d65520 ; OopMap{rbp=Oop [0]=Oop off=108}
;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
; {static_call}
0x0000000112e2c98c: test %eax,%eax
0x0000000112e2c98e: je 0x0000000112e2c970 ;*ifne
; - com.hx.test05.Test22VisibleToStop$3::run@5 (line 75)
0x0000000112e2c990: mov $0x4,%esi
0x0000000112e2c995: movabs $0x795580c78,%r10 ; {oop(a 'java/lang/Class' = 'java/lang/System')}
0x0000000112e2c99f: mov 0x6c(%r10),%ebp
0x0000000112e2c9a3: callq 0x0000000112d646a0 ; OopMap{rbp=NarrowOop [0]=Oop off=136}
;*new ; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
; {runtime_call}
0x0000000112e2c9a8: callq 0x000000011128a904 ;*new
; - com.hx.test05.Test22VisibleToStop$3::run@17 (line 78)
; {runtime_call}
0x0000000112e2c9ad: xor %ebp,%ebp
0x0000000112e2c9af: jmp 0x0000000112e2c97c
0x0000000112e2c9b1: mov $0xffffff9d,%esi
0x0000000112e2c9b6: mov %ebx,(%rsp)
0x0000000112e2c9b9: xchg %ax,%ax
0x0000000112e2c9bb: callq 0x0000000112d646a0 ; OopMap{rbp=Oop off=160}
;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
; {runtime_call}
0x0000000112e2c9c0: callq 0x000000011128a904 ; {runtime_call}
0x0000000112e2c9c5: mov %rax,%rsi
0x0000000112e2c9c8: add $0x20,%rsp
0x0000000112e2c9cc: pop %rbp
0x0000000112e2c9cd: jmpq 0x0000000112e21820 ;*invokestatic access$200
; - com.hx.test05.Test22VisibleToStop$3::run@2 (line 75)
; {runtime_call}
0x0000000112e2c9d2: hlt
0x0000000112e2c9d3: hlt
0x0000000112e2c9d4: hlt
0x0000000112e2c9d5: hlt
0x0000000112e2c9d6: hlt
0x0000000112e2c9d7: hlt
0x0000000112e2c9d8: hlt
0x0000000112e2c9d9: hlt
0x0000000112e2c9da: hlt
0x0000000112e2c9db: hlt
0x0000000112e2c9dc: hlt
0x0000000112e2c9dd: hlt
0x0000000112e2c9de: hlt
0x0000000112e2c9df: hlt
[Stub Code]
0x0000000112e2c9e0: movabs $0x0,%rbx ; {no_reloc}
0x0000000112e2c9ea: jmpq 0x0000000112e2c9ea ; {runtime_call}
[Exception Handler]
0x0000000112e2c9ef: jmpq 0x0000000112d76da0 ; {runtime_call}
[Deopt Handler Code]
0x0000000112e2c9f4: callq 0x0000000112e2c9f9
0x0000000112e2c9f9: subq $0x5,(%rsp)
0x0000000112e2c9fe: jmpq 0x0000000112d66500 ; {runtime_call}
0x0000000112e2ca03: hlt
0x0000000112e2ca04: hlt
0x0000000112e2ca05: hlt
0x0000000112e2ca06: hlt
0x0000000112e2ca07: hlt
basic type loop finish:17687011
basic type main stop
basic type with sync loop finish:0
basic type with sync main stop
Disconnected from the target VM, address: '127.0.0.1:58727', transport: 'socket'
Process finished with exit code 0
可以看出 编译了 三个版本, 其中 第二个版本 逻辑更加容易 理解一些
如果有兴趣的话 可以看一下第一个版本, 呵呵 反正我是没看, 有点麻烦
根据 bx 查看一下运行时方法的信息
呵呵 发现了这个的话, 我觉得 以这个例子 理解一下 Method 的 _from_interpreted_entry, _from_compiled_entry, _i2i_entry, code 这几个东西了
呵呵 另外一件事情, 就是 看到了 Method 里面的 MethodData 和 MethodCounters 了, 之前调试的时候 大部分的时候 看到的都是 NULL
相关疑问?
1. -Xint, -Xcomp 都能够正常结束, -Xmixed 不行 ?
可能可以从 R大 上面的这段解释 中找出原因吧, 不过 终究还是 道行太浅, 没得依据
2. 在 Thread-2 里面打上断点, 放掉 就能够退出了
呵呵 可能是 hit 到断点的时候, 回退了运行时 执行的代码吧, 之类的, 没得依据
添加于2020.03.01 - 找到的一个合理的解释
呵呵 最近的时候, 在 perfma 社区看到了一篇文章
一道面试题引发的对Java内存模型的一点疑问,第二部。这篇文章可以关联到文章 一道面试题引发的对Java内存模型的一点疑问?这篇文章又可以关联到知乎的一篇文章 java中volatile关键字的疑惑?
这里面的解释, 虽然我目前 还有一些 没有明白的地方, 但是根据我的调试, 最终运行时的这些东西 和 文章中的论证的结论是一致的
呵呵 多久再细看一下 hb, 在研究研究, 目前还了解的不够吧
测试用例
先看看测试用例, 和原文的用例差不多的
/**
* Test13InfiniteLoop
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2021-02-22 11:14
*/
public class Test13InfiniteLoop {
static int num = 11; // 0/1/11
// Test13InfiniteLoop, 死循环
// refer : https://club.perfma.com/question/2079981
// refer : https://club.perfma.com/question/267086
// refer : https://www.zhihu.com/question/263528143/answer/270308453
public static void main(String[] args) {
new Thread(() -> {
System.out.println(" child -> " + num);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
num++;
System.out.println(" child -> " + num);
}).start();
System.out.println(" main -> " + num);
int counter = 0;
while (num == 11) {
counter++;
// System.out.println(" main -> " + num);
}
System.out.println(" main -> " + num);
System.out.println(" main -> " + counter);
}
}
我们这会看 num 初始化为 0, 1, 11 的三种场景
之所以这里处理 num 这三种情况, 是因为 num 为 0 的时候, 我们判断不出 前面的这一个 test 指令是否是对应于 main 里面的 "while (num == 11)" 的判断
num 为 0 的情况
main 线程的运行时的代码的信息如下, 可以看出 "testl %r11d, %r11d" 大致是 "while (num == 0)" 的判断, 下面的 0x10cb718c5 以及紧接着的三条指令为 循环里面的业务代码
(lldb) dis -s 0x10cb718a0 -c 100
0x10cb718a0: movl %esi, %edi
0x10cb718a2: movabsq $0x1045ec000, %r10 ; imm = 0x1045EC000
0x10cb718ac: callq *%r10
0x10cb718af: movabsq $0x747bb8860, %r10 ; imm = 0x747BB8860
0x10cb718b9: movl 0x70(%r10), %r11d
0x10cb718bd: testl %r11d, %r11d
0x10cb718c0: jne 0x10cb718d0
0x10cb718c2: incl %r13d
-> 0x10cb718c5: incl %r13d
0x10cb718c8: testl %eax, -0xc7008ce(%rip)
0x10cb718ce: jmp 0x10cb718c5
0x10cb718d0: movl %r11d, %r10d
0x10cb718d3: negl %r10d
0x10cb718d6: cmpl $0x80000000, %r11d ; imm = 0x80000000
0x10cb718dd: jne 0x10cb71ffb
0x10cb718e3: movl $0x14, %ebp
0x10cb718e8: movl $0x1, %r8d
0x10cb718ee: movl $0x14, %ecx
0x10cb718f3: jmp 0x10cb7191c
0x10cb718f5: nop
// 省略一部分记录信息
num 为 1 的情况
main 线程的运行时的代码的信息如下, 可以看出 "cmpl $0x1, %r10d" 大致是 "while (num == 1)" 的判断, 下面的 0x10dafe302 以及紧接着的三条指令为 循环里面的业务代码
(lldb) dis -s 0x10dafe2f0 -c 100
0x10dafe2f0: cmpb %cl, 0x747bb(%rax)
0x10dafe2f6: addb %al, (%rax)
0x10dafe2f8: movl 0x70(%r10), %r10d
0x10dafe2fc: cmpl $0x1, %r10d
0x10dafe300: jne 0x10dafe30c
0x10dafe302: incl %ebp
-> 0x10dafe304: testl %eax, -0xd78d30a(%rip)
0x10dafe30a: jmp 0x10dafe302
0x10dafe30c: movl $0xffffff86, %esi ; imm = 0xFFFFFF86
0x10dafe311: nop
// 省略一部分记录信息
num 为 11 的情况
main 线程的运行时的代码的信息如下, 可以看出 "cmpl $0xb, %r11d" 大致是 "while (num == 11)" 的判断, 下面的 0x10c382546 以及紧接着的三条指令为 循环里面的业务代码
(lldb) dis -s 0x10c382531 -c 100
0x10c382531: orb %cl, 0x747bb(%rcx)
0x10c382537: addb %al, (%rax)
0x10c382539: movl 0x70(%r10), %r11d
0x10c38253d: cmpl $0xb, %r11d
0x10c382541: jne 0x10c382551
0x10c382543: incl %r13d
-> 0x10c382546: incl %r13d
0x10c382549: testl %eax, -0xc11154f(%rip)
0x10c38254f: jmp 0x10c382546
0x10c382551: movl %r11d, %r10d
0x10c382554: negl %r10d
0x10c382557: cmpl $0x80000000, %r11d ; imm = 0x80000000
0x10c38255e: jne 0x10c382c7b
0x10c382564: movl $0x14, %ebp
0x10c382569: movl $0x1, %r8d
0x10c38256f: movl $0x14, %ecx
0x10c382574: jmp 0x10c38259c
0x10c382576: nop
// 省略一部分记录信息
记录就差不多到这里了, 结果是和 这篇文章的记录是吻合的
代码确实是被替换成了, 类似于 如下的代码片
if (num == 11) {
while(true) {
counter++;
}
}
完
参考
[讨论] 内存可见性问题
一道面试题引发的对Java内存模型的一点疑问,第二部。
一道面试题引发的对Java内存模型的一点疑问?
java中volatile关键字的疑惑?