Sí, el código IL de JIT implica traducir el IL en instrucciones nativas de la máquina.
Sí, el tiempo de ejecución de .NET interactúa con el código de máquina nativo editado por JIT, en el sentido de que el tiempo de ejecución es propietario de los bloques de memoria ocupados por el código de máquina nativo, el tiempo de ejecución llama al código de máquina nativo, etc.
Tiene razón en que el tiempo de ejecución de .NET no interpreta el código IL en sus ensamblados.
Lo que sucede es que cuando la ejecución alcanza una función o un bloque de código (como una cláusula else de un bloque if) que aún no ha sido compilado con JIT en código de máquina nativo, se invoca el JIT'r para compilar ese bloque de IL en código de máquina nativo. . Una vez hecho esto, la ejecución del programa ingresa el código de máquina recién emitido para ejecutar la lógica del programa. Si mientras se ejecuta esa ejecución de código de máquina nativo llega una llamada de función a una función que aún no ha sido compilada en código de máquina, se invoca el JIT'r para compilar esa función "justo a tiempo". Y así.
El JIT'r no necesariamente compila toda la lógica del cuerpo de una función en código de máquina a la vez. Si la función tiene sentencias if, es posible que los bloques de sentencias de las cláusulas if o else no se compilen con JIT hasta que la ejecución pase a través de ese bloque. Las rutas de código que no se han ejecutado permanecen en forma IL hasta que se ejecutan.
El código de máquina nativo compilado se mantiene en la memoria para que pueda volver a utilizarse la próxima vez que se ejecute esa sección de código. La segunda vez que llame a una función, se ejecutará más rápido que la primera vez que la llame porque no es necesario ningún paso JIT la segunda vez.
En .NET de escritorio, el código de máquina nativo se mantiene en la memoria durante la vida útil del dominio de la aplicación. En .NET CF, el código de máquina nativo puede desecharse si la aplicación se está quedando sin memoria. Se volverá a compilar JIT a partir del código IL original la próxima vez que la ejecución pase por ese código.
El código se "compila" en el lenguaje intermedio de Microsoft, que es similar al formato ensamblador.
Cuando hace doble clic en un ejecutable, Windows carga,
mscoree.dll
que luego configura el entorno CLR e inicia el código de su programa. El compilador JIT comienza a leer el código MSIL en su programa y compila dinámicamente el código en instrucciones x86, que la CPU puede ejecutar.fuente
.NET usa un lenguaje intermedio llamado MSIL, a veces abreviado como IL. El compilador lee su código fuente y produce MSIL. Cuando ejecuta el programa, el compilador .NET Just In Time (JIT) lee su código MSIL y genera una aplicación ejecutable en la memoria. No verá nada de esto suceder, pero es una buena idea saber qué está pasando detrás de escena.
fuente
Describiré la compilación del código IL en instrucciones nativas de CPU a través del ejemplo siguiente.
public class Example { static void Main() { Console.WriteLine("Hey IL!!!"); } }
Principalmente CLR conoce todos los detalles sobre el tipo y qué método se llama desde ese tipo, esto se debe a los metadatos.
Cuando CLR comienza a ejecutar IL en una instrucción de CPU nativa, ese tiempo CLR asigna estructuras de datos internas para cada tipo al que hace referencia el código de Main.
En nuestro caso, solo tenemos un tipo de consola, por lo que CLR asignará una estructura de datos interna a través de esa estructura interna, administraremos el acceso a los tipos referenciados.
dentro de esa estructura de datos, CLR tiene entradas sobre todos los métodos definidos por ese tipo. Cada entrada contiene la dirección donde se puede encontrar la implementación del método.
Al inicializar esta conjuntos estructura CLR cada entrada de indocumentado FUNCIÓN contenido dentro de CLR itself.And como se puede adivinar esta FUNCIÓN es lo que llamamos JIT Compiler.
En general, podría considerar el compilador JIT como una función CLR que compila IL en instrucciones nativas de la CPU. Permítanme mostrarles en detalle cómo será este proceso en nuestro ejemplo.
1.Cuando Main hace su primera llamada a WriteLine, se llama a la función JITCompiler.
2. La función del compilador JIT sabe qué método se está llamando y qué tipo define este método.
Luego, Jit Compiler busca el ensamblado donde se definió ese tipo y obtiene el código IL para el método definido por ese tipo en nuestro caso, el código IL del método WriteLine.
El compilador JIT asigna el bloque de memoria DYNAMIC , después de que JIT verifique y compile el código IL en el código de la CPU nativo y guarde ese código de la CPU en ese bloque de memoria.
Luego, el compilador JIT vuelve a la entrada de la estructura de datos interna y reemplaza la dirección (que principalmente hace referencia a la implementación del código IL de WriteLine) con la dirección del nuevo bloque de memoria creado dinámicamente que contiene instrucciones nativas de CPU de WriteLine.
6. Finalmente, la función del compilador JIT salta al código en el bloque de memoria. Este código es la implementación del método WriteLine.
7.Después de la implementación de WriteLine, el código regresa al código de la red principal, que continúa la ejecución con normalidad.
fuente
.NET Framework utiliza CLR Environment para producir MSIL (Microsoft Intermediate Language), también llamado IL. El compilador lee tu código fuente y cuando construyes / compilas tu proyecto, genera MSIL. Ahora, cuando finalmente ejecute su proyecto, el .NET JIT ( compilador Just-in-time ) entra en acción. JIT lee su código MSIL y produce código nativo (que son instrucciones x86) que puede ser ejecutado fácilmente por la CPU. JIT lee todas las instrucciones MSIL y las ejecuta línea por línea.
Si está interesado en ver qué sucede detrás de escena, ya ha sido respondido. Por favor siga - Aquí
fuente