59 多线程环境普通变量作为标记循环不结束

news2024/9/28 10:32:19

前言

最近看到这篇例子的时候, [讨论] 内存可见性问题, 吧其中的 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关键字的疑惑?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Segmenter论文解读

Segmenter: Transformer for Semantic Segmentation 论文&#xff1a;[2105.05633] Segmenter: Transformer for Semantic Segmentation (arxiv.org) 代码&#xff1a;[rstrudel/segmenter: ICCV2021] Official PyTorch implementation of Segmenter: Transformer for Semanti…

vue3+ts error TS7053:

在远程仓库拉取线上正常运行的项目&#xff0c;编译之后出现报错出现问题&#xff0c;逐步排查node版本是否与别人一致2.检查node_modules是否与别人一致检查到这一步就发现了是因为依赖版本不一致导致的原因因为目前vue-tsc等依赖更新频繁把这两个依赖的版本号锁死&#xff0c…

vuex

目录 1、什么是vuex 2、vuex的工作方式 3、vuex的使用场景 4、工作流程&#xff1a;View -> Actions -> Mutations -> State -> View 5、vuex的核心API ​ &#xff08;1&#xff09;state&#xff1a; ​ &#xff08;2&#xff09;mutations ​ &#xff…

Pinia的使用(以vue3+ts+vite为例)

文章目录Pinia1. 安装2. 引入vue33. 初始化store仓库4. 修改state5. 解构store6. store中的方法和计算属性&#xff08;actions、getters&#xff09;7. API7.1 $reset7.2 $subscribe 和 $onAction8. 插件案例&#xff1a;持久化插件Pinia Pinia官方文档 Pinia GitHub地址 1…

VSCode vscode-pandoc插件将中文Markdown转换为好看的pdf文档(使用eisvogel模板)

Markdown的使用经常需要转变其他格式&#xff0c;在VSCode里有个很好用的插件&#xff1a;vscode-pandoc&#xff0c;先进行下载。 打开设置&#xff08;左下角的小齿轮&#xff09; 输入pandoc 在HTML Opt String中粘贴入&#xff1a; -s -t html5可将Markdown转换输出HTML。…

STL-----map的常见使用

1&#xff0c;MAP的说明Map是STL的一个关联容器&#xff0c;它提供一对一&#xff08;其中第一个可以称为关键字&#xff0c;每个关键字只能在map中出现一次&#xff0c;第二个可能称为该关键字的值&#xff09;的数据 处理能力&#xff0c;由于这个特性&#xff0c;它完成有可…

3.1.8 多态

文章目录1.概念2.特点3.入门案例练习4 多态的好处5 多态的使用6 练习&#xff1a;多态成员使用测试7 拓展7.1 综合案例7.2 多态为了统一调用标准7.3 静态变量和实例变量的区别7.4 向上转型和向下转型1.概念 多态是面向对象程序设计&#xff08;OOP&#xff09;的一个重要特征&…

【数据结构初阶】第三篇——单链表

链表的概念及其结构 初始化链表 打印单链表 增加结点 头插 尾插 在给定位置之前插入 在给定位置之后插入 删除结点 头删 尾删 删除给定位置的结点 查找数据 修改数据 链表的概念及其结构 基本概念 链表是一种物理存储结构上非连续&#xff0c;非顺序的存储结构&a…

盘点保护隐私安全的浏览器,密码锁屏这个功能,真香

在互联网时代&#xff0c;大家都比较关心自己的隐私安全。一些互联网公司和在线客服会跟踪用户的在线活动&#xff0c;收集用户的个人信息&#xff0c;有时候甚至因为个人的不良习惯导致信息泄露&#xff0c;因此选择隐私和安全性好的浏览器尤其重要。下面给大家介绍隐私安全做…

大数据技术架构(组件)11——Hive:日期函数

1.4.5、日期函数1.4.5.1、from_unixtimeselect from_unixtime(1638602968),from_unixtime(1638602968,yyyy-MM-dd HH:mm:SS),from_unixtime(1638602968,yyyy-MM-dd);1.4.5.2、unix_timestampselect unix_timestamp();1.4.5.3、to_dateselect to_date(2021-12-04 2021-12-04 15:…

【授权与认证】OAuth 2.0 和 OIDC 的异同点

开发者谈 | OAuth 2.0 和 OIDC 协议的关系&#xff1f;&#xff08;内含必看案例&#xff09; 【Web 安全】CSRF 攻击详解 OAuth 2.0 OAuth 2.0 的一个简单解释OAuth 2.0 的四种方式什么是Oauth2.0&#xff0c;Oauth2.0的四种授权模式 简单说&#xff0c;OAuth 就是一种授权…

【前端】Vue项目:旅游App-(16)home+hooks:窗口滚动到底部动态加载新数据、抽取到hook

文章目录目标过程与代码监听窗口的滚动窗口上事件监听的移除封装到一个hook回调函数法&#xff08;不推荐&#xff09;返回值法&#xff08;推荐&#xff09;效果总代码修改或添加的文件hooks的useScrollhome-content参考本项目博客总结&#xff1a;【前端】Vue项目&#xff1a…

git 使用tag

文章目录概述示例创建标签 tag查看tag删除本地标签推送标签git 根据tag创建分支回退到tag参考概述 常常为发布上线某个版本打上一个标签&#xff0c;表示这是什么版本&#xff0c;这样后续找起来就很方便。 如果没有标签只能通过commit历史去查找&#xff0c;而且commit版本显…

每日学术速递1.30

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 更多Ai资讯&#xff1a; 今天带来的arXiv上最新发表的3篇文本图像的生成论文。 Subjects: cs.LG、cs.Cv、cs.AI、cs.CL 1.StyleGAN-T: Unlocking the Power of GANs for Fast Large-Scale Text-to-Im…

Spire.Doc for Java v11.1.1 Patch

Spire.Doc for Java是一个专业的 Word API&#xff0c;它使 Java 应用程序能够在不依赖 Microsoft Word 的情况下创建、转换、操作和打印 Word文档。 通过使用这个多功能库&#xff0c;开发人员能够毫不费力地处理大量任务&#xff0c;例如插入图像、超链接、 数字签名、书签和…

Mybatis-plus(下)

一&#xff0c;乐观锁可参考官方文档&#xff1a;https://baomidou.com/pages/0d93c0/场景&#xff1a;当两个工作人员同时去处理一条投诉工单的时候当两个人一起点开了投诉工单详情 并一起编辑处理 随后同时反馈给用户时 此时就会出现矛盾 当系统正常 没有bug的时候 是会出现两…

SpringCloud_Sleuth分布式链路请求跟踪

目录一、概述1.为什么会出现这个技术&#xff1f;需要解决哪些问题&#xff1f;2.是什么3.解决二、搭建链路监控步骤1.zipkin2.服务提供者3.服务消费者&#xff08;调用方&#xff09;4.依次启动eureka7001/8001/805.打开浏览器访问&#xff1a; http://localhost:9411一、概述…

网络流量监控对DMS系统排错分析案例

背景 DMS系统是某汽车集团的经销商在线系统&#xff0c;是汽车集团的重要业务系统。本次分析重点针对DMS系统性能进行分析&#xff0c;以供安全取证、性能分析、网络质量监测以及深层网络分析。 该汽车总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和…

Qt扫盲-QDebug理论总结

QDebug理论使用总结一、概述二、使用1. 基础使用2. 格式化选项3.将自定义类型写入流一、概述 每当开发人员需要将调试或跟踪信息写入设备、文件、字符串或控制台时&#xff0c;都会使用QDebug。这个就可以方便我们调试&#xff0c;基本上Qt所有的内容都能通过调试打印出来&…

14.重载运算与类型转换

文章目录重载运算与类型转换14.1基本概念直接调用一个重载的运算符函数某些运算符不应该被重载使用与内置类型一致的含义赋值和复合赋值运算符选择作为成员或者非成员14.2输入和输出运算符14.2.1重载输出运算符<<输出运算符尽量减少格式化操作输入输出运算符必须是非成员…