tipos que programa lenguaje funciona compilar compiladores compilador compilacion como capas interpreter jit .net-assembly

interpreter - programa - que es compilar



Técnicas de generación de código JIT (7)

Por lo que sé, compila todo en la memoria porque tiene que ejecutar algunas heurísticas para optimizar el código (es decir, en línea con el tiempo), pero puede echar un vistazo a la versión del rotor Shared Source Common Language Infrastructure 2.0 . Toda la base de código es idéntica a .NET, excepto la Jitter y la GC.

¿Cómo genera una máquina virtual un código máquina nativo sobre la marcha y lo ejecuta?

Suponiendo que pueda averiguar cuáles son los códigos de operación de la máquina nativa que desea emitir, ¿cómo se ejecuta en realidad?

¿Es algo tan raro como mapear las instrucciones mnemotécnicas a códigos binarios, rellenarlo en un puntero char * y convertirlo en una función y ejecución?

¿O generaría una biblioteca compartida temporal (.dll o .so o lo que sea) y la cargaría en la memoria utilizando funciones estándar como LoadLibrary ?


Simplemente puede hacer que el contador del programa apunte al código que desea ejecutar. Recuerde que los datos pueden ser datos o códigos. En x86, el contador del programa es el registro EIP. La parte IP de EIP significa puntero de instrucción. La instrucción JMP se llama para saltar a una dirección. Después del salto EIP contendrá esta dirección.

¿Es algo tan raro como mapear las instrucciones mnemotécnicas a códigos binarios, rellenarlo en un puntero char * y convertirlo en una función y ejecución?

Sí. Esta es una forma de hacerlo. El código resultante se convertiría en un puntero para funcionar en C.


¿Es algo tan raro como mapear las instrucciones mnemotécnicas a códigos binarios, rellenarlo en un puntero char * y convertirlo en una función y ejecución?

Sí, si lo hicieras en C o C ++ (o algo similar), eso es exactamente lo que harías.

Parece hacky, pero eso es en realidad un artefacto del diseño del lenguaje. Recuerde, el algoritmo real que desea utilizar es muy simple: determine qué instrucciones desea usar, cárguelos en un búfer en la memoria y salte al principio de ese búfer.

Sin embargo, si realmente intenta hacer esto, asegúrese de tener la convención de llamadas correcta cuando regrese a su programa C. Creo que si quisiera generar código buscaría una biblioteca para que se encargue de ese aspecto para mí. Nanojit ha estado en las noticias recientemente; podrías mirar eso.



Sip. Simplemente crea un char * y lo ejecuta. Sin embargo, debe tener en cuenta un par de detalles. El char * debe estar en una sección ejecutable de la memoria y debe tener una alineación adecuada.

Además de nanojit, también puede consultar LLVM, que es otra biblioteca que es capaz de compilar varias representaciones de programas hasta un puntero de función. Su interfaz está limpia y el código generado tiende a ser eficiente.


Acerca de generar una DLL: la E / S adicional requerida para eso, más el enlace, más la complejidad de generar el formato DLL, complicarían mucho más y, sobre todo, matarían el rendimiento; Además, al final todavía se llama un puntero a la función del código cargado, por lo que ... Además, la compilación de JIT puede ocurrir un método a la vez, y si quieres hacer eso generarías muchos archivos DLL pequeños.

Sobre el requisito de "sección ejecutable", llamar a mprotect () en los sistemas POSIX puede corregir los permisos (hay una API similar en Win32). Necesitarás hacer eso para un gran segmento de memoria en lugar de eso una vez por método, ya que de lo contrario sería demasiado lento.

En el x86 simple no notaría el problema, en x86 con máquinas PAE o 64bit AMD64 / Intel de 64 bits se obtendría un segfault.


¿Es algo tan raro como mapear las instrucciones mnemotécnicas a códigos binarios, rellenarlo en un puntero char * y convertirlo en una función y ejecución?

Sí, eso funciona

Para hacer esto en Windows, debe establecer PAGE_EXECUTE_READWRITE en el bloque asignado:

void (*MyFunc)() = (void (*)()) VirtualAlloc(NULL, sizeofblock, MEM_COMMIT, PAGE_EXECUTE_READWRITE); //Now fill up the block with executable code and issue- MyFunc();