HotSpot
To build hotspot, get the sources, for example into /usr/src/hotspot
# To build a C2 compiler /usr/src/hotspot/build/linux$ make debug ALT_BOOTDIR=/usr/lib/jvm/java-6-sun # To build a C1 compiler /usr/src/hotspot/build/linux$ make debug1 ALT_BOOTDIR=/usr/lib/jvm/java-6-sun
To use the newly built hotspot, use the following hotspot.sh script.
#!/bin/sh build1=/usr/src/hotspot/build/linux/linux_i486_compiler1/debug build2=/usr/src/hotspot/build/linux/linux_i486_compiler2/debug build=$build1 export JAVA_HOME=/usr/lib/jvm/java-6-sun/ export LD_LIBRARY_PATH=$build exec $build/gamma $*
I didn't find a way to get a list of the interesting -XX options, you can get them using the following script (but probably it can be done easier):
#!/bin/sh
hotspot_dir="$1"
exe=/tmp/hotspot_options
if [ -z "$hotspot_dir" ]; then
echo Usage: $0 "<hotspot dir>" >&2
exit 1
fi
cpp <<- EOF | grep BLAH | sed 's/BAZ/\n/g;s/BLAH//g' | gcc -x c - -o ${exe}
#include "${hotspot_dir}/src/share/vm/runtime/globals.hpp"
#include "${hotspot_dir}/src/share/vm/c1/c1_globals.hpp"
#include "${hotspot_dir}/src/share/vm/opto/c2_globals.hpp"
#define foo4(a, b, c, d) BLAH printf("%s (%s)\n\t%s\n\n", #b, #a, d); BAZ
#define foo3(a, b, c) BLAH printf("%s (%s)\n\t%s\n\n", #b, #a, c); BAZ
#define a(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define b(aa, bb, cc) foo3(aa, bb, cc)
#define c(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define d(aa, bb, cc) foo3(aa, bb, cc)
#define e(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define f(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define g(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define h(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define i(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define j(aa, bb, cc) foo3(aa, bb, cc)
#define k(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define l(aa, bb, cc) foo3(aa, bb, cc)
#define m(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define n(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define o(aa, bb, cc) foo3(aa, bb, cc)
#define p(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define q(aa, bb, cc) foo3(aa, bb, cc)
#define r(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
#define s(aa, bb, cc, dd) foo4(aa, bb, cc, dd)
BLAH#include<stdio.h>
BLAH int main() {
BLAH printf("\n\n\n================== RUNTIME ==================\n\n\n");
RUNTIME_FLAGS(a, b, c, d, e, f, g, h)
BLAH printf("\n\n\n================== C1 ==================\n\n\n");
C1_FLAGS(i, j, k, l, m)
BLAH printf("\n\n\n================== C2 ==================\n\n\n");
C2_FLAGS(n, o, p, q, r, s)
BLAH }
EOF
${exe}
rm ${exe}
If you want to use an disassembler, you must provide one in a shared library disassembler.so. Here is a simple binutils based disassebler for x86:
Makefile :
HOTSPOT_HOME = /usr/src/hotspot
disassembler.so: disass.cc
g++ -I$(HOTSPOT_HOME) -fpic -shared -o $@ $< -lopcodes
disass.cc:
#include <dis-asm.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "src/share/vm/compiler/disassemblerEnv.hpp"
static void disass_printf(PTR p, const char *fmt, ...) {
char buf[512];
va_list ap;
va_start(ap, fmt);
buf[0] = '\0';
vsprintf(buf, fmt, ap);
((DisassemblerEnv *)p)->print_raw(buf);
va_end(ap);
}
static int disass_buffer_read_memory(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info)
{
memcpy(myaddr, (void *) (intptr_t) memaddr, length);
return 0;
}
extern "C" unsigned char *decode_instruction(unsigned char *code, DisassemblerEnv *env) {
static int initialized = 0;
static disassemble_info info;
if (!initialized) {
INIT_DISASSEMBLE_INFO(info, NULL, disass_printf);
info.mach = bfd_mach_i386_i386;
info.read_memory_func = &disass_buffer_read_memory;
initialized = 1;
}
info.stream = env;
return code + print_insn_i386((bfd_vma) (intptr_t) code, &info);
}