[インデックス 104] ファイルの概要
このコミットは、Goコンパイラの6g(64-bit x86アーキテクチャ向けのGoコンパイラ)に関連するruntime.cとruntime.hファイルの削除を記録しています。これらのファイルは、Goのランタイムシステムの一部として、低レベルの操作やシステムコール、メモリ管理、文字列操作、インターフェース変換などの機能を提供していました。
コミット
d1493d1edcaae2d6403b42d99b9d7b3ccb3698a5
GitHub上でのコミットページへのリンク
元コミット内容
checked into both gc and runtime by mistake
SVN=121498
変更の背景
このコミットの背景は、コミットメッセージ「checked into both gc and runtime by mistake」(誤ってgcとruntimeの両方にチェックインされた)が明確に示している通り、コードの重複を解消することにあります。Goの初期開発段階において、ランタイム関連のコードがコンパイラ(gc)のディレクトリと、Goランタイム自体のディレクトリの両方に誤って存在していたと考えられます。このコミットは、その重複を修正し、src/cmd/6gディレクトリからこれらのランタイムファイルを削除することで、コードベースの整合性と単一責任の原則を確立することを目的としています。
前提知識の解説
- Goコンパイラ (
gc): Go言語の公式コンパイラ群を指します。6gは、x86-64アーキテクチャ向けのGoコンパイラを意味していました(Go 1.5以降は、コンパイラはGo言語自体で書かれ、go tool compileとして統合されています)。初期のGoコンパイラはC言語で書かれており、コンパイル時にGoプログラムを機械語に変換する役割を担っていました。 - Goランタイム (
runtime): Goプログラムが実行されるために必要な、低レベルの機能を提供するライブラリです。これには、ガベージコレクション、ゴルーチンのスケジューリング、メモリ管理、システムコールインターフェース、プリミティブなデータ型(文字列、スライス、マップなど)の操作などが含まれます。Goランタイムは、GoプログラムがOSと対話し、効率的にリソースを使用するための基盤となります。初期のGoランタイムの一部はC言語で書かれていましたが、Go 1.5以降、ほとんどのランタイムコードはGo言語自体で書かれるようになりました。 runtime.cとruntime.h: これらはC言語のソースファイルとヘッダーファイルであり、GoランタイムのC言語部分を構成していました。runtime.hは、runtime.cで実装される関数の宣言や、ランタイムが使用するデータ構造の定義を含んでいました。runtime.cは、これらの宣言に対応する具体的な実装を提供し、OSとの直接的な対話や、Go言語では直接扱えない低レベルの操作を行っていました。
このコミットが行われた時期(2008年)はGo言語の非常に初期の段階であり、コンパイラとランタイムの構造がまだ固まっていない時期でした。そのため、このようなファイルの重複が発生しやすかったと考えられます。
技術的詳細
削除されたsrc/cmd/6g/runtime.cとsrc/cmd/6g/runtime.hは、Goコンパイラ6gのビルドプロセスの一部としてコンパイルされ、Goプログラムの実行に必要なランタイム機能を提供していました。これらのファイルには、以下のような機能のC言語実装が含まれていました。
- 基本的なI/O操作:
sys_printbool,sys_printfloat,sys_printint,sys_printstringなど、デバッグ目的や基本的な出力のための関数。これらは直接システムコール(sys_write)を呼び出して標準出力に書き込んでいました。 - メモリ管理:
brk(メモリ領域の確保)、mal(メモリ割り当て)といった関数が含まれており、Goのガベージコレクタがまだ成熟していない初期段階でのメモリ確保の仕組みを示唆しています。sys_mmap(メモリマップ)のようなシステムコールを直接利用していました。 - 文字列操作:
sys_catstring(文字列結合)、sys_cmpstring(文字列比較)、sys_slicestring(文字列スライス)、sys_indexstring(文字列インデックスアクセス)など、Goの組み込み文字列型の低レベルな操作をC言語で行っていました。 - インターフェース変換:
sys_ifaces2i,sys_ifacei2i,sys_ifacei2sといった関数は、Goのインターフェース型と構造体型間の変換(型アサーションやインターフェースの実装チェック)に関連するロジックを含んでいました。特にhashmap関数は、インターフェースのメソッド解決のためのハッシュマップを管理していました。 - ユーティリティ関数:
strlen(文字列長)、prints(文字列出力)、dump(メモリダンプ)、throw(エラー発生時の終了)、mcpy(メモリコピー)など、一般的なC言語ユーティリティが含まれていました。 - 型サイズのチェック:
check関数は、Goの基本的な型(int8,uint8,int16,uint16,int32,uint32,int64,uint64,float32,float64, ポインタ型)のサイズが期待通りであることを検証していました。これは、異なるプラットフォームでの互換性を保証するための初期のテストの一部と考えられます。
これらのファイルがsrc/cmd/6gから削除されたということは、これらの機能がGoランタイムの別の場所(おそらくsrc/runtimeディレクトリ)に既に存在していたか、あるいはより適切な場所に移管されたことを意味します。これにより、コンパイラとランタイムの役割分担が明確になり、コードの重複が解消され、メンテナンス性が向上しました。Go言語の進化に伴い、これらの低レベルな機能の多くは最終的にGo言語自体で再実装され、C言語のコードは最小限に抑えられていきました。
コアとなるコードの変更箇所
このコミットでは、以下の2つのファイルが完全に削除されています。
src/cmd/6g/runtime.c: 595行のコードが削除されました。src/cmd/6g/runtime.h: 107行のコードが削除されました。
合計で702行のコードが削除されており、これはこれらのファイルがGoコンパイラの6g部分から完全に除去されたことを示しています。
コアとなるコードの解説
削除されたruntime.cとruntime.hは、Goの初期のランタイムシステムにおいて重要な役割を担っていました。
runtime.hは、Goランタイムが使用する基本的な型定義(int8, uint8などの固定幅整数型、bool, byte, string型など)や、ランタイム内部で使用される構造体(Sigs, Sigi, Mapなど)、そしてランタイムが提供する低レベル関数のプロトタイプ宣言を含んでいました。特に、string型がlenとstr[1](可変長配列のC言語での表現)を持つ構造体として定義されている点や、Map構造体がインターフェースのメソッドテーブルを管理するためのfun配列を持つ点など、Goの基本的なデータ構造がC言語レベルでどのように表現されていたかが伺えます。
runtime.cは、これらのヘッダーで宣言された関数の具体的な実装を提供していました。例えば、sys_printint関数は、int64型の整数を文字列に変換して標準出力に書き出すロジックを含んでいました。sys_catstring関数は、2つの文字列を結合して新しい文字列を生成するロジックを、メモリ割り当て(mal)とメモリコピー(mcpy)を組み合わせて実装していました。hashmap関数は、Goのインターフェース型が実行時にどのようにメソッドを解決していたかを示す重要な部分であり、インターフェースのシグネチャ(Sigi)と構造体のシグネチャ(Sigs)を基に、メソッドの実装関数へのポインタをルックアップする仕組みを持っていました。
これらのファイルが削除されたことは、Goのランタイムがより整理され、特定の機能が重複なく、より適切な場所(おそらくsrc/runtimeディレクトリ)に集約されたことを意味します。また、Go言語自体が成熟するにつれて、C言語で書かれていたこれらの低レベルな機能の多くがGo言語で再実装され、Goのコードベース全体がよりGoらしい(Go-idiomatic)ものへと進化していった過程の一部でもあります。
関連リンク
参考にした情報源リンク
- Go commit d1493d1edcaae2d6403b42d99b9d7b3ccb3698a5 on GitHub
- Go compiler's
gc(Go compiler) runtime,runtime.candruntime.hpurpose: Web Search Results (and related links within the search results)