Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 18662] ファイルの概要

コミット

コミットハッシュ: e8fe1cce66f51e7fa12a1b37dd273bbcd10176a8 Author: Russ Cox rsc@golang.org Date: Wed Feb 26 12:21:31 2014 -0500

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/e8fe1cce66f51e7fa12a1b37dd273bbcd10176a8

元コミット内容

runtime, net: fixes from CL 68490043 review

These are mistakes in the first big NaCl CL.

LGTM=minux.ma, iant
R=golang-codereviews, minux.ma, iant
CC=golang-codereviews
https://golang.org/cl/69200043

変更の背景

このコミットは、Goランタイムとネットワーク関連のコードベースにおける修正であり、特に以前の大きなNative Client (NaCl) 関連の変更セット (CL 68490043) で導入された誤りを修正することを目的としています。元のコミットメッセージにある「These are mistakes in the first big NaCl CL.」という記述から、NaClサポートの初期段階で発生した実装上の問題や見落としを修正する、クリーンアップ的な性質のコミットであることがわかります。

Go言語は、Googleが開発したプログラミング言語であり、そのランタイムはメモリ管理、スケジューリング、ガベージコレクションなど、プログラムの実行環境全体を管理します。Native Client (NaCl) は、Googleが開発したサンドボックス技術で、ウェブブラウザ内でC/C++などのネイティブコードを安全に実行することを可能にするものでした。Go言語がNaClをサポートするということは、Goで書かれたプログラムをNaCl環境向けにコンパイルし、ウェブブラウザなどのサンドボックス化された環境で実行できるようにすることを意味します。

このコミットは、NaClサポートの導入に伴う初期のバグ修正の一環として、特定のアーキテクチャ (amd64 および amd64p32) における物理ページサイズ (PhysPageSize) の定義と、goc2c ツールに関するコメントの追加を行っています。これは、Goランタイムが異なるOSやアーキテクチャ、特にNaClのような特殊な環境で正しく動作するための調整が進行中であったことを示唆しています。

前提知識の解説

Native Client (NaCl) と Go言語

Native Client (NaCl) は、Googleが開発したオープンソースのサンドボックス技術です。ウェブブラウザ内でC/C++などのネイティブコードを安全かつ高性能に実行することを目的としていました。NaClは、コードの検証、メモリ保護、システムコールインターセプトなどのメカニズムを通じて、サンドボックス化された環境を提供します。これにより、悪意のあるコードがシステムに損害を与えることを防ぎつつ、ネイティブアプリケーションに近いパフォーマンスを実現しようとしました。

Go言語は、Go 1.3のリリースでNaCl環境へのビルドサポートを導入しました。これにより、Goプログラムをnacl/386nacl/amd64p32nacl/armといったターゲット向けにコンパイルし、NaClサンドボックス内で実行することが可能になりました。これは、Goアプリケーションをウェブ環境でより効率的に実行するための試みの一つでしたが、現在ではNaClのサポートは非推奨となり、LLVMなどのツールチェーンからも削除されつつあります。

GOOS_nacl

GOOS_naclは、Goのビルドシステムにおける環境変数またはコンパイル時定義で、ターゲットオペレーティングシステムがNative Client (NaCl) であることを示します。Goのクロスコンパイル機能の一部として、特定のOS向けのコードパスを有効にするために使用されます。この定義が存在する場合、GoランタイムはNaCl環境に特化した動作や最適化を行うことができます。

PhysPageSize

PhysPageSizeは、物理メモリのページサイズを定義する定数です。オペレーティングシステムは、メモリを固定サイズの「ページ」に分割して管理します。このページサイズは、OSやアーキテクチャによって異なります。Goランタイムのメモリ管理、特にガベージコレクタやアロケータは、この物理ページサイズを考慮して動作します。例えば、Goランタイムのmheapは、8192バイト(8KB)の粒度でメモリを管理するとされており、これはGoランタイムが内部的に使用するページサイズを示唆しています。NaCl環境では、通常のOSとは異なるメモリ管理の制約や特性があるため、PhysPageSizeが異なる値に設定されることがありました。

RuntimeGogoBytes

RuntimeGogoBytesに関する具体的な情報は、一般的なGoのドキュメントや公開されている情報源からは見つかりませんでした。これは、Goランタイムの非常に内部的な実装詳細に関連する定数である可能性が高いです。Goランタイムのコンテキストでは、「gogo」という用語は、Goルーチンのコンテキストスイッチやスタック切り替えに関連する操作を指すことがあります。したがって、RuntimeGogoBytesは、Goルーチンのコンテキスト切り替えに必要なスタックフレームやレジスタの状態を保存するために必要なバイト数など、特定のランタイム内部構造のサイズに関連している可能性があります。

goc2c

goc2cは、Goのツールチェーンの一部であり、.gocファイルを.cファイルに変換するユーティリティです。.gocファイルは、GoコードとCコードを組み合わせたハイブリッドなファイル形式で、GoからCの関数を呼び出すためのラッパーコードを生成するために使用されます。これは、GoとCの相互運用性(Cgoに似たメカニズム)を可能にするためのもので、特にGoランタイムの低レベルな部分や、特定のハードウェアと直接やり取りする必要がある場合に利用されます。goc2cは、生成されるCコードがターゲットシステムで正しくアラインメントされるように調整したり、ガベージコレクタに対して引数リストのどの部分が入力でどの部分が出力であるかを伝える役割も担います。

技術的詳細

このコミットは、主にGoランタイムのアーキテクチャ固有のヘッダーファイル (src/pkg/runtime/arch_amd64.h および src/pkg/runtime/arch_amd64p32.h) と、ランタイムの共通ヘッダーファイル (src/pkg/runtime/runtime.h) に変更を加えています。

PhysPageSize の条件付きコンパイルの削除

src/pkg/runtime/arch_amd64.hsrc/pkg/runtime/arch_amd64p32.h の両方で、PhysPageSize の定義から GOOS_nacl に基づく条件付きコンパイルが削除されています。

変更前:

#ifdef GOOS_nacl
	PhysPageSize = 65536,
#else
	PhysPageSize = 4096,
#endif

変更後:

	PhysPageSize = 4096,

この変更は、NaCl環境における物理ページサイズが、他の環境(例えばLinuxやWindowsなど)と同じ4096バイトに統一されたことを意味します。以前はNaCl環境では65536バイト(64KB)という大きなページサイズが設定されていましたが、これが標準的な4KBに修正されたか、あるいはNaCl環境での特別なページサイズ設定が不要になったことを示唆しています。これは、NaClランタイムのメモリ管理がGoランタイムの期待するページサイズとより整合性が取れるようになったか、またはGoランタイムがNaCl環境のページサイズの違いをより柔軟に扱えるようになったため、特定の条件付き定義が不要になった可能性があります。

RuntimeGogoBytes の条件付きコンパイルの削除

src/pkg/runtime/arch_amd64p32.h では、RuntimeGogoBytes の定義から GOOS_solaris に基づく条件付きコンパイルが削除されています。

変更前:

#ifdef GOOS_solaris
	RuntimeGogoBytes = 80,
#else
	RuntimeGogoBytes = 64,
#endif

変更後:

	RuntimeGogoBytes = 64,

この変更により、Solaris環境におけるRuntimeGogoBytesの特別な設定が削除され、他の環境と同じ64バイトに統一されました。これは、Solaris環境でのGoルーチンのコンテキスト切り替えに関連する内部構造のサイズが、他のOSと同一になったことを示唆しています。

runtime.h における goc2c の役割に関するコメントの追加

src/pkg/runtime/runtime.h では、goc2c の役割に関するコメントが追加されています。

追加されたコメント:

+ * Goc2c also takes care of conveying to the garbage collector
+ * which parts of the argument list are inputs vs outputs.

このコメントは、goc2c が単にGoとCの間のインターフェースを生成するだけでなく、ガベージコレクタに対して、関数呼び出しの引数リストのどの部分が入力(呼び出し元から渡される値)で、どの部分が出力(関数が返す値)であるかを伝える重要な役割を担っていることを明確にしています。これは、ガベージコレクタが正確にポインタを追跡し、不要なメモリを解放するために不可欠な情報です。特に、GoとCの間でポインタが受け渡される場合、ガベージコレクタがC側のメモリを適切に管理するためには、このようなメタデータが必要になります。

これらの変更は、Goランタイムが様々なオペレーティングシステムやアーキテクチャ、特にNaClのような特殊な環境で、より堅牢かつ効率的に動作するための継続的な改善の一環として行われたものです。条件付きコンパイルの削除は、コードの簡素化と、異なる環境間での動作の一貫性の向上に貢献します。goc2cに関するコメントの追加は、GoのガベージコレクションとCgo/goc2cメカニズムの間の相互作用に関する重要な詳細を文書化しています。

コアとなるコードの変更箇所

diff --git a/src/pkg/runtime/arch_amd64.h b/src/pkg/runtime/arch_amd64.h
index 88b68cc6df..060c4d4f53 100644
--- a/src/pkg/runtime/arch_amd64.h
+++ b/src/pkg/runtime/arch_amd64.h
@@ -11,10 +11,6 @@ enum {
 #else
 	RuntimeGogoBytes = 64,
 #endif
-#ifdef GOOS_nacl
-	PhysPageSize = 65536,
-#else
 	PhysPageSize = 4096,
-#endif
 	PCQuantum = 1
 };
diff --git a/src/pkg/runtime/arch_amd64p32.h b/src/pkg/runtime/arch_amd64p32.h
index 88b68cc6df..073a9e30e1 100644
--- a/src/pkg/runtime/arch_amd64p32.h
+++ b/src/pkg/runtime/arch_amd64p32.h
@@ -6,11 +6,7 @@ enum {
 	thechar = '6',
 	BigEndian = 0,
 	CacheLineSize = 64,
-#ifdef GOOS_solaris
-	RuntimeGogoBytes = 80,
-#else
 	RuntimeGogoBytes = 64,
-#endif
 #ifdef GOOS_nacl
 	PhysPageSize = 65536,
 #else
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 0069d5a774..e040c18272 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -795,6 +795,8 @@ int32	runtime·charntorune(int32*, uint8*, int32);\n  * first output value. Almost all code should write such\n  * functions in .goc files, where goc2c (part of cmd/dist)\n  * can arrange the correct alignment for the target system.\n+ * Goc2c also takes care of conveying to the garbage collector\n+ * which parts of the argument list are inputs vs outputs.\n  *\n  * Therefore, do NOT use this macro if at all possible.\n  */ 

コアとなるコードの解説

src/pkg/runtime/arch_amd64.h および src/pkg/runtime/arch_amd64p32.h

これらのファイルは、それぞれAMD64アーキテクチャとAMD64P32(32ビットポインタのAMD64)アーキテクチャに特化したランタイムの定数を定義しています。

  • PhysPageSize の変更:

    • 両方のファイルで、#ifdef GOOS_nacl#endif で囲まれていた PhysPageSize = 65536, の行が削除され、#else 以下の PhysPageSize = 4096, の行が残されています。
    • これは、GoランタイムがNaCl環境においても物理ページサイズを4096バイトとして扱うように統一されたことを意味します。以前はNaCl環境では64KBのページサイズを想定していましたが、この修正により、より一般的な4KBのページサイズに合わせるか、NaCl環境での特別な考慮が不要になったことを示しています。これにより、コードの複雑性が減少し、異なる環境間でのメモリ管理の一貫性が向上します。
  • RuntimeGogoBytes の変更 (arch_amd64p32.h のみ):

    • src/pkg/runtime/arch_amd64p32.h において、#ifdef GOOS_solaris#endif で囲まれていた RuntimeGogoBytes = 80, の行が削除され、#else 以下の RuntimeGogoBytes = 64, の行が残されています。
    • これにより、Solaris環境におけるRuntimeGogoBytesの特別な定義が削除され、他の環境と同じ64バイトに統一されました。これは、Goルーチンのコンテキスト切り替えに関連する内部構造のサイズが、Solarisにおいても他のOSと同一になったことを示唆しています。

src/pkg/runtime/runtime.h

このファイルは、Goランタイムの共通のヘッダーファイルであり、様々なランタイム内部関数やマクロの宣言が含まれています。

  • goc2c に関するコメントの追加:
    • runtime·charntorune 関数のコメントブロック内に、goc2c の追加の役割を説明する新しい行が挿入されています。
    • 追加された行: * Goc2c also takes care of conveying to the garbage collector* which parts of the argument list are inputs vs outputs.
    • このコメントは、goc2c が単にGoとCの間のインターフェースを生成するだけでなく、Goのガベージコレクタに対して、Cgo/goc2c経由で呼び出される関数の引数リストにおいて、どの部分が入力(呼び出し元から渡される値)で、どの部分が出力(関数が返す値)であるかを伝える重要な役割を担っていることを明示しています。これは、ガベージコレクタがポインタを正確に追跡し、メモリリークを防ぐために不可欠な情報です。特に、GoのヒープとCのスタック/ヒープの間でポインタが受け渡される場合、ガベージコレクタが参照を正しく管理するためには、このようなメタデータが必要となります。

これらの変更は、Goランタイムのクロスプラットフォーム対応と内部的なメモリ管理、ガベージコレクションの正確性を向上させるための、細かではあるが重要な修正です。特に、条件付きコンパイルの削除はコードの保守性を高め、goc2cに関するコメントの追加は、Goの複雑なランタイムメカニズムの理解を深めるのに役立ちます。

関連リンク

参考にした情報源リンク