2011-05-13 13 views
13

He escrito una aplicación Brainfuck (C++) que funciona de esta manera:Hacer un compilador JIT

  1. Leer archivo brainfuck entrada
  2. hacer optimizaciones triviales brainfuck
  3. Convertir a código de máquina para la máquina virtual
  4. ejecutar este código de máquina en la VM

esto es bastante rápido, pero el cuello de botella se encuentra ahora en la máquina virtual. Está escrito en C++ y lee un token, ejecuta una acción (que no son muchos en absoluto, si conoces Brainfuck) y así sucesivamente.

Lo que quiero hacer es quitar la VM y generar código de máquina nativo sobre la marcha (tan básicamente, un compilador JIT). Esto puede ser fácilmente una aceleración de 20x.

Esto significa que el paso 3 se reemplaza por un compilador JIT y el paso 4 con la ejecución del código máquina generado.

no sé realmente por dónde empezar, así que tengo un par de preguntas:

  1. ¿Cómo funciona esto, ¿cómo el código de máquina generado se ejecutan?
  2. ¿Hay alguna biblioteca C++ para generar código máquina nativo?

Respuesta

15
  1. código de máquina generado es simplemente jmp -ed o call -ed como función habitual. A veces también era necesario desactivar el indicador de no ejecución (bit NX) en la memoria, que contenía el código generado. En Linux, esto se hace con mprotect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC.) En Windows, el NX se llama DEP.

  2. Hay algunos ... E.g. http://www.gnu.org/software/lightning/ - GNU Lightning (universal) y https://developer.mozilla.org/En/Nanojit - Nanojit, que se utiliza en los motores JavaScript JIT de Firefox. El JIT más potente y moderno es LLVM, solo necesitas traducir el código BF a LLVM IR, y luego LLVM puede hacer optimizaciones y generación de código para muchas plataformas, o ejecutar LLVM IR en intérprete (máquina virtual) con capacidades JIT. Hay un post sobre BF & LLVM con total compilador LLVM JIT para BF http://www.remcobloemen.nl/2010/02/brainfuck-using-llvm/

Otra BF + compilador LLVM está aquí, en el SVN de LLVM: https://llvm.org/svn/llvm-project/llvm/trunk/examples/BrainF/BrainF.cpp

+1

+1 y aceptado para el único que explica cómo se llama el código de máquina. – orlp

3

GNU Lightning es un conjunto de macros que pueden generar código nativo para algunas arquitecturas diferentes. Necesitará una sólida comprensión del código ensamblador porque su paso 3 implicará el uso de macros Lightning para emitir código de máquina directamente en un búfer que luego ejecutará.

5

LLVM es una completa biblioteca de C++ (o conjunto de bibliotecas) para generar código nativo a partir de un formulario intermedio, completo con documentación y ejemplos, y que se ha utilizado para producir JITters.

(También tiene un compilador C/C++ que utiliza el marco; sin embargo, el marco mismo se puede usar para otros idiomas).

Cuestiones relacionadas