software que programa parte ejemplos compilar compilador compilacion capas java assembly jvm jit
hsdis-i386.dllhsdis-amd64.dll

java - que - ¿Cómo ver el código compilado JIT en JVM?



jit software (7)

Uso general

Como se explica en otras respuestas, puede ejecutar con las siguientes opciones de JVM:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

Filtrar en un método específico

También puede filtrar en un método específico con la siguiente sintaxis:

-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod

Notas:

  • es posible que deba colocar el segundo argumento entre comillas, según el sistema operativo, etc.
  • si el método se inserta, puede perder algunas optimizaciones

Cómo: Instalar las bibliotecas necesarias en Windows

Si está ejecutando Windows, esta página tiene instrucciones sobre cómo construir e instalar hsdis-amd64.dll y hsdis-i386.dll que son necesarios para que funcione. Copiamos a continuación y ampliamos el contenido de esa página * como referencia:

Dónde obtener binarios preconstruidos

Puede descargar binarios fcml para Windows desde el proyecto fcml

Cómo construir hsdis-amd64.dll y hsdis-i386.dll en Windows

Esta versión de la guía se preparó en Windows 8.1 de 64 bits utilizando Cygwin de 64 bits y produciendo hsdis-amd64.dll

  1. Instala Cygwin . En la pantalla Select Packages , agregue los siguientes paquetes (expandiendo la categoría Devel , luego haciendo clic una vez en la etiqueta Skip lado de cada nombre de paquete):

    • make
    • mingw64-x86_64-gcc-core (solo necesario para hsdis-amd64.dll )
    • mingw64-i686-gcc-core (solo necesario para hsdis-i386.dll )
    • diffutils (en la categoría diffutils )
  2. Ejecute la Terminal Cygwin. Esto se puede hacer usando el ícono de escritorio o menú de inicio creado por el instalador, y creará su directorio de inicio de Cygwin ( C:/cygwin/home/<username>/ o C:/cygwin64/home/<username>/ de forma predeterminada) .

  3. Descargue el último paquete fuente de binutils de GNU y extraiga su contenido en el directorio de inicio de Cygwin. En el momento de escribir, el último paquete es binutils-2.25.tar.bz2 . Esto debería dar como resultado un directorio llamado binutils-2.25 (o cualquiera que sea la última versión) en su directorio de inicio de Cygwin.
  4. Descargue la fuente de OpenJDK yendo al repositorio de actualizaciones de JDK 8 , seleccionando la etiqueta correspondiente a su versión de JRE instalada y haciendo clic en bz2. Extraiga el directorio hsdis (que se encuentra en src/share/tools ) en su directorio de inicio de Cygwin.
  5. En la Terminal Cygwin, ingrese cd ~/hsdis .
  6. Para construir hsdis-amd64.dll , ingrese

    make OS=Linux MINGW=x86_64-w64-mingw32 ''AR=$(MINGW)-ar'' BINUTILS=~/binutils-2.25

    Para construir hsdis-i386.dll , ingrese

    make OS=Linux MINGW=i686-w64-mingw32 ''AR=$(MINGW)-ar'' BINUTILS=~/binutils-2.25

    En cualquier caso, reemplace 2.25 con la versión binutils que descargó. OS=Linux es necesario porque, aunque Cygwin es un entorno similar a Linux, el archivo make hsdis no lo reconoce como tal.

  7. La compilación fallará con los mensajes ./chew: No such file or directory y gcc: command not found . Edite <Cygwin home directory>/hsdis/build/Linux-amd64/bfd/Makefile en un editor de texto como Wordpad o Notepad ++ para cambiar SUBDIRS = doc po (línea 342, si usa binutils 2.25) a SUBDIRS = po . Vuelve a ejecutar el comando anterior.

La DLL ahora se puede instalar copiándola de hsdis/build/Linux-amd64 o hsdis/build/Linux-i586 en el directorio bin/server o bin/client su JRE. Puede encontrar todos esos directorios en su sistema buscando java.dll .

Consejo de bonificación: si prefiere la sintaxis de Intel ASM a AT & T, especifique -XX:PrintAssemblyOptions=intel junto con cualquier otra opción de PrintAssembly que utilice.

* la licencia de página es Creative Commons

¿Hay alguna forma de ver el código nativo producido por el JIT en una JVM?


Creo que WinDbg sería útil si lo está ejecutando en la máquina de Windows. Acabo de ejecutar un frasco.

  • Luego me uní al proceso de Java a través de Windbg
  • Hilos examinados por ~ comando; Hubo 11 hilos, 0 thread was main worker thread
  • Cambiado a 0-thread - ~ 0s
  • Miró a través de callstack no dañado por kb había:

    0008fba8 7c90e9c0 ntdll! KiFastSystemCallRet
    0008fbac 7c8025cb ntdll! ZwWaitForSingleObject + 0xc
    0008fc10 7c802532 kernel32! WaitForSingleObjectEx + 0xa8
    0008fc24 00403a13 kernel32! WaitForSingleObject + 0x12
    0008fc40 00402f68 java + 0x3a13
    0008fee4 004087b8 java + 0x2f68
    0008ffc0 7c816fd7 java + 0x87b8
    0008fff0 00000000 kernel32! BaseProcessStart + 0x23

Las líneas resaltadas son código JIT-ed de ejecución directa en JVM.

  • Entonces podemos buscar la dirección del método:
    java + 0x2f68 es 00402f68

  • En WinDBG:
    Haga clic en Ver -> Desensamblar.
    Haga clic en Editar -> Ir a dirección.
    Ponga 00402f68 allí
    y consiguió

    00402f68 55 push ebp
    00402f69 8bec mov ebp, esp
    00402f6b 81ec80020000 sub esp, 280h
    00402f71 53 push ebx
    00402f72 56 push esi
    00402f73 57 push edi
    ... y así sucesivamente

Para obtener información adicional, aquí está el Example cómo rastrear el código JIT-ed desde los volcados de memoria utilizando Process Explorer y WinDbg.


Imprima el ensamblaje de sus puntos de acceso con los perfiladores de perfil de JMH ( LinuxPerfAsmProfiler o WinPerfAsmProfiler ). JMH requiere la biblioteca hsdis ya que depende de PrintAssembly .


Necesita un complemento hsdis para usar PrintAssembly . Una opción conveniente es el complemento hsdis basado en la biblioteca FCML.

Se puede compilar para sistemas de tipo UNIX y en Windows puede usar bibliotecas pre compiladas disponibles en la sección de download FCML en Sourceforge:

Para instalar en Windows:

  • Extraiga el dll (se puede encontrar en hsdis-1.1.2-win32-i386.zip y hsdis-1.1.2-win32-amd64.zip).
  • Copie el java.dll a donde exista java.dll (use la búsqueda de Windows). En mi sistema, lo encontré en dos lugares:
    • C:/Program Files/Java/jre1.8.0_45/bin/server
    • C:/Program Files/Java/jdk1.8.0_45/jre/bin/server

Para instalar en Linux:

  • Descargue el código fuente, extráigalo
  • cd <source code dir>
  • ./configure && make && sudo make install
  • cd example/hsdis && make && sudo make install
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.so
  • sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so
  • En mi sistema, el JDK está en /usr/lib/jvm/java-8-oracle

Cómo ejecutarlo:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code -jar fcml-test.jar

Parámetros de configuración adicionales:

código Imprimir código máquina antes de la mnemotécnica.
Intel Usa la sintaxis Intel.
gas Utilice la sintaxis del ensamblador de AT & T (compatible con ensamblador GNU).
dec Imprime el IMM y el desplazamiento como valores decimales.
mpad = XX Relleno para la parte mnemónica de la instrucción.
cpad = XX Relleno para el código de máquina.
seg Muestra los registros de segmentos predeterminados.
ceros Muestra los ceros iniciales en el caso de los literales HEX.

La sintaxis de Intel es una predeterminada en el caso de Windows, mientras que la de AT & T es la predeterminada para GNU / Linux.

Para más detalles, consulte el Manual de referencia de la biblioteca FCML.


Otra forma de ver el código de la máquina y algunos datos de rendimiento es usar CodeAnalyst u OProfile de AMD, que tienen un complemento de Java para visualizar la ejecución del código de Java como código de máquina.



Suponiendo que está utilizando la JVM de Sun Hotspot (es decir, la que proporciona Oracle en java.com ), puede agregar la java.com

-XX: + PrintOptoAssembly

cuando ejecutas tu código Esto imprimirá el código optimizado generado por el compilador JIT y omite el resto.

Si desea ver el bytecode completo, incluidas las partes no optimizadas, agregue

-XX: CompileThreshold = #

cuando estás ejecutando tu código

Puede leer más sobre este comando y la funcionalidad de JIT en general here .