Alex headshot

AlBlue’s Blog

Macs, Modularity and More

JavaOne 2016: HotSpot Under the Hood

2016, assembly, hotspot, hsdis, java, javaone, openjdk, presentation

CON3808 Under the Hood of the JVM: From Bytecode to Assembly

JavaOne I’ve just given a presentation at JavaOne 2016, entitled “HotSpot Under the Hood”. It’s a new version of the talk I gave for the DocklandsLJC earlier on this year.

Unfortunately the talk wasn’t recorded (ony a few of the rooms appear to have any video recording in them) but the video from the above DocklandsLJC talk has just been published on InfoQ. It’s mostly the same presentation as before, but the JavaOne version was formatted to widescreen and a few additional slides were added (hopefully self sufficient).

Seventh best sesion for Monday

The talk came 7th the “Best Session @ Conference” for Monday; out of over 100 talks that’s not too shabby for a JavaOne first timer!

I’ve uploaded the version of the presentation that I gave at JavaOne to my SpeakerDeck account, if you want to step through the slides individually. And if you’d like to hear the sound of my dulcet tones, I have recorded a narrated version of the presentation at Vimeo.

Building hsdis

You don’t actually need to clone the whole OpenJDK repository in order to be able to compile hsdis; you just need to be able to grab the files from the hotspot/src/share/tools/hsdis/ directory. Specifically, you need to download:

There’s also a README file, which is useful but not necessary.

To build, you’ll also need to download binutils and expand it to a directory build/binutils.

Or, you can just copy and paste the following into an appropriate directory:

Building HSDIS
1
2
3
4
5
6
curl -O -O -O -O https://raw.githubusercontent.com/dmlloyd/openjdk/jdk9/jdk9/hotspot/src/share/tools/hsdis/{hsdis.c,hsdis.h,Makefile,README}
mkdir -p build/binutils
curl http://ftp.gnu.org/gnu/binutils/binutils-2.27.tar.gz | tar --strip-components=1 -C build/binutils -z -x -f -
make both || make
# make both # for dual 32-bit and 64-bit platforms
# make      # for single-type platforms

This will download all the necessary files, run the build, and you’ll be left with a number of .dylib (for macOS) and corresponding .so and .dll for other platforms.

The macOS platform can support building and using both 32-bit and 64-bit binaries on the same platform; however, Linux platforms generally can’t handle both types.

Note that if you’re building on Windows with Mingw, you’ll need to replace the AR command with ${MINGW)-ar, in the same line that changes the CC variant for ${MINGW}-gcc. Ideally this should be fixed upstream but championing a fix is non trivial.

Command Options

The command options that I used in the talk were as follows:

  • -XX:+UnlockDiagnosticVMOptions – needed for the vast number of -XX:Print* flags
  • -XX:+PrintInterpreter – dump the template interpreter table
  • -XX:+PrintCompilation – show the compilation of methods as they occur, and what level they run as
  • -XX:+PrintAssembly – dump the assembly code for methods as they are compiled
  • -XX:+/-UseCompressedOops – turn on (or off) the ability to compress OOPs on a 64 bit JVM (defaults to on for less than 32G)
  • -XX:+/-UseCompressedClassPointers – turn on (or off) the compression of class pointers (defaults to on for 64 bit platforms)
  • -XX:ObjectAlignmentInBytes=8 – align objects on 8 byte boundary. Must be multiple of 2. Can use up to 64G if set to 16 but caution/testing required.
  • -XX:+/-TieredCompilation – defaults to on for Java 8 but off for Java 7

When you’re using OpenJDK flags, it’s sometimes a benefit to add -version to the end so you don’t get the help usage. For example, if you want to see what all the flags you can use -XX:+PrintFlagsFinal -version which will dump everything you can tweak (including what flags have been detected based on your VM configuration).