Message-ID: <> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_3764_283482168.1495502306996" ------=_Part_3764_283482168.1495502306996 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html PrintAssembly


Puzzled by a performance glitch? You might have to look at the gene= rated code.

Examining generated code

The following HotSpot options (with an -XX: prefix on the command line) = require OpenJDK 7 and an externally loadable disassembler plugin:

These flags are "diagnostic", meaning that they must be preced= ed by -XX:+UnlockDiagnosticVMOptions. On the command line, the= y must all be preceded by -XX:. They may also be placed in a f= lags file, .hotspotrc by default, or configurable as -XX= :Flags=3Dmyhotspotrc.txt.

The disassembly output is annotated with various kinds of debugging info= rmation, such as field names and source locations. The quality of this info= rmation improved markedly in January 2010 (bug fix 6912062).


0x0188272f: mov=09ecx, [ecx+0x1A8B8B30]  ;   {oop(cache [42] fo=
r constant pool [234]/invokedynamic for 'SumWithIndy' cache=3D0x1a8b8b30)}
  0x01882735: mov=09edx, [ecx+0x10]
  0x01882738: cmp=09edx, a 'sun/dyn/ToGeneric$A2'
                                        ;   {oop(a 'sun/dyn/ToGeneric$A2')}
  0x0188273e: jnz=090x018827c1      ;*invokedynamic
                                        ; - SumWithIndy::test@17 (line 90)
  0x01882744: mov=09edi, 0x00000150
  0x01882749: mov=09edx, [edi+0x1A8B9110]  ;*getstatic cache
                                        ; - java.lang.Integer::valueOf@35 (=
line 651)
                                        ; - sun.dyn.ToGeneric$A2::targetA2@=
3 (line 663)
                                        ; - sun.dyn.ToGeneric$A2::invoke_L@=
4 (line 672)
                                        ; - java.dyn.InvokeDynamic::invokeE=
                                        ; - SumWithIndy::test@17 (line 90)
                                        ;   {oop('java/lang/Integer$Integer=

Complete file: samp= le-disassembly.txt

Plugin Implementations

There are 2 implementations around:

OpenJDK sources (defines th= e plugin API)

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

Look at the README for instructions on building.

With recent binutils version (i.e. binutils-2.23.2) you may get the foll= owing build error:

WARNING: `makeinfo' is missing on your system.  You should only n=
eed it if
         you modifie= d a `.texi' or `.texinfo' file, or any other file

This is because of "Bug&nb= sp;15345 - [2.23.2 regression] binutils-2.23.2 tar= ball doesn't build without makeinfo". The simplest workaround i= s to touch 'bfd/doc/' in the biuntils source di= rectory.

Pre-built binaries do not seem to be available (help... anyone?). Prebuilt binaries for Windows-x86: = hsdis-i386.dll

Kenai project base-hsdis

This is a from-scratch implementation which uses code from the Bastard project at SourceForge. The copyrights on this code = are non-restrictive.

The Kenai project offers binary downloads.<= /p>

Installing the Plugin

Once you succeed in building or downloading the hsdis binar= y library (in the following named DLL), you have to install it next to your= (jvm.dll on Windows), in the same folder. (Alternatively, you ca= n put it anywhere on your LD_LIBRARY_PATH.) The DLL must be gi= ven the name that the JVM will be looking for. The core of the name will be= hsdis-i386 for 32-bit Intel JVMs. Other names in use are hsdis-amd64, hsdis-sparc, and hsdis-sparcv9. A prefix and/or suffix will be required, according to system-dependent= rules for naming DLLs.

installing the plugin on Solaris
$ JDK7=3Dmy/copy/of/jre1.7.0
$ cp -p hsdis/.libs/ $JDK7/lib/i386/client/
$ cp -p hsdis/.libs/ $JDK7/lib/i386/server/
$ XJAVA=3D"$JDK7/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAss=
$ $XJAVA -Xcomp -cp ~/Classes hello
$ $XJAVA -Xcomp -cp ~/Classes -XX:PrintAssemblyOptions=3Dhsdis-print-bytes =
$ $XJAVA -XX:-PrintAssembly -XX:+PrintStubCode
$ $XJAVA -XX:-PrintAssembly -XX:+PrintInterpreter
$ $XJAVA -XX:-PrintAssembly -XX:+PrintSignatureHandlers
$ $XJAVA -Xbatch -cp ~/Classes -XX:+PrintCompilation myloopingbenchmark

The last line (with myloopingbenchmark) is most typical, si= nce it uses the batch execution mode common with benchmarks. The -XX:= +PrintCompilation flag will let you know which (if any) methods are = being compiled.

Filtering Output

The -XX:+PrintAssembly option prints everything. If that's = too much, drop it and use one of the following options.

Individual methods may be printed:

  • CompileCommand=3Dprint,*MyClass.myMethod prints assembly f= or just one method
  • CompileCommand=3Doption,*MyClass.myMethod,PrintOptoAssembly (debug build only) produces the old print command output
  • CompileCommand=3Doption,*MyClass.myMethod,PrintNMethods pr= oduces method dumps

These options accumulate.

If you get no output, use -XX:+PrintCompilation to verify t= hat your method is getting compiled at all.

Reading the compiler's mi= nd

The -XX:+LogCompilation flag produces a low-level XML file = about compiler and runtime decisions, which may be interesting to some. The= -XX:+UnlockDiagnosticVMOptions must come first. The dump is t= o hotspot.log in the current directory; use -XX:LogFile= =3Dfoo.log to change this.

The LogCompilation output is basic line-oriented XML. It ca= n usefully be read in a text editor, and there are also tools for parsing a= nd scanning it.