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

时间:2015-01-07 11:02:20

标签: java assembly jvm jit disassembly

我尝试使用此命令在Test类下面进行反汇编:

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


测试类

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);
    }
}

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

CompilerOracle: print *Test.main
Java HotSpot(TM) Client VM warning: printing of assembly code is enabled; turning on 
DebugNonSafepoints to gain additional output
loading Test

如果我通过添加somme虚拟代码修改我的main方法:

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

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

例如,我发现像这样的装配线:

0x026f1843: mov    $0x24655510,%edx   ;   {oop("azertyu")}

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

所以我不明白为什么我无法获得所有程序的汇编代码?

注意:我使用hsdis-i386.dll中链接的Oracle wiki about PrintAssembly

1 个答案:

答案 0 :(得分:2)

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

对于最初的程序来说,没有什么工作要做,所以没有编译,即一切只是解释。您在程序中执行的循环和内容越多,编译器就越多。

关于什么将被编译以及什么时候,几乎没有(没有?)保证。

你的“azertyu”组装的原因可能是因为它是“不变的”,优化器在运行for循环时发现了它。