Brandt Bucher de la Microsoft, unul dintre dezvoltatorii esențiali ai CPython, care lucrează în echipa responsabilă cu creșterea performanței interpretului CPython, a publicat o implementare a compilatorului JIT pentru Python, folosind tehnica Copy-and-Patch. Publicația JIT este lansată de Crăciun și anunțul este scris în versuri.
JIT-ul propus se remarcă printr-o viteză extrem de mare de generare a codului, ușurința mentenanței și integrarea completă cu interpretul. Metoda propusă permite transformarea automată a interpretului, scris în C, într-un compilator JIT, fără a necesita formare separată a logicii de generare a codului și fără a crea manual reprezentări de asamblare. Prin această abordare, corectarea erorilor în interpret este automată și se va reflecta și în JIT, deoarece se folosește un generator comun de cod.
Metoda Copy-and-Patch se bazează pe faptul că relocarea codului în memorie la încărcarea fișierelor obiect și înlocuirea instrucțiunilor mașină în locul bytecode-ului în JIT sunt sarcini similare. În timpul execuției programului, JIT-ul parcurge instrucțiunile bytecode generate de interpret și copiază pentru fiecare instrucțiune codul mașină precompilat în zona de memorie cu codul executabil, precum și modifică instrucțiunile pe parcursul execuției pentru a înlocui datele procesate (JIT copiază șabloane gata precompilate și le completează cu valorile necesare, cum ar fi argumentele și constantele). În momentul încărcării fișierelor obiect, se efectuează, de asemenea, copierea codului mașină în memorie și înlocuirea simbolurilor externe.
În Copy-and-Patch JIT, un fișier obiect în format ELF este compilat cu ajutorul LLVM, conținând date despre instrucțiunile bytecode și informații despre înlocuirea necesară a datelor. JIT-ul înlocuiește instrucțiile bytecode generate în timpul interpretării programului cu reprezentări în codul mașină, în același timp completând datele necesare pentru calcule. Implementarea JIT necesită LLVM ca dependență în timpul compilării, dar componentele de runtime nu depind de alte biblioteci externe și constau în aproximativ 300 de linii de cod scrise manual în C și 3000 de linii de cod C generate.
Comparativ cu un instrument JIT tradițional (LLVM -O0), JIT-ul propus oferă o generare a codului de 100 de ori mai rapidă și un cod rezultat cu 15% mai rapid. Comparativ cu compilarea în WebAssembly (Liftoff), noul JIT generează cod de 5 ori mai rapid, iar codul rezultat funcționează cu 50% mai repede. Dacă comparăm noul JIT cu JIT-ul optimizator (LuaJIT), care folosește cod scris manual în asamblor, varianta propusă s-a dovedit a fi mai rapidă în 13 din cele 44 de teste, iar în medie a fost cu 35% mai lent, având totodată o simplificare semnificativă a întreținerii și o reducere a nivelului de complexitate al implementării.

Sursa: opennet.ro
