Brandt Bucher frÄn Microsoft, en av kÀrnutvecklarna för CPython och del av teamet som arbetar med att öka prestandan hos CPython-tolken, har publicerat en implementation av en JIT-kompilator för Python, som anvÀnder Copy-and-Patch-tekniken. Publiceringen av JIT sammanfaller med jul och tillkÀnnagivandet Àr skrivet pÄ vers.
Den föreslagna JIT Àr anmÀrkningsvÀrd för sin mycket höga hastighet vid kodgenerering, enkelhet i underhÄll och fullstÀndig integration med tolken. Den föreslagna metoden möjliggör att automatiskt omvandla en tolk, skriven i C, till en JIT-kompilator, utan separat utveckling av logik för kodgenerering och utan manuellt skapande av assembly-representationer. Med detta angreppssÀtt kommer en buggfix i tolken automatiskt att ÄtgÀrda samma problem i JIT, eftersom en gemensam kodgenerator anvÀnds.
Arbetet med Copy-and-Patch-metoden bygger pÄ att kodflyttning i minnet under lastning av objektfiler av lÀnkaren och insÀttning av maskininstruktioner istÀllet för bytekod i JIT Àr liknande uppgifter. Under JIT:s körning i programmet görs en genomgÄng av de bytekodsinstruktioner som skapats av tolken och för varje instruktion kopieras den förkompilerade maskinkoden till en minnesregion med körbar kod, liksom justering av instruktionerna i realtid för att införliva de bearbetade datan (JIT kopierar fÀrdiga mallar av redan kompilerade funktioner och sÀtter in nödvÀndiga vÀrden som argument och konstanter). Vid lastning av objektfiler sker ocksÄ en kopiering av maskinkod till minnet och insÀttning av externa symboler.
I Copy-and-Patch JIT sammanstÀlls en objektfil i ELF-format med hjÀlp av LLVM, som innehÄller data om bytekodsinstruktioner och information om nödvÀndiga datainsÀttningar. JIT ersÀtter de instruktioner av bytekod som genererats under programtolkningen med representationer i maskinkod, samtidigt som den införlivar nödvÀndiga data för berÀkningar. Implementeringen av JIT krÀver LLVM som beroende under byggstadiet, men runtime-komponenterna Àr inte kopplade till externa beroenden och bestÄr av ungefÀr 300 manuellt skrivna rader i C och 3000 genererade rader i C.
JÀmfört med traditionella JIT-verktyg (LLVM -O0) erbjuder den föreslagna JIT:en 100 gÄnger snabbare kodgenerering och 15 % snabbare resulterande kod. JÀmfört med kompilering till WebAssembly (Liftoff) genererar den nya JIT:en kod 5 gÄnger snabbare, och den resulterande koden Àr 50 % snabbare. Om man jÀmför den nya JIT:en med den optimerande JIT:en (LuaJIT), som anvÀnder manuellt skriven assemblerkod, var alternativet snabbare i 13 av 44 tester, men i genomsnitt var det 35 % lÄngsammare, med betydande förenkling av underhÄllet och minskad implementeringssvÄrighet.

KĂ€lla: opennet.ru
