为什么反汇编插件在这种情况下不起作用?

Why the disassembler plugin doesn't work in this case?

我正在尝试使用以下命令反汇编测试 class:

java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Test.main Test > log.txt


测试class:

public class Test {
    static {
        System.out.println("loading Test");
    }
    public static void main(String[] args) {
        Aze a = new Aze(1,2,3);
        Baz b = new Baz();
    }

}

class Aze {
    private String toto ;
    private int titi ;
    private int tata ;

    public Aze(int a, int b, int c) {
        this.toto = "azertyu";
        this.titi = b;
        this.tata = c;
    }
}

class Baz extends Aze {        

    public Baz() {
        super(1,2,3);
    }
}

但结果不包含任何汇编代码:

编译器Oracle:打印*Test.main
Java HotSpot(TM) 客户端 VM 警告:已启用汇编代码打印;打开
DebugNonSafepoints 以获得额外的输出
加载测试

如果我通过添加一些虚拟代码来修改我的主要方法:

        long x = 0;
        for (int i = 0; i < 100000; i++) {
            x += i*i;
        }
        System.out.println("x=" + x);

它突然起作用了,我得到的输出不仅与添加的代码有关。

例如,我找到了这样的装配线:

0x026f1843: mov    [=2=]x24655510,%edx   ;   {oop("azertyu")}

现在,如果我使用以下方法稍微修改一下 for 循环:for (int i = 0; i < 10000; i++) 我只有结果行 x=333283335000 而根本没有汇编代码。

所以我不明白为什么我不能获取所有程序的汇编代码?

注:我用的是hsdis-i386.dll linked in Oracle wiki about PrintAssembly

只显示 "just-in-time-compiled" 代码,因为这是唯一的汇编代码,其余的是解释字节代码。

对于最初的程序,要做的工作太少以至于什么都没有编译,即一切都只是解释。您在程序中执行的循环和操作越多,编译成汇编程序的内容就越多。

很少(不是?)保证编译什么和什么时候编译。

你的 "azertyu" 被组装的原因可能是因为它是 "invariant",而优化器在 运行 for 循环时发现了这一点。