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

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

このコミットでは、Goコンパイラの内部で使用されるヘッダーファイルである src/cmd/5g/gg.hsrc/cmd/6g/gg.h、および src/cmd/8g/gg.h が変更されています。具体的には、これらのヘッダーファイルから一部の関数宣言が削除または移動され、コメントの修正が行われています。

コミット

  • コミットハッシュ: 617b7cf166a99e1fe3326b6fc6985be9f83e51ca
  • 作者: Rémy Oudompheng oudomphe@phare.normalesup.org
  • 日付: 2012年9月27日 木曜日 08:34:00 +0200
  • コミットメッセージ:
    cmd/[568]g: header cleanup.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/6573059
    

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

https://github.com/golang/go/commit/617b7cf166a99e1fe3326b6fc6985be9f83e51ca

元コミット内容

cmd/[568]g: header cleanup.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6573059

変更の背景

このコミットの目的は、Goコンパイラのヘッダーファイルの「クリーンアップ」です。2012年当時のGoコンパイラは、5g (ARM向け)、6g (AMD64向け)、8g (x86向け) といった異なるアーキテクチャをターゲットとする複数のコンパイラで構成されており、これらはPlan 9のツールチェインを起源としていました。

「ヘッダーのクリーンアップ」という表現は、通常、以下のいずれかまたは複数の目的で行われます。

  1. 未使用の宣言の削除: もはやコードベースのどこからも参照されていない関数や変数の宣言をヘッダーファイルから削除し、コードの肥大化を防ぎ、可読性を向上させます。
  2. 宣言の適切な配置: 宣言がその機能に最も関連性の高いヘッダーファイルやセクションに移動されていない場合、それを適切な場所に移動します。これにより、モジュール性が向上し、依存関係が明確になります。
  3. コメントの修正: コードの変更やリファクタリングに伴い、古くなったコメントや誤ったコメントを修正し、コードの意図を正確に反映させます。
  4. 重複の排除: 複数のヘッダーファイルに同じ宣言が重複して存在する場合、それを一箇所に集約します。

このコミットでは、特に gg.h という共通のヘッダーファイル群に対して、これらのクリーンアップ作業が行われたと考えられます。これは、コンパイラ内部のコードベースの保守性と理解しやすさを向上させるための、継続的なリファクタリングの一環です。

前提知識の解説

Goコンパイラ (5g, 6g, 8g)

2012年当時、Go言語の公式コンパイラは gc ツールチェインの一部として提供されており、主に以下の3つのコンパイラが存在しました。

  • 5g: ARMアーキテクチャ(例: Raspberry Piなどの組み込みシステムやモバイルデバイス)をターゲットとするGoコードをコンパイルするためのコンパイラです。
  • 6g: AMD64(x86-64)アーキテクチャ(現在の一般的なデスクトップPCやサーバー)をターゲットとするGoコードをコンパイルするためのコンパイラです。
  • 8g: 386(x86)アーキテクチャ(32ビットのIntel/AMDプロセッサ)をターゲットとするGoコードをコンパイルするためのコンパイラです。

これらのコンパイラは、Go言語のソースコードを各ターゲットアーキテクチャの機械語に変換する役割を担っていました。現在では、これらのコンパイラは go tool compile コマンドの内部で抽象化されており、ユーザーが直接 5g6g を呼び出すことは稀になっています。

gg.h ヘッダーファイル

gg.h は、Goコンパイラの内部で使用されるヘッダーファイルです。C言語やC++におけるヘッダーファイルと同様に、他のソースファイルで利用される関数や変数の宣言(プロトタイプ)を含んでいます。これにより、コンパイラの異なるモジュール間で共通のインターフェースを共有し、コンパイル時に必要な情報を提供します。

Goコンパイラの初期の実装は、C言語の影響を強く受けており、このようなヘッダーファイルが多用されていました。src/cmd/[568]g/gg.h というパスは、各アーキテクチャ固有のコンパイラ (5g, 6g, 8g) のコマンドディレクトリ (src/cmd/5g, src/cmd/6g, src/cmd/8g) の直下に配置されていることを示しています。

src/cmd ディレクトリ構造

Goプロジェクトのソースコードリポジトリにおいて、src/cmd ディレクトリは、Go言語のツールチェイン(コンパイラ、リンカ、アセンブラ、その他のユーティリティ)のソースコードを格納する場所です。各サブディレクトリは、特定のツールやコンパイラのフロントエンドに対応しています。例えば、src/cmd/5g5g コンパイラのソースコードを、src/cmd/6g6g コンパイラのソースコードを含んでいます。

技術的詳細

このコミットで行われた「ヘッダークリーンアップ」は、主に以下の技術的な変更を含んでいます。

  1. gaddoffsetsetconstsetaddr 関数の宣言削除:

    • src/cmd/5g/gg.h から gaddoffsetsetconstsetaddr の3つの関数宣言が削除されています。
    • src/cmd/6g/gg.h から gaddoffset の関数宣言が削除されています。
    • src/cmd/8g/gg.h から gaddoffsetsetconstsetaddr の3つの関数宣言が削除されています。 これらの関数は、おそらくコンパイラの内部で特定のノード(抽象構文木の要素)に対するオフセットの追加、定数値の設定、アドレスの設定などを行うためのものでした。ヘッダーファイルからこれらの宣言が削除されたということは、これらの関数がもはや外部から呼び出される必要がなくなったか、あるいはその機能が別の場所に移管されたことを示唆しています。これは、コンパイラの内部構造がリファクタリングされ、これらの関数がより限定されたスコープで利用されるようになった可能性が高いです。
  2. datastring および datagostring 関数の宣言移動:

    • src/cmd/6g/gg.h から datagostring の関数宣言が削除され、gobj.c セクションに移動されています。
    • src/cmd/8g/gg.h から datastring および datagostring の関数宣言が削除され、gobj.c セクションに移動されています。 datastringdatagostring は、おそらく文字列リテラルやGoの文字列データをオブジェクトファイルに書き込むための関数です。これらの関数が gobj.c セクションに移動されたことは、それらがオブジェクトファイルの生成(gobj.c は "Go Object" の略である可能性が高い)に関連する機能として論理的にグループ化されたことを意味します。これにより、ヘッダーファイルの役割がより明確になり、関連する宣言が一箇所に集約されることで、コードの保守性が向上します。
  3. コメントの修正:

    • src/cmd/6g/gg.h 内のコメントで、gen.cggen.c に、cgencgen.c に修正されています。 これは、ファイル名の誤記を修正するもので、コードの機能には直接影響しませんが、ドキュメントとしての正確性を高め、将来の開発者がコードを理解する上での混乱を防ぎます。

これらの変更は、Goコンパイラの内部構造が進化し、より整理されたモジュール設計へと移行している過程を示しています。不要な宣言の削除や関連する宣言の集約は、コードベースの複雑性を軽減し、長期的なメンテナンスを容易にするための重要なステップです。

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

src/cmd/5g/gg.h

--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -117,14 +117,11 @@ void	clearp(Prog*);
 void	proglist(void);
 Prog*	gbranch(int, Type*, int);
 Prog*	prog(int);
-void	gaddoffset(Node*);
 void	gconv(int, int);
 int	conv2pt(Type*);
 vlong	convvtox(vlong, int);
 void	fnparam(Type*, int, int);
 Prog*	gop(int, Node*, Node*, Node*);
-void	setconst(Addr*, vlong);
-void	setaddr(Addr*, Node*);
 int	optoas(int, Type*);
 void	ginit(void);
 void	gclean(void);

src/cmd/6g/gg.h

--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -58,7 +58,7 @@ EXTERN	Node*	throwreturn;
 extern	vlong	unmappedzero;
 
 /*
- * gen.c
+ * ggen.c
  */
 void	compile(Node*);
 void	proglist(void);
@@ -81,7 +81,7 @@ void	ginscall(Node*, int);
 int	gen_as_init(Node*);
 
 /*
- * cgen
+ * cgen.c
  */
 void	agen(Node*, Node*);
 void	igen(Node*, Node*, Node*);
@@ -103,7 +103,6 @@ void	clearp(Prog*);
 void	proglist(void);
 Prog*	gbranch(int, Type*, int);
 Prog*	prog(int);
-void	gaddoffset(Node*);
 void	gconv(int, int);
 int	conv2pt(Type*);
 vlong	convvtox(vlong, int);
@@ -125,7 +124,6 @@ int	isfat(Type*);
 void	sudoclean(void);
 int	sudoaddable(int, Node*, Addr*);
 void	afunclit(Addr*);
-void	datagostring(Strlit*, Addr*);
 void	nodfconst(Node*, Type*, Mpflt*);
 
 /*
@@ -139,6 +137,7 @@ void	complexgen(Node*, Node*);
  * gobj.c
  */
 void	datastring(char*, int, Addr*);
+void	datagostring(Strlit*, Addr*);
 
 /*
  * list.c

src/cmd/8g/gg.h

--- a/src/cmd/8g/gg.h
+++ b/src/cmd/8g/gg.h
@@ -122,14 +122,11 @@ void	clearp(Prog*);
 void	proglist(void);
 Prog*	gbranch(int, Type*, int);
 Prog*	prog(int);
-void	gaddoffset(Node*);
 void	gconv(int, int);
 int	conv2pt(Type*);
 vlong	convvtox(vlong, int);
 void	fnparam(Type*, int, int);
 Prog*	gop(int, Node*, Node*, Node*);
-void	setconst(Addr*, vlong);
-void	setaddr(Addr*, Node*);
 int	optoas(int, Type*);
 int	foptoas(int, Type*, int);
 void	ginit(void);
@@ -141,8 +138,6 @@ void	nodreg(Node*, Type*, int);
 void	nodindreg(Node*, Type*, int);
 void	nodconst(Node*, Type*, int64);
 void	gconreg(int, vlong, int);
-void	datagostring(Strlit*, Addr*);
-void	datastring(char*, int, Addr*);
 void	buildtxt(void);
 Plist*	newplist(void);
 int	isfat(Type*);
@@ -161,6 +156,12 @@ int	complexop(Node*, Node*);
 void	complexmove(Node*, Node*);
 void	complexgen(Node*, Node*);
 
+/*
+ * gobj.c
+ */
+void	datastring(char*, int, Addr*);
+void	datagostring(Strlit*, Addr*);
+
 /*
  * list.c
  */

コアとなるコードの解説

gaddoffset, setconst, setaddr の削除

これらの関数は、Goコンパイラのコード生成フェーズにおいて、抽象構文木 (AST) のノードやアドレス構造体 (Addr*) を操作するために使用されていたと考えられます。

  • gaddoffset(Node*): ASTノードに関連するオフセットを追加する機能。
  • setconst(Addr*, vlong): 特定のアドレスに定数値を設定する機能。
  • setaddr(Addr*, Node*): 特定のアドレスにASTノードの情報を設定する機能。

これらの宣言が gg.h から削除されたことは、以下のいずれかの理由が考えられます。

  1. 機能の廃止または統合: これらの関数がもはやコンパイラの現在の設計では必要とされなくなったか、あるいはその機能がより高レベルの抽象化された関数に統合された可能性があります。
  2. 内部的な利用への変更: これらの関数が、もはやヘッダーファイルを通じて外部に公開される必要がなく、特定のソースファイル内でのみ使用されるようになった可能性があります。これにより、ヘッダーファイルのインターフェースが簡素化され、モジュール間の結合度が低下します。
  3. より適切なヘッダーへの移動: これらの関数が、より具体的な機能を持つ別のヘッダーファイルに移動された可能性もあります。

いずれにしても、これはコンパイラの内部構造がより整理され、特定の機能がより適切にカプセル化されるようになったことを示唆しています。

datastring および datagostringgobj.c セクションへの移動

  • datastring(char*, int, Addr*): Cスタイルの文字列(char*)をデータセクションに書き込むための関数。
  • datagostring(Strlit*, Addr*): Goの文字列リテラル(Strlit*)をデータセクションに書き込むための関数。

これらの関数は、コンパイルされたプログラムのデータセクションに文字列データを配置する役割を担っています。src/cmd/6g/gg.hsrc/cmd/8g/gg.h からこれらの宣言が削除され、代わりに /* gobj.c */ というコメントブロックの下に再宣言されています。

この変更は、以下の意図があると考えられます。

  1. 論理的なグループ化: gobj.c は「Go Object」に関連するコードを扱うファイルであると推測されます。文字列データをオブジェクトファイルに書き込む機能は、オブジェクト生成のプロセスの一部であるため、これらの関数を gobj.c に関連するセクションに移動することで、コードの論理的な構造が改善されます。
  2. 依存関係の明確化: これにより、datastringdatagostringgobj.c の実装に密接に関連していることが明確になります。ヘッダーファイルは、その宣言がどのソースファイルで実装されているかを示すことで、開発者がコードベースをナビゲートしやすくなります。

コメントの修正 (gen.c -> ggen.c, cgen -> cgen.c)

これは単純なタイポの修正です。gen.cggen.c の誤記であり、cgencgen.c の誤記であったと考えられます。このような修正は、コードのドキュメンテーションとしての正確性を高め、将来のコードリーディングやメンテナンスの際に誤解を防ぐために重要です。

全体として、このコミットはGoコンパイラの内部ヘッダーファイルを整理し、コードの可読性、保守性、およびモジュール性を向上させるための、細かではあるが重要なリファクタリング作業を示しています。

関連リンク

参考にした情報源リンク