Brandt Bucher fra Microsoft, en av kjerneteamene bak CPython, som jobber med å forbedre ytelsen til CPython-tolkeren, har publisert en implementering av en JIT-kompilator for Python, som bruker Copy-and-Patch-teknikken. JIT-publikasjonen er timet til jul, og kunngjøringen er skrevet på vers.
Den foreslåtte JIT-er er bemerkelsesverdig for sin svært høye kodegenereringshastighet, enkel vedlikehold og fullstendig integrasjon med tolken. Den foreslåtte metoden tillater automatisk konvertering av tolken, som er skrevet på C, til en JIT-kompilator, uten å måtte utvikle separat logikk for generering av kode og uten manuell oppretting av assembler-representasjoner. Med denne tilnærmingen, vil en feilretting i tolken automatisk føre til at samme problem blir løst i JIT, ettersom de deler en felles kodegenerator.
Arbeidet med Copy-and-Patch-metoden baserer seg på at omplassering av kode i minnet ved lastingen av objektfiler og substitusjon av maskininstruksjoner i stedet for bytekode i JIT, er lignende oppgaver. Når JIT kjører under programkjøring, itererer den over instruksjonene i bytekoden opprettet av tolken og kopierer den forhåndskomplimerte maskinkoden for hver instruksjon til den kjørbare koden i minnet, samtidig som den dynamisk endrer instruksjonene for å sette inn de behandlende dataene (JIT kopierer ferdige maler fra allerede kompilerte funksjoner og setter inn nødvendige verdier, som argumenter og konstanter). Under lasting av objektfiler kopieres også maskinkoden til minnet og eksterne symboler settes inn.
I Copy-and-Patch JIT kompilert til ELF-format, inkludert data om bytekodeinstruksjoner og informasjon om nødvendig datamal. JIT erstatter instruksjoner i bytekoden generert under tolkningen av programmet med representasjoner i maskinkode, samtidig som den setter inn de nødvendige dataene for beregningene. Implementeringen av JIT krever LLVM som avhengighet under oppbyggingen, men runtime-komponentene er ikke knyttet til eksterne avhengigheter og utgjør omtrent 300 manuelt skrevne linjer i C og 3000 genererte linjer med C-kode.
Sammenlignet med tradisjonelle JIT-verktøy (LLVM -O0) gir den foreslåtte JIT-en 100 ganger raskere kodegenerering og 15 % raskere resulterende kode. Sammenlignet med kompilering til WebAssembly (Liftoff) genererer den nye JIT-en kode 5 ganger raskere, mens den resulterende koden kjører 50 % raskere. Når vi sammenligner den nye JIT-en med den optimaliserende JIT-en (LuaJIT), som bruker håndskrevet assemblerkode, viste den foreslåtte varianten seg å være raskere i 13 av 44 tester, men var i gjennomsnitt 35 % tregere, med betydelig forenklet vedlikehold og redusert implementeringskompleksitet.

Kilde: opennet.ru
