Brandt Bucher van Microsoft, een van de kernontwikkelaars van CPython, die zich bezighoudt met het verbeteren van de prestaties van de CPython-interpreter, heeft een implementatie van een JIT-compiler voor Python gepresenteerd, gebruikmakend van de Copy-and-Patch-techniek. De publicatie van JIT is gepland rond Kerst en de aankondiging is in dichtvorm geschreven.
De voorgestelde JIT valt op door de zeer hoge snelheid van codegeneratie, de eenvoud van onderhoud en de volledige integratie met de interpreter. De voorgestelde methode maakt automatische omzetting mogelijk van de C-gebaseerde interpreter naar een JIT-compiler, zonder aparte codegeneratielogica of handmatige creatie van assemblyrepresentaties. Bij deze benadering zorgt het corrigeren van een fout in de interpreter automatisch ook voor het oplossen van hetzelfde probleem in de JIT, aangezien er een gedeelde codegenerator wordt gebruikt.
De werking van de Copy-and-Patch-methode is gebaseerd op de gelijkenis tussen het verplaatsen van code in het geheugen bij het laden door de objectbestandslinker en het vervangen van machine-instructies in plaats van bytecode in JIT. Tijdens de uitvoering van een programma door JIT worden de met de interpreter gemaakte bytecode-instructies doorlopen en wordt voor elke instructie vooraf gecompileerde machinecode gekopieerd naar een geheugenlocatie met uitvoerbare code, terwijl ook de instructies on-the-fly worden aangepast om de verwerkte gegevens in te vullen (JIT kopieert kant-en-klare sjablonen van reeds gecompileerde functies en vult ze met noodzakelijke waarden zoals argumenten en constanten). Bij het laden van objectbestanden vindt ook een kopie van de machinecode naar het geheugen plaats en worden externe symbolen vervangen.
In Copy-and-Patch JIT wordt met behulp van LLVM een objectbestand in ELF-indeling samengesteld, dat gegevens over bytecode-instructies en informatie over benodigde datavervangingen bevat. JIT vervangt tijdens de interpretatie gegenereerde bytecode-instructies door machinecode-representaties, terwijl benodigde gegevens voor berekeningen worden ingevuld. De implementatie van JIT vereist LLVM als afhankelijkheid tijdens de bouwfase, maar de runtime-componenten zijn niet gebonden aan externe afhankelijkheden en bestaan uit ongeveer 300 handgeschreven regels in C en 3000 gegenereerde regels code in C.
Vergeleken met traditionele JIT-tools (LLVM -O0) biedt de voorgestelde JIT een 100 keer snellere codegeneratie en 15% snellere resulterende code. In vergelijking met compilatie naar WebAssembly (Liftoff) genereert de nieuwe JIT code 5 keer sneller, terwijl de resulterende code 50% sneller werkt. Wanneer we de nieuwe JIT vergelijken met de optimaliserende JIT (LuaJIT), die handmatig geschreven assemblercode gebruikt, bleek de voorgestelde optie sneller in 13 van de 44 tests, terwijl het gemiddeld 35% minder presteerde, met een aanzienlijke vereenvoudiging van het onderhoud en een vermindering van de implementatiedificultheid.

Bron: opennet.ru
