ゲーム業界では、リリース間での互換性の維持が非常に重要です。古いゲームであっても 、更新されたPlayStation®オペレーティングシステム上で動作させなければならないためです。意図せず発生してしまう非互換性からオペレーティングシステムを守るため、当社ではこのたび、現在サポートされている全PlayStation®プラットフォーム用(PS4だけでなくPS3およびVitaも対象)にC++ ABIテストスイートを開発しました。SN Systemsでは、当テストスイートをオープンソースコミュニティに提供していますので、誰でも自由に使用することができます。当テストスイートは以下の場所にあります:http://llvm.org/svn/llvm-project/test-suite/trunk/ABI-Testsuite。
ABIとは
C++ ABIには、ハイレベルなC++の構成要素をどのように低レベルに実装するのかの定義があります。なかでも、C++ ABIは、オーバーロード定義されている関数を許可するため、関数名をどのようにマングルしたらよいのか、また、基本クラスの割り当て方法や、さらに、仮想関数をどのように呼び出すのかなどを定義します。プログラム全体を連動させるためには、相互にリンクされるオブジェクト ファイルも、こういった規則にのっとったものにする必要があります。コンパイラによって実装されるABIに非互換性が少しでもあると、プログラムモジュール間でのやりとりに影響が及びますが、これはプログラミングを行う者にとって、診断が非常にやっかいなものです。ABIの非互換性が原因で発生する不具合は、たちの悪いコンパイルエラーの原因になります。その理由は次のとおりです。
- この手の問題を解析する際、デバッガの利用が制限されることが頻繁にあります。デバッガは、コンパイラにより生成されたデバッグ情報に依存しますが、この場合、この情報が不正確なものになるためです。
- コンパイル済みコードのひとつひとつのファイルを個別に見ると、有効なものに見えてしまう。この機能不良は、相互にリンクが行われたときしか確認できません。
IA-64 ABIまたはItanium ABIとして知られる、現在使用されているC++コンパイラのほとんどに採用されているC++ ABIは、当初Itanium 64ビットプロセッサ用に開発されたものでした。しかし、このABIは、GNU-C++、ARMcc、Clang/LLVMやPS3、PSVitaおよびPS4などのPlayStation用コンパイラなど、広く使用されている多くのコンパイラによって利用されてきました。Microsoft Visual C++コンパイラを除き、C++ ABIは、コンパイラベンダーの事実上の業界標準になりました。ABIの現在の公開用バージョンは以下で利用可能です:http://mentorembedded.github.io/cxx-abi/abi.html。
ABIテストスイートにより実現されること
SN SystemsのABIテストスイートは、ABI仕様の各部に準拠するC++コードを使用することで、ABI仕様と照らし合わせてコンパイラの実装をテストします。さらにコンパイラによって生成されたレイアウトが「正しい値」であるかどうかを比較します。当社のABIテストスイートは、およそ400個のテストファイル上に分散された、100万個強のユニークなクラスで構成されています。
テストの対象となるもの
- クラスのサイズおよびアラインメント
- フィールドおよび基本クラスのオフセット
- ビットフィールド
- vtblおよびVTTコンテンツ
- ctorおよびdtor vtables
- 名前のマングル
- 空のクラス
- サンク
- 初期化ガード変数
- RTTI /typeinfo変数
テストの作成方法
名前のマングルのテストは手動で作成されていますが、テストスイートの大部分は、オブジェクトのレイアウト、VtableやVTTなどのテスト専用になっています。こういったテストのクラスは、ABI仕様や、一部のパラメータ内の全列挙の研究、および既存のコードベースの検査により作成されています。実際のテストは、当社のSNCコンパイラ を修正することにより作成したテストジェネレータによって生成されています。また、Cレベルの構造体の割り当ても、ビットフィールドやpacked型属性と合わせてテストされています。
詳しい内容を確認したい場合には、テストスイート内にある README.txt、FAQ.pdf および Design document をダウンロードしてください:http://llvm.org/svn/llvm-project/test-suite/trunk/ABI-Testsuite/。
トップに戻る