[インデックス 18206] ファイルの概要
このコミットは、Go言語の次期リリース(Go 1.2と推測される)に向けたAPIの変更を記録する api/next.txt
ファイルの更新です。具体的には、debug/goobj
パッケージの型に String()
メソッドが追加され、sync
パッケージに Pool
型が導入され、さらにNetBSDおよびWindows向けの syscall
パッケージに多数のシステムコール関連定数や関数が追加されています。
コミット
commit e598bf1c887e565d37bfccf7145fd01a2c655e31
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Thu Jan 9 14:31:10 2014 -0800
api: update next.txt
R=golang-codereviews, minux.ma
CC=golang-codereviews
https://golang.org/cl/50190043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e598bf1c887e565d37bfccf7145fd01a2c655e31
元コミット内容
このコミットは、api/next.txt
ファイルを更新し、Go言語の次期バージョンで導入される予定の新しい公開API要素を追記しています。変更内容は以下の通りです。
debug/goobj
パッケージのSym
,SymID
,SymKind
型にString()
メソッドが追加されました。sync
パッケージにPool
型とそのメソッド (Get
,Put
) およびフィールド (New
) が追加されました。syscall
パッケージに、NetBSD (386およびAMD64アーキテクチャ、CGOの有無を含む) 向けのCLONE_*
,MADV_*
,MAP_*
,MCL_*
,MS_*
,PROT_*
といった多数のシステムコール関連定数が追加されました。syscall
パッケージに、Windows (386およびAMD64アーキテクチャ) 向けのNewCallbackCDecl
関数が追加されました。
変更の背景
このコミットの背景には、Go言語の標準ライブラリの機能拡張と、異なるオペレーティングシステム(特にNetBSDとWindows)におけるシステムコールへの対応強化があります。
-
api/next.txt
の役割:api/next.txt
は、Go言語のリリースプロセスにおいて非常に重要なファイルです。このファイルは、次のメジャーリリースで公開される予定のAPIの変更点(追加、削除、変更)を記録するために使用されます。Go言語の互換性ポリシーでは、既存の公開APIを破壊的に変更することは極力避けるため、新しいAPIの追加は慎重に行われ、このファイルを通じて追跡されます。このコミットは、開発中の新機能や改善がAPIとして安定し、公開される準備ができたことを示しています。 -
debug/goobj
のString()
メソッド:debug/goobj
パッケージは、Goのオブジェクトファイル(.o
ファイル)を解析するための機能を提供します。Sym
(シンボル)、SymID
(シンボルID)、SymKind
(シンボルの種類)といった型にString()
メソッドが追加されることで、これらのオブジェクトファイル内の要素を人間が読みやすい形式で表現できるようになります。これはデバッグやツール開発において非常に有用です。 -
sync.Pool
の導入:sync.Pool
は、一時的なオブジェクトの再利用を目的としたGoの標準ライブラリの機能です。頻繁に生成・破棄されるオブジェクト(例: バイトスライス、バッファ)がある場合、その都度メモリを確保・解放するとガベージコレクション(GC)の負荷が増大し、パフォーマンスが低下する可能性があります。sync.Pool
を使用することで、これらのオブジェクトをプールしておき、必要に応じて再利用することで、メモリ割り当てのオーバーヘッドを削減し、GCの頻度を減らすことができます。これは、特に高負荷なサーバーアプリケーションなどでパフォーマンスを向上させるための重要な最適化手段となります。 -
syscall
パッケージの拡張:syscall
パッケージは、GoプログラムからOSのシステムコールを直接呼び出すためのインターフェースを提供します。- NetBSD: NetBSDは、UNIX系のオープンソースオペレーティングシステムであり、様々なアーキテクチャをサポートしています。
CLONE_*
(プロセス生成)、MADV_*
(メモリ使用のヒント)、MAP_*
(メモリマッピング)、MCL_*
(メモリロック)、MS_*
(メモリ同期)、PROT_*
(メモリ保護)といった定数の追加は、GoプログラムがNetBSD上でより低レベルなシステムリソース管理やプロセス間通信、メモリ操作を直接行えるようにするためのものです。これにより、GoアプリケーションがNetBSDの特定の機能やパフォーマンス特性を最大限に活用できるようになります。 - Windows: Windows向けの
NewCallbackCDecl
関数の追加は、GoとC言語(またはC++)で書かれたライブラリとの相互運用性(CGO)を強化するためのものです。__cdecl
はC言語の標準的な呼び出し規約であり、この関数を使用することで、Goの関数をC言語のライブラリが呼び出せる形式に変換できるようになります。これは、既存のWindows APIやサードパーティのC/C++ライブラリをGoから利用する際に不可欠な機能です。
- NetBSD: NetBSDは、UNIX系のオープンソースオペレーティングシステムであり、様々なアーキテクチャをサポートしています。
これらの変更は、Go言語がより多様なプラットフォームで、より高性能かつ低レベルな操作を可能にするための継続的な進化の一環として行われました。
前提知識の解説
このコミットの技術的詳細を理解するためには、以下の前提知識が役立ちます。
-
Go言語のAPI互換性: Go言語は、後方互換性を非常に重視しています。一度公開されたAPIは、原則として変更または削除されません。新しい機能が追加される場合、それは既存のAPIを壊さない形で行われます。
api/next.txt
は、この互換性ポリシーを維持しつつ、将来のAPI変更を追跡するためのメカニズムです。 -
Goのオブジェクトファイル (
.o
ファイル): Goコンパイラがソースコードをコンパイルすると、中間形式としてオブジェクトファイルが生成されます。これらのファイルには、コンパイルされたコード、データ、そしてシンボル情報(関数名、変数名など)が含まれています。debug/goobj
パッケージは、これらのオブジェクトファイルをプログラム的に解析するためのツールを提供します。 -
ガベージコレクション (GC): Go言語は、自動メモリ管理(ガベージコレクション)を採用しています。プログラマは明示的にメモリを解放する必要がありません。しかし、頻繁なメモリ割り当てと解放はGCのオーバーヘッドを増加させ、アプリケーションのレイテンシやスループットに影響を与える可能性があります。
-
オブジェクトプール: オブジェクトプールは、リソース管理のパターンの一つです。コストの高いオブジェクト(メモリ割り当て、ネットワーク接続、データベース接続など)を事前に作成しておき、必要に応じてプールから取得し、使用後にプールに戻すことで、オブジェクトの生成・破棄にかかるオーバーヘッドを削減します。
-
システムコール (System Call): システムコールは、ユーザー空間のプログラムがオペレーティングシステム(OS)のカーネル空間のサービスを要求するためのインターフェースです。ファイルI/O、プロセス管理、メモリ管理、ネットワーク通信など、OSが提供するほとんどの機能はシステムコールを通じて利用されます。Goの
syscall
パッケージは、これらの低レベルなOS機能へのアクセスを提供します。 -
メモリ管理関連のシステムコール:
mmap()
: ファイルや匿名メモリ領域をプロセスのアドレス空間にマッピングするためのシステムコール。メモリマップドファイルや共有メモリの実現に用いられます。madvise()
: プロセスがメモリ領域をどのように使用するかについて、カーネルにヒントを与えるためのシステムコール。これにより、カーネルはメモリ管理の最適化を行うことができます(例:MADV_DONTNEED
は、そのメモリ領域がもう必要ないことを示唆し、カーネルが解放するのを助けます)。mprotect()
: メモリ領域の保護属性(読み取り、書き込み、実行)を変更するためのシステムコール。mlockall()
: プロセスのアドレス空間全体、または指定されたメモリ領域を物理メモリにロックし、スワップアウトされないようにするためのシステムコール。リアルタイムアプリケーションなどで使用されます。msync()
: メモリマップドファイルの内容をディスクと同期するためのシステムコール。
-
プロセス管理関連のシステムコール:
clone()
(Linux/NetBSD): 新しいプロセス(またはスレッド)を作成するためのシステムコール。親プロセスと様々なリソース(メモリ空間、ファイルディスクリプタ、シグナルハンドラなど)を共有するかどうかを細かく制御できます。CLONE_*
フラグは、この共有の挙動を定義します。
-
呼び出し規約 (Calling Convention): 関数が呼び出される際に、引数がどのようにスタックに積まれ、レジスタがどのように使用され、戻り値がどのように返されるかなどを定義するルールセットです。異なるプログラミング言語やコンパイラは、異なる呼び出し規約を使用することがあります。
__cdecl
: C言語の標準的な呼び出し規約の一つで、呼び出し側がスタックをクリーンアップします。Windows APIなどで広く使われています。
技術的詳細
debug/goobj
パッケージの拡張
debug/goobj
パッケージは、Goのコンパイラやリンカが生成するオブジェクトファイル(.o
ファイル)の内部構造を解析するための低レベルなAPIを提供します。このコミットでは、以下の型に String()
メソッドが追加されました。
Sym
: オブジェクトファイル内のシンボル(関数、変数など)を表す型。SymID
: シンボルを一意に識別するためのID。SymKind
: シンボルの種類(例: テキストセクション、データセクションなど)を表す列挙型。
String()
メソッドは、Goの fmt
パッケージによって自動的に呼び出され、その型の値を人間が読みやすい文字列形式に変換します。これにより、debug/goobj
を利用するツール(例: go tool objdump
のようなデバッガやプロファイラ)が、シンボル情報をより分かりやすく表示できるようになります。これは、Goのバイナリを解析したり、デバッグ情報を抽出したりする際の利便性を向上させます。
sync.Pool
の導入
sync.Pool
は、Go 1.3で導入された、一時的なオブジェクトを効率的に再利用するためのメカニズムです。その主な目的は、頻繁に割り当てられ、すぐに不要になるオブジェクト(例: HTTPリクエストの処理中に使用されるバッファ、JSONエンコーダ/デコーダのインスタンスなど)のガベージコレクションの負荷を軽減することです。
sync.Pool
の構造は非常にシンプルです。
type Pool struct {
New func() interface{}
// contains filtered or unexported fields
}
New func() interface{}
: プールが空のときに新しいオブジェクトを生成するための関数です。この関数は、Get()
メソッドがプール内に利用可能なオブジェクトを見つけられなかった場合に呼び出されます。
提供されるメソッドは以下の通りです。
func (p *Pool) Get() interface{}
: プールからオブジェクトを取得します。プールに利用可能なオブジェクトがあればそれを返し、なければp.New
関数を呼び出して新しいオブジェクトを生成して返します。返される値はinterface{}
型なので、使用する際には適切な型アサーションが必要です。func (p *Pool) Put(x interface{})
: オブジェクトをプールに戻します。プールに戻されたオブジェクトは、将来のGet()
呼び出しで再利用される可能性があります。
sync.Pool
は、スレッドセーフであり、複数のGoroutineから安全にアクセスできます。ただし、プールされたオブジェクトはGCの対象となる可能性があり、プールされたオブジェクトがいつ解放されるかは保証されません。そのため、sync.Pool
はあくまで一時的なオブジェクトの再利用に限定して使用すべきであり、永続的なオブジェクトの管理には適していません。
NetBSD向け syscall
パッケージの拡張
NetBSDは、移植性の高さで知られるUNIX系OSです。このコミットでは、NetBSDの386およびAMD64アーキテクチャ(CGOの有無を含む)向けに、多数のシステムコール関連定数が追加されました。これらは、GoプログラムがNetBSD上で低レベルなOS機能にアクセスするために使用されます。
-
CLONE_*
定数: これらは、プロセスやスレッドの作成に関連するclone()
システムコール(Linux由来の概念だが、NetBSDにも類似の機能や互換性レイヤーが存在する可能性がある)のフラグです。例えば、CLONE_VM
は親とメモリ空間を共有、CLONE_FILES
はファイルディスクリプタを共有、CLONE_SIGHAND
はシグナルハンドラを共有するといった意味を持ちます。これにより、GoプログラムはNetBSD上でより柔軟なプロセス生成やスレッド管理が可能になります。 -
MADV_*
定数:madvise()
システムコールで使用されるフラグです。MADV_DONTNEED
: 指定されたメモリ領域の内容がもう必要ないことをカーネルに通知し、解放を促します。MADV_FREE
: メモリ領域を解放可能であることを示唆しますが、必要になるまで物理メモリを保持します。MADV_NORMAL
,MADV_RANDOM
,MADV_SEQUENTIAL
: メモリアクセスパターンに関するヒントをカーネルに与えます。MADV_WILLNEED
: 指定されたメモリ領域がすぐに必要になることをカーネルに通知し、プリフェッチを促します。
-
MAP_*
定数:mmap()
システムコールで使用されるフラグです。MAP_ANON
: ファイルではなく匿名メモリ領域をマッピングします。MAP_PRIVATE
: プライベートなコピーオンライトマッピングを作成します。MAP_SHARED
: 共有メモリマッピングを作成します。MAP_FIXED
: 指定されたアドレスにマッピングを試みます。MAP_STACK
: スタック領域として使用されるメモリをマッピングします。 その他、アライメントに関する定数 (MAP_ALIGNMENT_*
) なども追加されています。
-
MCL_*
定数:mlockall()
システムコールで使用されるフラグです。MCL_CURRENT
: 現在マッピングされているすべてのページをロックします。MCL_FUTURE
: 将来マッピングされるすべてのページをロックします。
-
MS_*
定数:msync()
システムコールで使用されるフラグです。MS_ASYNC
: 非同期で変更をディスクに書き込みます。MS_SYNC
: 同期的に変更をディスクに書き込みます。MS_INVALIDATE
: キャッシュされたデータを無効化します。
-
PROT_*
定数:mmap()
やmprotect()
システムコールで使用されるメモリ保護フラグです。PROT_READ
: 読み取り可能。PROT_WRITE
: 書き込み可能。PROT_EXEC
: 実行可能。PROT_NONE
: アクセス不可。
これらの定数の追加により、GoプログラムはNetBSD上でより高度なメモリ管理、プロセス間通信、および低レベルなリソース操作を直接行えるようになり、システムプログラミングの可能性が広がります。
Windows向け syscall
パッケージの拡張
Windows向けの syscall
パッケージには、NewCallbackCDecl
関数が追加されました。
-
func NewCallbackCDecl(interface{}) uintptr
: この関数は、Goの関数をWindowsのC言語の呼び出し規約 (__cdecl
) に従うコールバック関数として利用できるようにするためのものです。Windows APIの多くはC言語で定義されており、コールバック関数を引数として受け取るものも少なくありません。NewCallbackCDecl
を使用することで、Goで実装された関数をこれらのWindows APIに渡すことが可能になります。具体的には、Goの関数を
uintptr
型のポインタに変換し、そのポインタをCGOを通じてC言語のコードに渡すことで、C言語側からGoの関数を呼び出すことができるようになります。これは、GoプログラムがWindowsのネイティブAPIやDLL(Dynamic Link Library)と連携する上で不可欠な機能であり、WindowsプラットフォームでのGoアプリケーションの機能性を大幅に向上させます。
コアとなるコードの変更箇所
このコミットは、api/next.txt
ファイルのみを変更しています。このファイルは、Go言語の公開APIの変更を記録するためのテキストファイルであり、実際のGoのソースコード(.go
ファイル)の変更は含まれていません。
--- a/api/next.txt
+++ b/api/next.txt
@@ -65,6 +65,9 @@ pkg debug/goobj, const SWINDOWS SymKind
pkg debug/goobj, const SXREF = 24
pkg debug/goobj, const SXREF SymKind
pkg debug/goobj, func Parse(io.ReadSeeker, string) (*Package, error)
+pkg debug/goobj, method (Sym) String() string
+pkg debug/goobj, method (SymID) String() string
+pkg debug/goobj, method (SymKind) String() string
pkg debug/goobj, type Data struct
pkg debug/goobj, type Data struct, Offset int64
pkg debug/goobj, type Data struct, Size int64
@@ -110,3 +113,401 @@ pkg debug/goobj, type Var struct, Kind int
pkg debug/goobj, type Var struct, Name string
pkg debug/goobj, type Var struct, Offset int
pkg debug/goobj, type Var struct, Type SymID
+pkg sync, method (*Pool) Get() interface{}
+pkg sync, method (*Pool) Put(interface{})
+pkg sync, type Pool struct
+pkg sync, type Pool struct, New func() interface{}
+pkg syscall (netbsd-386), const CLONE_CSIGNAL = 255
+pkg syscall (netbsd-386), const CLONE_CSIGNAL ideal-int
+... (以下、NetBSDおよびWindowsのsyscall関連の追加が続く)
コアとなるコードの解説
前述の通り、このコミット自体はGoのソースコードの変更を含まず、api/next.txt
というAPI変更履歴ファイルを更新するものです。したがって、ここに示されている変更箇所は、Goの次期リリースで公開されるAPIの「宣言」であり、そのAPIを実装する実際のGoのコードは、このコミット以前または同時に別のコミットで追加されています。
例えば、pkg sync, type Pool struct
の行は、sync
パッケージに Pool
という新しい型が追加されることを示しています。この Pool
型の具体的な実装(sync/pool.go
など)は、この api/next.txt
の更新とは別のコミットでGoのソースツリーに追加されています。
同様に、pkg syscall (netbsd-386), const CLONE_CSIGNAL = 255
のような行は、NetBSDの syscall
パッケージに CLONE_CSIGNAL
という定数が追加されることを示しており、この定数の定義は syscall/zsysnum_netbsd_386.go
のようなファイルに存在します。
このコミットの「コアとなるコードの変更箇所」は、GoのAPI互換性ポリシーとリリースプロセスを理解する上で重要です。api/next.txt
は、Goの公開APIの安定性を保証するための重要なドキュメントであり、このファイルへの追加は、新しいAPIがGoの標準ライブラリの一部として正式に公開される準備ができたことを意味します。
関連リンク
- Go言語の互換性保証: https://go.dev/doc/go1compat
sync.Pool
のドキュメント: https://pkg.go.dev/sync#Pool- Goの
syscall
パッケージ: https://pkg.go.dev/syscall - Goの
debug/goobj
パッケージ: https://pkg.go.dev/debug/goobj
参考にした情報源リンク
- Go言語の公式ドキュメント
- Go言語のソースコードリポジトリ (GitHub)
- UNIX系OSのシステムコールに関する一般的な知識
- Windows APIおよびCGOに関する一般的な知識
sync.Pool
の設計に関する議論 (GoのメーリングリストやIssueトラッカー)- NetBSDのシステムコールに関するドキュメント (必要に応じて)
- Go 1.3 リリースノート (sync.Poolが導入されたバージョン)
- Go 1.2 リリースノート (このコミットが対象とする可能性のあるバージョン)
- https://go.dev/doc/go1.2
- https://go.dev/doc/go1.2#syscall
- https://go.dev/doc/go1.2#debug_goobj
sync.Pool
はGo 1.3で導入されたため、このコミットはGo 1.2のAPI更新とGo 1.3のAPI更新の両方を含んでいる可能性があります。api/next.txt
は次のリリースに向けた変更を記録するため、Go 1.2のリリース直前またはGo 1.3の開発初期段階のコミットと考えられます。