17 апр. 2010 г.

java: How to get PrintAssembly

Thanks to Roman Yaroslavtsev who gave me a link to an article Memory Barriers and JVM Concurrency.

First of all this article is useful to gain a better understanding of Java Memory Model - another great thing that I discover is ability to look inside of assembly code generated by jit.

Refer to load-test-tool usage I going to use that simple example:
public class ArrayIterationTest {

private final int[] data;

public ArrayIterationTest(final int size) {
this.data = new int[size];
}

public void doTest() {
for ( int i = 0; i < data.length; i++ ){
int j = data[i];
}
}

public static final void main(String[] args){
final long t0 = System.nanoTime();
ArrayIterationTest t = new ArrayIterationTest(1000000);
t.doTest();
System.out.println((System.nanoTime() - t0) / 1000 / 1e3);
}
}


Let's start it (user's jvm is sun jdk 1.6.0_20):
java -XX:+UnlockDiagnosticVMOptions
-XX:+PrintAssembly -XX:PrintAssemblyOptions=hsdis-print-bytes
-XX:CompileCommand=print,ArrayIterationTest
ArrayIterationTest
and have got
CompilerOracle: print ArrayIterationTest
Could not load hsdis-i386.so; library not loadable; PrintAssembly is disabled
14.029

So...

Dude, where's my hsdis-i386.so ?

There is no hsdis-i386.so in dev-java/sun-jdk-1.6.0.20, nor in dev-java/sun-jdk-1.7.0.0_alpha89 or in dev-java/icedtea6-bin-1.8.0

Let's fetch openjdk plugin implementation
hg clone http://hg.openjdk.java.net/jdk7/hotspot/hotspot/src/share/tools/hsdis/ openjdk-hotspot
and build it using hsdis's README

This version of the plugin requires the Gnu disassembler, which is available separately as part of the binutils project.

cd openjdk-hotspot/src/share/tools/hsdis/
mkdir build && cd build
wget http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.bz2
tar jxf binutils-2.20.1.tar.bz2 && mv binutils-2.20.1 binutils && cd ..
make

and start again it now:
LD_LIBRARY_PATH=openjdk-hotspot/src/share/tools/hsdis/build/linux-i586/:$LD_LIBRARY_PATH
java -XX:+UnlockDiagnosticVMOptions
-XX:+PrintAssembly -XX:PrintAssemblyOptions=hsdis-print-bytes
-XX:CompileCommand=print,ArrayIterationTest
ArrayIterationTest


Note: use your own path to hsdis-arch.so in LD_LIBRARY_PATH .

And you've got something like this for your platform:
CompilerOracle: print ArrayIterationTest
Loaded disassembler from hsdis-i386.so
Decoding compiled method 0xb3bb5c48:
Code:
[Disassembling for mach='i386']
[Entry Point]
[Verified Entry Point]
0xb3bb5d20: call 0xb7168b60 ;...e83b2e5b 03
; {runtime_call}
0xb3bb5d25: xchg %ax,%ax ;...666690
...


ps. for further information please refer to PrintAssembly at wikis.sun.com as well as for prebuild hsdis-i386.dll

2 комментария:

Denis Bazhenov комментирует...

Thanks a lot. I didn't know that there is possibility to see the assembly code. Sad to see that this feature is not provided by sun jdk itself.

Владимир Долженко комментирует...

This is plugin externally loadable disassembler plugin for jdk. It's specific to hotspot vm, and probably openjdk final build will include it.