Brandt Bucher z Microsoftu, který patří mezi hlavní vývojáře CPython a pracuje v týmu zaměřeném na zvyšování výkonu CPythonu, publikoval implementaci JIT kompilátoru pro Python, využívající techniku Copy-and-Patch. Publikace JIT byla načasována na Vánoce a její oznámení je napsáno ve verších.
Navrhovaný JIT se vyznačuje velmi vysokou rychlostí generování kódu, jednoduchostí údržby a plnou integrací s interpretem. Navrhovaná metoda umožňuje automaticky převést interpreter napsaný v jazyce C na JIT kompilátor, bez nutnosti samostatného vytváření logiky generování kódu a bez ručního vytváření assemblerových reprezentací. Při tomto přístupu oprava chyby v interpreteru automaticky povede k odstranění téhož problému v JIT, protože se používá společný generátor kódu.
Práce metody Copy-and-Patch spočívá v tom, že relokace kódu v paměti při načítání linkerem objektových souborů a nahrazování strojových instrukcí místo bajtkódu v JIT jsou podobné úkoly. Při práci JIT během vykonávání programu dochází k procházení instrukcí bajtkódu vytvořených interpretem a kopírování pro každou instrukci předem zkompilovaného strojového kódu do oblasti paměti s vykonávaným kódem, stejně jako k dynamické úpravě instrukcí pro nahrazení zpracovávanými daty (JIT kopíruje připravené šablony již zkompilovaných funkcí a nahrazuje v nich potřebné hodnoty, jako jsou argumenty a konstanty). Při načítání objektových souborů také dochází ke kopírování strojového kódu do paměti a nahrazování externích symbolů.
V Copy-and-Patch JIT pomocí LLVM vzniká objektový soubor ve formátu ELF, který obsahuje informace o instrukcích bajtkódu a údaje o potřebné výměně dat. JIT nahrazuje během interpretace programu vytvářené instrukce bajtkódu reprezentacemi ve strojovém kódu, přičemž zároveň dosazuje potřebná data pro výpočty. Realizace JIT vyžaduje jako závislost LLVM během fáze sestavení, ale runtime komponenty nejsou vázány na externí závislosti a skládají se přibližně ze 300 ručně napsaných řádků v jazyce C a 3000 vygenerovaných řádků kódu v C.
V porovnání s tradičním JIT nástrojem (LLVM -O0) navrhovaný JIT poskytuje generaci kódu 100krát rychlejší a výsledný kód je o 15 % rychlejší. V porovnání s kompilací do WebAssembly (Liftoff) nový JIT generuje kód 5krát rychleji a výsledný kód funguje o 50 % rychleji. Při srovnání nového JIT s optimalizujícím JIT (LuaJIT), který používá ručně psaný assemblerový kód, se navrhovaná varianta ukázala být rychlejší v 13 z 44 testů, přičemž průměrně zaostala v výkonu o 35 %, a to při značném zjednodušení údržby a snížení úrovně složitosti implementace.

Zdroj: opennet.ru
