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

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

このコミットは、Go言語のコンパイラツールチェーンの一部である cmd/6c におけるビルドエラーを修正するものです。具体的には、src/cmd/6c/swt.c ファイル内の型アライメントまたはサイズ計算に関するコピー&ペーストエラーを修正し、xround 関数の引数を SZ_LONG から SZ_VLONG に変更することで、コンパイラの正確な動作を保証します。

コミット

commit 07e87885ad4094aa27f166d1e666b29b910c0429
Author: Russ Cox <rsc@golang.org>
Date:   Mon Feb 18 13:29:55 2013 -0500

    cmd/6c: fix build
    
    copy+paste error while cleaning up CL 7303099 before submit
    
    R=ken2
    CC=golang-dev
    https://golang.org/cl/7308104
---
 src/cmd/6c/swt.c | 2 +--
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c
index 53b12d9941..068401e19b 100644
--- a/src/cmd/6c/swt.c
+++ b/src/cmd/6c/swt.c
@@ -626,7 +626,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 int32
 maxround(int32 max, int32 v)
 {
-	v = xround(v, SZ_LONG);
+	v = xround(v, SZ_VLONG);
 	if(v > max)
 		return v;
 	return max;

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

https://github.com/golang/go/commit/07e87885ad4094aa27f166d1e666b29b910c0429

元コミット内容

このコミットの元々の内容は、「cmd/6c: ビルドを修正」という簡潔なものです。詳細な説明として、「CL 7303099 を提出する前のクリーンアップ中にコピー&ペーストエラーが発生した」と述べられています。これは、以前の変更セット(Change List, CL)の作業中に誤って不正確なコードが導入され、それがビルドエラーを引き起こしたことを示唆しています。

変更の背景

この変更の背景には、Goコンパイラの開発プロセスにおける一般的なバグ修正のシナリオがあります。コミットメッセージに明記されているように、以前の変更セットである「CL 7303099」のクリーンアップ作業中に、開発者が誤ってコピー&ペーストエラーを犯し、それが cmd/6c のビルドを妨げる問題を引き起こしました。

Go言語のコンパイラは、異なるアーキテクチャ(例: 6camd64 または x86-64 を指すことが多い)向けにコードを生成する際に、厳密な型サイズとアライメントの規則に従う必要があります。xround 関数は、おそらく特定のサイズに値を丸めるために使用されるユーティリティ関数であり、SZ_LONGSZ_VLONG はそれぞれ異なるデータ型のサイズまたはアライメント要件を表す定数です。

元のCL 7303099がどのような変更を含んでいたかは不明ですが、そのクリーンアップ作業中に、本来 SZ_VLONG を使用すべき箇所で誤って SZ_LONG がコピー&ペーストされたと考えられます。この不整合が、コンパイラのビルドプロセスにおいて型システムやメモリレイアウトに関するエラーを引き起こしたため、このコミットで修正されることになりました。

前提知識の解説

Go言語のコンパイラツールチェーン (cmd/6c)

Go言語のコンパイラは、ソースコードを機械語に変換する役割を担います。Goのコンパイラツールチェーンは、go tool compilego tool link など、複数のツールで構成されています。cmd/6c は、Goの初期のコンパイラツールチェーンの一部であり、特に amd64 (64ビットIntel/AMDプロセッサ) アーキテクチャ向けのコンパイラを指すことが多かったです。Goのコンパイラは、C言語で書かれた部分とGo言語で書かれた部分が混在しており、swt.c のようなC言語のファイルは、コンパイラのバックエンドやコード生成、型システム処理など、低レベルな部分を担っていました。

型アライメントとサイズ (SZ_LONG, SZ_VLONG)

コンピュータのメモリは、バイト単位でアドレス指定されますが、プロセッサは特定のバイト境界(アライメント)に配置されたデータに効率的にアクセスできます。データ型にはそれぞれサイズがあり、メモリ上での配置にはアライメントの制約があります。

  • SZ_LONG: 一般的に、C言語における long 型のサイズまたはアライメントを表す定数です。システムによって異なりますが、32ビットシステムでは4バイト、64ビットシステムでは8バイトであることが多いです。
  • SZ_VLONG: VLONG は "Very Long" または "Variable Long" の略である可能性がありますが、Goコンパイラの文脈では、より大きな整数型、例えば64ビット整数(int64)や、特定のプラットフォームにおける最大のアライメント要件を持つ型(例: double やポインタ)のサイズまたはアライメントを表す定数である可能性が高いです。この定数が SZ_LONG と異なるということは、処理対象のデータが long 型よりも大きなサイズやより厳密なアライメントを必要とする型であったことを示唆しています。

xround 関数

xround 関数は、Goコンパイラの内部で使われるユーティリティ関数で、おそらく値を特定のアライメント境界に丸める(アラインする)ために使用されます。例えば、メモリ割り当ての際に、確保するメモリのサイズを特定のアライメントの倍数に切り上げる、といった用途が考えられます。

関数のシグネチャ int32 maxround(int32 max, int32 v) と、その内部で v = xround(v, SZ_LONG); または v = xround(v, SZ_VLONG); が呼び出されていることから、xroundvSZ_LONG または SZ_VLONG の倍数に切り上げる(または切り捨てる)処理を行っていると推測されます。maxround 関数自体は、maxv のうち、v をアラインした後の値と比較して大きい方を返す関数であるようです。

CL (Change List)

Goプロジェクトでは、変更を提出する際に「Change List (CL)」という単位で管理されます。これは、Gerritなどのコードレビューシステムで使われる概念で、一連の変更をまとめたものです。コミットメッセージにある「CL 7303099」は、このコミットの前に存在した、関連する変更セットの識別子です。

技術的詳細

このコミットの技術的な核心は、src/cmd/6c/swt.c ファイル内の maxround 関数における xround の第2引数の変更です。

変更前: v = xround(v, SZ_LONG); 変更後: v = xround(v, SZ_VLONG);

この変更は、v の値を丸める際のアライメントまたはサイズ指定を SZ_LONG から SZ_VLONG に変更することを意味します。

考えられるシナリオは以下の通りです。

  1. 型サイズの不整合: maxround 関数が処理している v の値が、実際には long 型よりも大きなサイズ(例えば long long やポインタ、あるいは特定の構造体)を表すものであったにもかかわらず、誤って SZ_LONG で丸められていた。これにより、メモリのアライメントが正しく行われず、コンパイラが生成するコードが不正なメモリアクセスを引き起こしたり、データが正しく配置されなかったりする可能性がありました。
  2. プラットフォーム固有のアライメント要件: 特定のアーキテクチャ(amd64 など)において、特定のデータ型や構造体に対するアライメント要件が SZ_LONG よりも厳しく、SZ_VLONG がそのより厳密な要件を満たすために必要であった。
  3. コピー&ペーストエラー: 開発者が別の場所からコードをコピー&ペーストした際に、本来 SZ_VLONG を使うべき箇所で SZ_LONG を誤って貼り付けてしまった。これは、コミットメッセージに「copy+paste error」と明記されていることから、最も可能性の高い原因です。

この修正により、maxround 関数が処理する値が、より適切な SZ_VLONG のアライメント境界に丸められるようになり、コンパイラの内部的なデータ構造やコード生成におけるメモリレイアウトの正確性が向上します。結果として、コンパイラのビルドエラーが解消され、生成されるバイナリの安定性と正確性が保証されます。

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

変更は src/cmd/6c/swt.c ファイルの maxround 関数内の一行のみです。

--- a/src/cmd/6c/swt.c
+++ b/src/cmd/6c/swt.c
@@ -626,7 +626,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 int32
 maxround(int32 max, int32 v)
 {
-	v = xround(v, SZ_LONG);
+	v = xround(v, SZ_VLONG);
 	if(v > max)
 		return v;
 	return max;

コアとなるコードの解説

maxround 関数は、2つの int32 型の引数 maxv を受け取ります。この関数は、v を特定のアライメントに丸めた後、その丸めた v の値と max の値を比較し、大きい方を返します。

変更された行は v = xround(v, SZ_LONG); から v = xround(v, SZ_VLONG); です。

  • xround(v, SZ_LONG): v の値を SZ_LONG で指定されるサイズまたはアライメントの倍数に丸めます。
  • xround(v, SZ_VLONG): v の値を SZ_VLONG で指定されるサイズまたはアライメントの倍数に丸めます。

この変更は、maxround 関数が処理する値 v が、SZ_LONG よりも SZ_VLONG のアライメント要件に合致する必要があることを示しています。これは、v が表すデータが、より大きなサイズやより厳密なアライメントを必要とする型(例えば、64ビット整数やポインタなど)に関連しているためと考えられます。この修正により、コンパイラがメモリレイアウトを計算する際の正確性が向上し、ビルドエラーが解消されました。

関連リンク

参考にした情報源リンク

  • Go言語のコンパイラに関する一般的な情報 (Goの公式ドキュメントやソースコードリポジトリ)
  • C言語における型アライメントに関する一般的な情報
  • Go言語の初期のコンパイラツールチェーン (6c など) に関する歴史的情報 (Goのメーリングリストや古いドキュメント)
  • Gerrit (Goプロジェクトが使用するコードレビューシステム) に関する情報