Je suis devenu un peu confus quant aux détails du fonctionnement du compilateur JIT. Je sais que C # compile jusqu'à IL. La première fois qu'il est exécuté, c'est JIT'd. Cela implique-t-il d'être traduit en code natif? Le runtime .NET (en tant que machine virtuelle?) Interagit-il avec le code JIT? Je sais que c'est naïf, mais je me suis vraiment perdu. Mon impression a toujours été que les assemblys ne sont pas interprétés par .NET Runtime mais je ne comprends pas les détails de l'interaction.
Oui, JIT'ing code IL implique la traduction de l'IL en instructions machine natives.
Oui, le runtime .NET interagit avec le code machine natif de JIT, en ce sens que le runtime possède les blocs de mémoire occupés par le code machine natif, les appels du runtime au code machine natif, etc.
Vous avez raison de dire que le runtime .NET n'interprète pas le code IL dans vos assemblys.
Que se passe-t-il lorsque l'exécution atteint une fonction ou un bloc de code (comme une clause else d'un bloc if) qui n'a pas encore été compilé JIT en code machine natif, le JIT'r est appelé pour compiler ce bloc d'IL en code machine natif . Lorsque cela est fait, l'exécution du programme entre le code machine fraîchement émis pour exécuter sa logique de programme. Si, lors de l'exécution de ce code machine natif, l'exécution atteint un appel de fonction à une fonction qui n'a pas encore été compilée en code machine, le JIT'r est appelé pour compiler that function "just in time". Etc.
JIT'r ne compile pas nécessairement toute la logique d'un corps de fonction en un code machine à la fois. Si la fonction a des instructions if, les blocs d'instructions des clauses if ou else peuvent ne pas être compilés JIT jusqu'à ce que l'exécution passe réellement par ce bloc. Les chemins de code qui n'ont pas été exécutés restent sous forme IL jusqu'à leur exécution.
Le code machine natif compilé est conservé en mémoire pour pouvoir être réutilisé lors de la prochaine exécution de la section de code. La deuxième fois que vous appelez une fonction, celle-ci sera plus rapide que la première fois, car aucune étape JIT n’est nécessaire la seconde fois.
Dans desktop .NET, le code machine natif est conservé en mémoire pendant toute la durée de vie du domaine d'application. Dans .NET CF, le code machine natif peut être jeté si l'application manque de mémoire. Il sera à nouveau compilé à partir du code IL original lors de la prochaine exécution.
Le code est "compilé" dans le langage Microsoft Intermediate Language, qui est similaire au format Assembly.
Lorsque vous double-cliquez sur un exécutable, Windows charge mscoree.dll
, qui configure ensuite l'environnement CLR et lance le code de votre programme. Le compilateur JIT commence à lire le code MSIL dans votre programme et le compile de manière dynamique en instructions x86, que le processeur peut exécuter.
.NET utilise un langage intermédiaire appelé MSIL, parfois abrégé en IL. Le compilateur lit votre code source et produit MSIL. Lorsque vous exécutez le programme, le compilateur .NET Just In Time (JIT) lit votre code MSIL et génère une application exécutable en mémoire. Cela ne se produira pas, mais c'est une bonne idée de savoir ce qui se passe dans les coulisses.
.NET Framework utilise l'environnement CLR pour produire le langage MSIL (Microsoft Intermediate Language), également appelé IL. Le compilateur lit votre code source et lorsque vous construisez/compilez votre projet, il génère MSIL. Maintenant, lorsque vous exécutez enfin votre projet, le .NET JIT ( Compilateur Just-in-Time ) entre en action . JIT lit votre code MSIL et produit le code natif (instructions x86). qui peut être facilement exécuté par la CPU.JIT lit toutes les instructions MSIL et les exécute ligne par ligne.
Si vous êtes intéressé à voir ce qui se passe dans les coulisses, il a déjà été répondu. S'il vous plaît suivre - ici