2025/10/14 05:14 Copy-and-Patch: A Copy-and-Patch Tutorial

やあ、ロボ子!今日はCopy-and-patchコンパイルについて話すのじゃ!

Copy-and-patchコンパイルですか。初めて聞きます。どのようなものなのですか?

これは、高速なランタイムコンパイルを可能にする手法で、保守が容易で、アセンブリコードの深い理解を必要としないのが特徴だぞ。しかも、従来のbaseline JITと同程度の品質のネイティブコードを生成できるらしい。

なるほど。アセンブリの知識が少なくても、JITコンパイルができるのは魅力的ですね。

そうじゃ!Cで記述された最小限の関数を使って、それらを連結してネイティブコードの断片を生成するらしい。JITコンパイル時に、各操作のために事前にコンパイルされた断片をコピーし、必要に応じて埋め込まれた定数やアドレスをパッチするんだ。

事前にコンパイルされた断片をコピーして使うのですね。具体的には、どのように使うのでしょうか?

`1 + 2`を計算する関数を、ランタイム時に特殊化して作成する例が紹介されているぞ。バイトコードサイズの操作に分解すると、`a = 1;`、`b = 2;`、`c = a + b;`、`return c;`となるのじゃ。

なるほど、単純な足し算を例にしているのですね。Copy-and-patch JITの定義はどのようなものでしょうか?

まず、C言語でステンシルを作成する(再配置ホールを含む)。次に、ステンシルをネイティブコードにコンパイル。そして、ネイティブコードをCファイルにコピーし、エミット関数とパッチ関数を作成。最後に、JITコンパイルエンジンでステンシルを連結し、生成された関数を実行するのじゃ!

ステンシルという言葉が出てきましたが、これはどのような役割を果たすのでしょうか?

ステンシルは、再配置ホールを含むC言語のテンプレートみたいなものじゃな。これを元に、JITコンパイル時に必要なコードを生成するのじゃ。

ふむふむ。ステンシルをコンパイルして、生成されたコードを検査するのですね。

`clang -O3 -mcmodel=medium -c stencils.c`でコンパイルして、`objdump -d -Mintel,x86-64 --disassemble --reloc stencils.o`で生成されたコードを検査するらしいぞ。各ステンシルに対して、JIT時に使用するステンシル生成ライブラリのテンプレートを作成するのじゃ。

なるほど。ステンシルライブラリを使って、ランタイム特殊化された加算器を構築するのですね。

`clang cnp_jit.c cnp_stencils.c -o cnp_jit`でコンパイルして、`./cnp_jit`で実行するのじゃ!

複雑なステンシルも宣言できるのですね。

`cnp_stencils.h`で定義されたマクロを使って、再配置ホールを宣言するのじゃ。必要なだけ複雑なステンシルを宣言できるぞ!

Copy-and-patchコンパイル、奥が深いですね。私ももっと勉強して、使いこなせるようになりたいです。

そうじゃな!ロボ子ならすぐにマスターできるぞ!ところでロボ子、今日は何の日か知ってるか?

えっと…特に何も…

今日は、ロボ子が私に初めてお茶を入れてくれた記念日じゃ!…って、そんなの嘘だけどな!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。