BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Go 1.5のブートストラップ化を目指すGoogle

Go 1.5のブートストラップ化を目指すGoogle

原文(投稿日:2015/01/15)へのリンク

Googleは先頃,Go 1.5をブートストラップ化する計画について公開した。Goのドキュメントの著者であり,コアデベロッパとして約6年のキャリアを持つRuss Cox氏によると,Googleはこの1年間,“Goのソースツリーから,すべてのCプログラムを排除する方法”について検討していたという。

ブートストラップとは,“コンパイルの対象とするプログラミング言語そのものでコンパイラ(またはアセンブラ)を開発するプロセス”のことだ。一般的にブートストラップには,次のようなメリットがあると言われている。

  • ブートストラップを行う言語のテストのため。
  • より高度な抽象性を備えた,通常は高レベルな言語でコンパイラを記述することができる。
  • 言語自体の改良結果を参照することで,コンパイラがそれらの恩恵を受けることが可能になる。

前述のようにGoogleは,1年以上前から5フェーズから成る変換プランを定義して,Goのソースツリー中のCプログラムを取り除く作業を初めている。

  • フェーズ1 – Go用の既存のCコンパイラを変換する十分な機能を備えた,C->Goトランスレータを開発する。このステップではGoコンパイラの実装が,マクロや共用体,ポインタ演算など,Goへの移植の困難なC言語機能を多用していない,という事実が功を奏すはずだ。

  • フェーズ2 – Goコンパイラのソースコードを変換して,生の出力として,C言語形式のGoソースコードを取得する。

  • フェーズ3 – コンパイラのソースコードを,一般的なGoプログラムに書き直す。パッケージの指定,ドキュメントやユニットテストの追加が主な作業になる。

  • フェーズ4 – コードを最適化する。コンパイラのメモリ使用量やCPU使用率に対策し,場合によっては並列処理も導入する。このフェーズではさらに,冗長なnilチェックやバウンダリチェックが削除可能なケースにおいて,コンパイラの最適化能力を向上するために,"アーキテクチャ非依存の非順序ツリー(Node*)と,現在使用しているアーキテクチャ依存性を持つ順序リスト(Prog*)の間に,新たな中間表現を導入する"試みを行う予定だ。

  • フェーズ5 – フロントエンドを置き換えてgo/parsergo/typesの最新バージョンにする。

Russによれば,これ以外にもいくつかのアプローチが検討されたが,2年前の提案に詳説されたようなさまざまな理由から,いずれも除外されている。

Goのブートストラップ化

コンパイラのブートストラップでは,開発しようとする言語をコンパイルする手段が必要であることから,“鶏が先か,卵が先か”という問題に直面するのが通常だ。

Goの場合,Go 1.5をビルドするには,Go 1.4以降を事前にインストールしておく必要がある。その既存ツールチェーンを使用して,Go 1.5ツールチェーンの基本バージョンがまずビルドされる。(Go 1.4でコンパイルされた)Go 1.5ツールチェーンが用意できれば,それ自体を使って再度ビルドを実行することで,Go 1.5でコンパイルされたGoツールチェーンが入手できる。後はこれを使用して,go_bootstrapと,標準ライブラリやコンポーネントなど残りの部分をビルドすればよい。生成したツールチェーンを使って自分自身を再度ビルドするという,中間ステップを加えたこのプロセスは,今後のGoのバージョンでも採用される予定だ。

InfoQでは,Goのブートストラップ化についてさらに詳しく知るために,Russに話を聞くことにした。

ブートストラップへの移行は,Goにとって大きなマイルストンだと思います。言語を改良する今の段階になって,これ程に大きな作業の実施を決定した理由について,詳しく教えてください。

Goは優れた汎用言語ですが,その設計のスイートスポットは,Googleのサーバで稼働しているような,大規模で並列性を持ったサーバサイドソフトウェアを記述することにあります。そのGoで書かれた最初の大規模プログラムがGoコンパイラであったとすれば,そのユースケースが言語の設計に対して必要以上に影響を与えてしまって,本来の目標を見失しなうことになるでしょう。

最初からブートストラップ化しなかった技術的な理由は他にもあります。移植性,ソースコードからのコンパイルを容易にすること,言語の初期段階には安定したコンパイラ実装が必要であったこと,などです。

Cに代えてGoを使用してビルドすることで,特に大きな改善が期待されると考える部分はありますか?

Ken Thompson氏が以前に,プログラムを書く上で,GoはCよりもずっとシンプルに感じる言語だ,と言ってくれたことがあります。その理由のひとつとして,無効なポインタ値の使用やメモリリーク,バッファオーバーフロー,深い再帰でのスタックオーバーフロー,void*の誤用,期待と違う数値比較といった,Cで一般的にバグの生じやすい部分を,Goですべて削除したことがあります。

標準のGoツールチェーンは,モジュール性やユニットテスト,プロファイルなどのサポートの面で,標準的なCツールチェーンよりもはるかに優れています。ですが,私が最も感動するのは,内部的なAPI変更やリファクタリングを行うときに,(gofixのような)プログラムの自動的な書き換えが期待できる点です。

Go 1.3+ Compiler Overhaul”では,既存のコンパイラをCからGoに転換するプロセスの5つのフェーズが紹介されていましたが,現時点でどのフェーズまで進んでいるのか,明確に示すことはできるのでしょうか?残りが完了するのはいつになるのでしょう?

プロジェクトとしては,言語のランタイムをCからGoに変換する作業を優先していました。それが終わって,今は再度コンパイラに取り掛かったところです。

資料に書いた内容でいえば,現在はフェーズ2です。トランスレータが完了して,ランタイムの変換に使用することができました。今はそれをコンパイラに適用しているところです。コンパイラを変換する作業までを,Go 1.5で実施したいと思っています。クリーンアップ作業は,その後のプロジェクトで実行することになるでしょう。

この記事に星をつける

おすすめ度
スタイル

BT