Brandt Bucher de Microsoft, membre de l'équipe des développeurs principaux de CPython et travaillant sur l'augmentation des performances de l'interpréteur CPython, a publié une implémentation d'un compilateur JIT pour Python, utilisant la technique Copy-and-Patch. La publication du JIT coïncide avec Noël et l'annonce est écrite en vers.
Le JIT proposĂ© se distingue par sa rapiditĂ© de gĂ©nĂ©ration de code, sa facilitĂ© de maintenance et son intĂ©gration complĂšte avec l'interprĂ©teur. La mĂ©thode proposĂ©e permet de transformer automatiquement un interprĂ©teur Ă©crit en C en compilateur JIT, sans avoir Ă Ă©laborer une logique de gĂ©nĂ©ration de code distincte et sans crĂ©er manuellement des reprĂ©sentations assembleur. Avec cette approche, la correction d'un bug dans l'interprĂ©teur entraĂźnera Ă©galement la rĂ©solution du mĂȘme problĂšme dans le JIT, car un gĂ©nĂ©rateur de code commun est utilisĂ©.
Le fonctionnement de la méthode Copy-and-Patch repose sur le fait que la relocation de code en mémoire lors du chargement par le linkeur d'objets et le remplacement des instructions machine au lieu du bytecode dans le JIT représentent des tùches similaires. Lors de l'exécution du JIT, le processus parcourt les instructions bytecode créées par l'interpréteur et copie, pour chaque instruction, un code machine préalablement compilé dans une zone mémoire avec du code exécutable, tout en modifiant à la volée les instructions pour substituer les données traitées (le JIT copie des modÚles de fonctions déjà compilées et les remplace par les valeurs nécessaires telles que les arguments et les constantes). Lors du chargement des fichiers objets, le code machine est également copié en mémoire et des symboles externes sont substitués.
Dans Copy-and-Patch JIT, un fichier objet au format ELF est gĂ©nĂ©rĂ© Ă l'aide de LLVM, contenant des donnĂ©es sur les instructions de bytecode et des informations nĂ©cessaires pour remplacer des donnĂ©es. JIT remplace les instructions de bytecode gĂ©nĂ©rĂ©es pendant l'interprĂ©tation du programme par des reprĂ©sentations en code machine, tout en substituant les donnĂ©es nĂ©cessaires aux calculs. La mise en Ćuvre de JIT nĂ©cessite LLVM comme dĂ©pendance au moment de la compilation, mais les composants au moment de l'exĂ©cution ne dĂ©pendent pas d'externalitĂ©s et se composent d'environ 300 lignes de code en C Ă©crites manuellement et de 3000 lignes de code en C gĂ©nĂ©rĂ©es.
ComparĂ© Ă l'outillage JIT traditionnel (LLVM -O0), le JIT proposĂ© assure une gĂ©nĂ©ration de code 100 fois plus rapide et un code rĂ©sultant 15% plus rapide. Par rapport Ă la compilation en WebAssembly (Liftoff), le nouveau JIT gĂ©nĂšre du code 5 fois plus rapidement, et le code rĂ©sultant fonctionne 50% plus rapidement. En comparaison avec le JIT optimisant (LuaJIT) utilisant du code assembleur Ă©crit manuellement, la nouvelle version s'est rĂ©vĂ©lĂ©e plus rapide dans 13 des 44 tests, avec un retard de performance moyen de 35%, tout en simplifiant beaucoup la maintenance et en rĂ©duisant le niveau de complexitĂ© de mise en Ćuvre.

Source : opennet.ru
