Brandt Bucher fra Microsoft, en af kerneudviklerne af CPython og arbejder i et team, der fokuserer på at forbedre CPython-interpreterens ydeevne, har offentliggjort en implementering af en JIT-kompilator til Python, der bruger Copy-and-Patch teknikken. Udgivelsen af JIT er planlagt til jul, og annonceteksten er skrevet på vers.
Den foreslåede JIT er bemærkelsesværdig for sin meget høje hastighed ved kodegenerering, sin enkelhed i vedligeholdelse og fuld integration med interpreterens funktioner. Den foreslåede metode muliggør automatisk konvertering af en interpreter skrevet i C til en JIT-kompilator, uden separat udarbejdelse af kodegenereringslogik og uden manuel oprettelse af assemblerrepræsentationer. Med denne tilgang vil rettelse af en fejl i interpreter automatisk føre til løsning af det samme problem i JIT, da der anvendes en fælles kodegenerator.
Copy-and-Patch-metoden er baseret på, at relocation af kode i hukommelsen ved indlæsning af objektfiler og udskiftning af maskininstruktioner i stedet for bytekode i JIT er lignende opgaver. Når JIT arbejder under programkørslen, foretages der en gennemgang af de instruktioner i bytekode, som er genereret af interpreter, og for hver instruktion kopieres den forudkompilerede maskinkode til hukommelsesområdet med eksekverbar kode, samt ændres instruktionerne dynamisk for at indsætte de behandlede data (JIT kopierer de færdige skabeloner af allerede komplierede funktioner og indsætter de nødvendige værdier, såsom argumenter og konstanter). Ved indlæsning af objektfiler kopieres også maskinkoden til hukommelsen og eksterne symboler udskiftes.
I Copy-and-Patch JIT samles et objektfil i ELF-format ved hjælp af LLVM, som indeholder data om bytekode-instruktioner og information om nødvendig datakompensering. JIT erstatter de instruktioner i bytekode, der er genereret under programinterpretation, med repræsentationer i maskinkode, samtidig med at nødvendige data til beregninger indsættes. Implementeringen af JIT kræver LLVM som afhængighed under opbygningen, men runtime-komponenterne er ikke knyttet til eksterne afhængigheder og kan reduceres til cirka 300 manuelt skrevne linjer i C og 3000 genererede linjer af C-kode.
Sammenlignet med traditionelle JIT-værktøjer (LLVM -O0) tilbyder den foreslåede JIT 100 gange hurtigere kodegenerering og 15% hurtigere resulterende kode. I forhold til kompilering til WebAssembly (Liftoff) genererer den nye JIT koden fem gange hurtigere, og den resulterende kode kører 50% hurtigere. Sammenlignet med den optimerende JIT (LuaJIT), der bruger håndskrevet assemblerkode, viste den foreslåede version sig at være hurtigere i 13 af 44 tests, og i gennemsnit var den 35% langsommere, mens den samtidig betydeligt forenklede vedligeholdelsen og reducerede kompleksitetsniveauet i implementeringen.

Kilde: opennet.ru
