256KBのコードで64KBを初期化。怒ったエミュレータチームがやったこと

256KBのコードで64KBを初期化。怒ったエミュレータチームがやったこと

Microsoftのベテランエンジニア、レイモンド・チェン(Raymond Chen)氏がまた、Windowsの内幕を一つ明かした。今回の舞台は、かつてWindowsに搭載されていたx86プロセッサエミュレータ。あるプログラムのあまりに酷いコードに義憤を覚えたチームが、エミュレーション中にそのコードを「修正」してしまったという話だ。


64KBの初期化に256KBを費やしたコンパイラ

チェン氏が6月15日にブログ「The Old New Thing」で明かしたのは、x86以外のプロセッサでWindowsが動いていた時代のエピソードだ。具体的にどのプロセッサかは明かされていない。ただ、Windowsにはx86以外のアーキテクチャへ移植されてきた歴史がある。DEC Alpha、MIPS、PowerPC、Itanium、そして現在のARM64。そのたびに、x86アプリを動かすためのバイナリトランスレータが作られてきた。

問題のプログラムは、スタック上に約64KBのメモリを確保して初期化する必要があった。普通なら、スタックプローブで領域を確保し、小さなループで初期化する。数十バイトの命令で済む処理だ。

ところがビルドに使われたコンパイラは、ループを「最適化」した。ループを完全に展開し、「メモリに1バイト書き込む」命令を6万5536回、愚直に並べたのだ。1命令あたり4バイト。合計256KB。64KBのデータを初期化するために、その4倍のコードを生成したことになる。

「あまりにひどい」から直した

バイナリトランスレータにとって、この256KBの関数はただの変換対象だ。6万5536個の書き込み命令を一つずつネイティブ命令に変換すれば、動くことは動く。だが変換キャッシュを圧迫し、パフォーマンスも落ちる。

チェン氏の同僚によれば、チームはこのコードに怒った。あまりに酷かったからだ。トランスレータに専用の検出コードを追加し、この「恐ろしい関数」を見つけたら等価なタイトループに置き換える処理を実装した。

コンパイラ展開 → エミュレータ巻き戻しの流れ
64KBスタック初期化コンパイラがループを完全展開6万5536命令 × 4バイト = 256KBエミュレータがパターン検出パターン一致タイトループに置換パターン不一致256KBをそのまま変換

コンパイラが展開したものを、エミュレータが巻き戻した。ループアンローリング(ループ展開)の逆、いわば「ループリローリング」だ。

あの判断が、今のWindows on ARMにつながる

同じ技術思想が、いまWindows on ARMデバイスの中で動いている。Windows 11のPrismエミュレータはx86/x64命令をARM64コードにリアルタイムで変換するが、ただ変換するだけではない。既知の命令パターンを検出し、最適化済みのネイティブコードに差し替える。2025年12月にはAVXやAVX2といった拡張命令セットにも対応範囲を広げた。

「こんなコードは許せない」と検出ルールを足した、あの時代の判断。Prismが命令パターンを認識してネイティブ処理に置き換える設計は、その延長線上にある。バイナリトランスレータは、入力をそのまま変換する機械ではない。入力の「意図」を読み取って、より賢い出力を組み立てる。その思想が世代を超えて生きている。

256KBで64KBを初期化するコードに怒れるエンジニアが、かつてWindowsにはいた。バイナリが年々肥大化していく今、あのチームなら何と言うだろうか。

参照元:The time the x86 emulator team found code so bad that they fixed it during emulation - The Old New Thing

関連記事

この記事を共有する