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

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

このコミットは、Go言語のリンカである cmd/5l (ARMアーキテクチャ向けリンカ) におけるメモリ使用量の最適化を目的としています。具体的には、リンカが内部的に使用する Prog および Sym という2つの重要なデータ構造のサイズを削減することで、リンカのフットプリントを小さくし、パフォーマンスを向上させます。

コミット

commit 9b568ef2b86ad383e5db9bc57723d4ce554a319e
Author: Dave Cheney <dave@cheney.net>
Date:   Sun Jan 20 20:14:24 2013 +1100

    cmd/5l: reduce the size of Prog and Sym
    
    Prog
    * Remove the unused Prog* dlink
    * note that align is also unused, but removing it does not help due to alignment issues.
    
    Saves 4 bytes, sizeof(Prog): 84 => 80.
    
    Sym
    * Align {u,}char fields on word boundaries
    
    Saves 4 bytes, sizeof(Sym): 136 => 132.
    
    Tested on linux/arm and freebsd/arm.
    
    R=minux.ma, remyoudompheng, rsc
    CC=golang-dev
    https://golang.org/cl/7106050

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

https://github.com/golang/go/commit/9b568ef2b86ad383e5db9bc57723d4ce554a319e

元コミット内容

このコミットの目的は、Goリンカ cmd/5l における Prog および Sym 構造体のサイズを削減することです。

Prog 構造体については、未使用の Prog* dlink フィールドを削除しました。これにより、Prog のサイズが84バイトから80バイトに4バイト削減されました。align フィールドも未使用ですが、アライメントの問題により削除してもサイズ削減に寄与しないため、そのまま残されています。

Sym 構造体については、uchar 型のフィールドをワード境界にアライメントするように再配置しました。これにより、Sym のサイズが136バイトから132バイトに4バイト削減されました。

これらの変更は linux/arm および freebsd/arm 環境でテストされています。

変更の背景

Go言語のリンカは、コンパイルされたオブジェクトファイルを結合して実行可能ファイルを生成する重要なツールです。リンカの内部では、プログラムの命令やシンボル情報を表現するために様々なデータ構造が使用されます。これらのデータ構造が大きくなると、リンカが消費するメモリ量が増加し、特にリソースが限られた環境(例えば組み込みシステムや古いハードウェア)でのビルド時間や実行効率に影響を与える可能性があります。

このコミットの背景には、リンカのメモリフットプリントを削減し、全体的なパフォーマンスを向上させるという目的があります。特に、ProgSym はリンカの処理中に大量に生成・操作される可能性のあるコアなデータ構造であるため、これらのサイズをわずかでも削減することは、リンカ全体のメモリ使用量に大きな影響を与えます。

また、Go言語はクロスコンパイルを重視しており、様々なアーキテクチャ(ARMなど)をサポートしています。cmd/5l はARMアーキテクチャ向けのリンカであり、ARMのようなリソース制約のある環境では、メモリ効率の最適化が特に重要になります。

前提知識の解説

1. リンカ (Linker)

リンカは、コンパイラによって生成された一つ以上のオブジェクトファイル(機械語コードとデータ、シンボル情報を含む)を結合し、実行可能なプログラムやライブラリを生成するシステムソフトウェアです。リンカの主な役割は以下の通りです。

  • シンボル解決 (Symbol Resolution): オブジェクトファイル間で未解決のシンボル参照(例えば、あるファイルで定義された関数を別のファイルから呼び出す場合)を解決し、正しいメモリアドレスにリンクします。
  • 再配置 (Relocation): オブジェクトファイル内のコードやデータが、最終的な実行可能ファイル内のどこに配置されるかに応じて、アドレス参照を調整します。
  • ライブラリの結合 (Library Linking): 静的ライブラリや動的ライブラリから必要なコードやデータを実行可能ファイルに含めます。

Go言語では、各アーキテクチャ(例: amd64, arm, arm64)に対応するリンカが存在し、それぞれ cmd/6l, cmd/5l, cmd/7l といった命名規則が使われていました(現在は cmd/link に統合されていますが、このコミット当時は分離されていました)。cmd/5l はARMアーキテクチャ向けのリンカです。

2. 構造体のアライメント (Struct Alignment) とパディング (Padding)

コンピュータのメモリは通常、バイト単位でアドレス指定されますが、CPUは特定のサイズのデータ(例えば4バイトの整数や8バイトのポインタ)を、そのサイズと同じ境界(アライメント)に配置されている場合に最も効率的にアクセスできます。例えば、4バイトの整数は4の倍数のアドレスに配置されるのが理想的です。

プログラミング言語の構造体(struct)では、複数のフィールドが連続してメモリに配置されますが、CPUの効率的なアクセスを保証するために、コンパイラはフィールド間に「パディング」と呼ばれる未使用のバイトを挿入することがあります。

例:

struct Example {
    char c1;  // 1バイト
    int i;    // 4バイト
    char c2;  // 1バイト
};

この構造体では、c1 の後に i が続く場合、i が4バイト境界に配置されるように c1 の後に3バイトのパディングが挿入されることがあります。同様に、i の後に c2 が続く場合も、構造体全体のサイズが最も大きいフィールドのサイズ(この場合は int の4バイト)の倍数になるように、c2 の後にパディングが挿入されることがあります。

フィールドの順序を変更することで、パディングの量を最小限に抑え、構造体全体のサイズを削減できる場合があります。これは「構造体パッキング (struct packing)」または「構造体レイアウトの最適化」と呼ばれます。

3. Go言語のリンカにおける ProgSym 構造体

  • Prog 構造体: リンカの内部では、プログラムの機械語命令は Prog (Program) 構造体のリストとして表現されます。各 Prog インスタンスは、単一の命令やデータ定義、またはリンカが処理する必要のあるその他のプログラム要素を表します。これには、命令の種類、オペランド、参照先のシンボル、行番号などの情報が含まれます。リンカはこれらの Prog オブジェクトを走査し、最終的な実行可能ファイルを構築します。

  • Sym 構造体: Sym (Symbol) 構造体は、プログラム内のシンボル(関数名、グローバル変数名、ラベルなど)に関する情報を格納します。各 Sym インスタンスは、シンボルの名前、種類(関数、データなど)、サイズ、アドレス、外部参照かどうか、エクスポートされるかどうかなどの詳細を保持します。リンカはシンボルテーブルを構築し、Sym オブジェクトを使用してシンボル解決と再配置を行います。

これらの構造体はリンカの動作中に頻繁に生成、アクセス、および操作されるため、そのサイズはリンカのメモリ使用量とパフォーマンスに直接的な影響を与えます。

技術的詳細

このコミットは、src/cmd/5l/l.h ヘッダーファイル内の Prog および Sym 構造体の定義を変更することで、メモリフットプリントを削減しています。

Prog 構造体の変更

Prog 構造体から dlink フィールドが削除されました。 元の定義:

struct Prog {
    // ...
    Prog*   cond;
    Prog*   link;
    Prog*   dlink; // 削除対象
    int32   pc;
    // ...
};

変更後:

struct Prog {
    // ...
    Prog*   cond;
    Prog*   link;
    // Prog*   dlink; // 削除
    int32   pc;
    // ...
};

コミットメッセージによると、dlink フィールドは未使用であったため、削除してもリンカの機能に影響はありません。ポインタ (Prog*) は通常、システムアーキテクチャのワードサイズ(ARM 32-bitでは4バイト)と同じサイズを持つため、この削除により Prog 構造体のサイズが4バイト削減されました。

また、align フィールドについては、コミットメッセージで「unused」と明記されていますが、削除されていません。これは、align フィールドを削除しても、構造体のアライメント要件により、コンパイラがその分のパディングを挿入してしまうため、結果的に構造体全体のサイズは変わらないという判断があったためです。コメント // unused が追加され、その状態が明示されました。

Sym 構造体の変更

Sym 構造体では、uchar 型のフィールド stkcheckhide の位置が変更されました。 元の定義:

struct Sym {
    // ...
    uchar   reachable;
    uchar   dynexport;
    uchar   leaf;
    uchar   stkcheck; // 移動対象
    uchar   hide;     // 移動対象
    int32   dynid;
    // ...
};

変更後:

struct Sym {
    // ...
    uchar   reachable;
    uchar   dynexport;
    uchar   leaf;
    // uchar   stkcheck; // 移動
    // uchar   hide;     // 移動
    int32   dynid;
    // ...
    uchar   special;
    uchar   fnptr;    // used as fn ptr
    uchar   stkcheck; // 新しい位置
    uchar   hide;     // 新しい位置
    Sym*    hash;
    // ...
};

uchar は1バイトのデータ型です。int32 は4バイトです。元の構造体では、3つの uchar (reachable, dynexport, leaf) の後に stkcheckhide が続き、その後に int32 が来ていました。この配置では、int32 dynid が4バイト境界にアライメントされるように、leaf, stkcheck, hide の後にパディングが挿入されていた可能性があります。

新しい配置では、stkcheckhide が、他の uchar フィールド (special, fnptr) の近くに移動されました。これにより、コンパイラが構造体をレイアウトする際に、uchar フィールドをまとめて配置し、その後に続く Sym* hash (ポインタ、4バイト) などのより大きなアライメント要件を持つフィールドとの間のパディングを最適化できたと考えられます。結果として、Sym 構造体全体のサイズが4バイト削減されました。これは、コンパイラが生成するパディングの量が減ったことを意味します。

削減効果

  • Prog 構造体: 84バイト → 80バイト (4バイト削減)
  • Sym 構造体: 136バイト → 132バイト (4バイト削減)

これらの削減は、リンカが処理する命令やシンボルの数が多いほど、全体的なメモリ使用量に大きな影響を与えます。

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

変更は src/cmd/5l/l.h ファイルに集中しています。

--- a/src/cmd/5l/l.h
+++ b/src/cmd/5l/l.h
@@ -108,7 +108,6 @@ struct	Prog
 	} u0;
 	Prog*	cond;
 	Prog*	link;
-	Prog*	dlink;
 	int32	pc;
 	int32	line;
 	int32	spadj;
@@ -117,7 +116,7 @@ struct	Prog
 	uchar	as;
 	uchar	scond;
 	uchar	reg;
-	uchar	align;
+	uchar	align;	// unused
 };
 
 #define	regused	u0.u0regused
@@ -136,8 +135,6 @@ struct	Sym
 	uchar	reachable;
 	uchar	dynexport;
 	uchar	leaf;
-	uchar	stkcheck;
-	uchar	hide;
 	int32	dynid;
 	int32	plt;
 	int32	got;
@@ -148,6 +145,8 @@ struct	Sym
 	int32	elfsym;
 	uchar	special;
 	uchar	fnptr;	// used as fn ptr
+	uchar	stkcheck;
+	uchar	hide;
 	Sym*	hash;	// in hash table
 	Sym*	allsym;	// in all symbol list
 	Sym*	next;	// in text or data list

コアとなるコードの解説

Prog 構造体

  • - Prog* dlink; この行が削除されました。dlinkProg 型のポインタであり、リンクリストのような構造で使われることが想定されますが、このコミットの時点で未使用と判断され、削除されました。これにより、ポインタ分のメモリ(ARM 32-bitでは4バイト)が節約されます。

  • + uchar align; // unused align フィールド自体は変更されていませんが、// unused というコメントが追加されました。これは、このフィールドが現在使用されていないことを明示し、将来のコードレビューやメンテナンスの際に役立つ情報となります。このフィールドが削除されなかったのは、構造体のアライメント要件により、削除しても全体のサイズが変わらないためです。

Sym 構造体

  • - uchar stkcheck;

  • - uchar hide; これらの行が削除されました。これは、stkcheckhide の2つの uchar 型フィールドが、構造体のより前の位置から削除されたことを示します。

  • + uchar stkcheck;

  • + uchar hide; これらの行が追加されました。これは、stkcheckhide の2つの uchar 型フィールドが、構造体のより後ろの位置(fnptr の後)に移動されたことを示します。この移動により、uchar 型のフィールドがメモリ上でより密接に配置され、その後に続く Sym* hash などのポインタ型フィールドとの間のパディングが最適化され、結果として Sym 構造体全体のサイズが削減されました。

これらの変更は、C言語の構造体定義におけるフィールドの順序が、コンパイラによるメモリレイアウトとパディングの挿入にどのように影響するかを理解していることを示しています。未使用フィールドの削除と、フィールドの再配置によるアライメントの最適化は、メモリ効率を向上させるための一般的な手法です。

関連リンク

参考にした情報源リンク

  • Go言語のリンカの内部構造に関するブログ記事や解説(一般的な情報源)
  • C言語における構造体のアライメントとパディングに関する技術記事
  • Go言語のコミット履歴と関連する議論(GerritのCLページなど)
  • https://golang.org/cl/7106050 (元のGerrit Change-List)
  • Go言語の cmd/link の進化に関する情報(5l などが link に統合された経緯など)
  • Go言語のソースコード内の src/cmd/5l/l.h ファイル (コミット対象ファイル)

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

このコミットは、Go言語のリンカである cmd/5l (ARMアーキテクチャ向けリンカ) におけるメモリ使用量の最適化を目的としています。具体的には、リンカが内部的に使用する Prog および Sym という2つの重要なデータ構造のサイズを削減することで、リンカのフットプリントを小さくし、パフォーマンスを向上させます。

コミット

commit 9b568ef2b86ad383e5db9bc57723d4ce554a319e
Author: Dave Cheney <dave@cheney.net>
Date:   Sun Jan 20 20:14:24 2013 +1100

    cmd/5l: reduce the size of Prog and Sym
    
    Prog
    * Remove the unused Prog* dlink
    * note that align is also unused, but removing it does not help due to alignment issues.
    
    Saves 4 bytes, sizeof(Prog): 84 => 80.
    
    Sym
    * Align {u,}char fields on word boundaries
    
    Saves 4 bytes, sizeof(Sym): 136 => 132.
    
    Tested on linux/arm and freebsd/arm.
    
    R=minux.ma, remyoudompheng, rsc
    CC=golang-dev
    https://golang.org/cl/7106050

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

https://github.com/golang/go/commit/9b568ef2b86ad383e5db9bc57723d4ce554a319e

元コミット内容

このコミットの目的は、Goリンカ cmd/5l における Prog および Sym 構造体のサイズを削減することです。

Prog 構造体については、未使用の Prog* dlink フィールドを削除しました。これにより、Prog のサイズが84バイトから80バイトに4バイト削減されました。align フィールドも未使用ですが、アライメントの問題により削除してもサイズ削減に寄与しないため、そのまま残されています。

Sym 構造体については、uchar 型のフィールドをワード境界にアライメントするように再配置しました。これにより、Sym のサイズが136バイトから132バイトに4バイト削減されました。

これらの変更は linux/arm および freebsd/arm 環境でテストされています。

変更の背景

Go言語のリンカは、コンパイルされたオブジェクトファイルを結合して実行可能ファイルを生成する重要なツールです。リンカの内部では、プログラムの命令やシンボル情報を表現するために様々なデータ構造が使用されます。これらのデータ構造が大きくなると、リンカが消費するメモリ量が増加し、特にリソースが限られた環境(例えば組み込みシステムや古いハードウェア)でのビルド時間や実行効率に影響を与える可能性があります。

このコミットの背景には、リンカのメモリフットプリントを削減し、全体的なパフォーマンスを向上させるという目的があります。特に、ProgSym はリンカの処理中に大量に生成・操作される可能性のあるコアなデータ構造であるため、これらのサイズをわずかでも削減することは、リンカ全体のメモリ使用量に大きな影響を与えます。

また、Go言語はクロスコンパイルを重視しており、様々なアーキテクチャ(ARMなど)をサポートしています。cmd/5l はARMアーキテクチャ向けのリンカであり、ARMのようなリソース制約のある環境では、メモリ効率の最適化が特に重要になります。

前提知識の解説

1. リンカ (Linker)

リンカは、コンパイラによって生成された一つ以上のオブジェクトファイル(機械語コードとデータ、シンボル情報を含む)を結合し、実行可能なプログラムやライブラリを生成するシステムソフトウェアです。リンカの主な役割は以下の通りです。

  • シンボル解決 (Symbol Resolution): オブジェクトファイル間で未解決のシンボル参照(例えば、あるファイルで定義された関数を別のファイルから呼び出す場合)を解決し、正しいメモリアドレスにリンクします。
  • 再配置 (Relocation): オブジェクトファイル内のコードやデータが、最終的な実行可能ファイル内のどこに配置されるかに応じて、アドレス参照を調整します。
  • ライブラリの結合 (Library Linking): 静的ライブラリや動的ライブラリから必要なコードやデータを実行可能ファイルに含めます。

Go言語では、各アーキテクチャ(例: amd64, arm, arm64)に対応するリンカが存在し、それぞれ cmd/6l, cmd/5l, cmd/7l といった命名規則が使われていました(現在は cmd/link に統合されていますが、このコミット当時は分離されていました)。cmd/5l はARMアーキテクチャ向けのリンカです。

2. 構造体のアライメント (Struct Alignment) とパディング (Padding)

コンピュータのメモリは通常、バイト単位でアドレス指定されますが、CPUは特定のサイズのデータ(例えば4バイトの整数や8バイトのポインタ)を、そのサイズと同じ境界(アライメント)に配置されている場合に最も効率的にアクセスできます。例えば、4バイトの整数は4の倍数のアドレスに配置されるのが理想的です。

プログラミング言語の構造体(struct)では、複数のフィールドが連続してメモリに配置されますが、CPUの効率的なアクセスを保証するために、コンパイラはフィールド間に「パディング」と呼ばれる未使用のバイトを挿入することがあります。

例:

struct Example {
    char c1;  // 1バイト
    int i;    // 4バイト
    char c2;  // 1バイト
};

この構造体では、c1 の後に i が続く場合、i が4バイト境界に配置されるように c1 の後に3バイトのパディングが挿入されることがあります。同様に、i の後に c2 が続く場合も、構造体全体のサイズが最も大きいフィールドのサイズ(この場合は int の4バイト)の倍数になるように、c2 の後にパディングが挿入されることがあります。

フィールドの順序を変更することで、パディングの量を最小限に抑え、構造体全体のサイズを削減できる場合があります。これは「構造体パッキング (struct packing)」または「構造体レイアウトの最適化」と呼ばれます。

3. Go言語のリンカにおける ProgSym 構造体

  • Prog 構造体: リンカの内部では、プログラムの機械語命令は Prog (Program) 構造体のリストとして表現されます。各 Prog インスタンスは、単一の命令やデータ定義、またはリンカが処理する必要のあるその他のプログラム要素を表します。これには、命令の種類、オペランド、参照先のシンボル、行番号などの情報が含まれます。リンカはこれらの Prog オブジェクトを走査し、最終的な実行可能ファイルを構築します。

  • Sym 構造体: Sym (Symbol) 構造体は、プログラム内のシンボル(関数名、グローバル変数名、ラベルなど)に関する情報を格納します。各 Sym インスタンスは、シンボルの名前、種類(関数、データなど)、サイズ、アドレス、外部参照かどうか、エクスポートされるかどうかなどの詳細を保持します。リンカはシンボルテーブルを構築し、Sym オブジェクトを使用してシンボル解決と再配置を行います。

これらの構造体はリンカの動作中に頻繁に生成、アクセス、および操作されるため、そのサイズはリンカのメモリ使用量とパフォーマンスに直接的な影響を与えます。

技術的詳細

このコミットは、src/cmd/5l/l.h ヘッダーファイル内の Prog および Sym 構造体の定義を変更することで、メモリフットプリントを削減しています。

Prog 構造体の変更

Prog 構造体から dlink フィールドが削除されました。 元の定義:

struct Prog {
    // ...
    Prog*   cond;
    Prog*   link;
    Prog*   dlink; // 削除対象
    int32   pc;
    // ...
};

変更後:

struct Prog {
    // ...
    Prog*   cond;
    Prog*   link;
    // Prog*   dlink; // 削除
    int32   pc;
    // ...
};

コミットメッセージによると、dlink フィールドは未使用であったため、削除してもリンカの機能に影響はありません。ポインタ (Prog*) は通常、システムアーキテクチャのワードサイズ(ARM 32-bitでは4バイト)と同じサイズを持つため、この削除により Prog 構造体のサイズが4バイト削減されました。

また、align フィールドについては、コミットメッセージで「unused」と明記されていますが、削除されていません。これは、align フィールドを削除しても、構造体のアライメント要件により、コンパイラがその分のパディングを挿入してしまうため、結果的に構造体全体のサイズは変わらないという判断があったためです。コメント // unused が追加され、その状態が明示されました。

Sym 構造体の変更

Sym 構造体では、uchar 型のフィールド stkcheckhide の位置が変更されました。 元の定義:

struct Sym {
    // ...
    uchar   reachable;
    uchar   dynexport;
    uchar   leaf;
    uchar   stkcheck; // 移動対象
    uchar   hide;     // 移動対象
    int32   dynid;
    // ...
};

変更後:

struct Sym {
    // ...
    uchar   reachable;
    uchar   dynexport;
    uchar   leaf;
    // uchar   stkcheck; // 移動
    // uchar   hide;     // 移動
    int32   dynid;
    // ...
    uchar   special;
    uchar   fnptr;    // used as fn ptr
    uchar   stkcheck; // 新しい位置
    uchar   hide;     // 新しい位置
    Sym*    hash;
    // ...
};

uchar は1バイトのデータ型です。int32 は4バイトです。元の構造体では、3つの uchar (reachable, dynexport, leaf) の後に stkcheckhide が続き、その後に int32 が来ていました。この配置では、int32 dynid が4バイト境界にアライメントされるように、leaf, stkcheck, hide の後にパディングが挿入されていた可能性があります。

新しい配置では、stkcheckhide が、他の uchar フィールド (special, fnptr) の近くに移動されました。これにより、コンパイラが構造体をレイアウトする際に、uchar 型のフィールドをまとめて配置し、その後に続く Sym* hash (ポインタ、4バイト) などのより大きなアライメント要件を持つフィールドとの間のパディングを最適化できたと考えられます。結果として、Sym 構造体全体のサイズが4バイト削減されました。これは、コンパイラが生成するパディングの量が減ったことを意味します。

削減効果

  • Prog 構造体: 84バイト → 80バイト (4バイト削減)
  • Sym 構造体: 136バイト → 132バイト (4バイト削減)

これらの削減は、リンカが処理する命令やシンボルの数が多いほど、全体的なメモリ使用量に大きな影響を与えます。

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

変更は src/cmd/5l/l.h ファイルに集中しています。

--- a/src/cmd/5l/l.h
+++ b/src/cmd/5l/l.h
@@ -108,7 +108,6 @@ struct	Prog
 	} u0;
 	Prog*	cond;
 	Prog*	link;
-	Prog*	dlink;
 	int32	pc;
 	int32	line;
 	int32	spadj;
@@ -117,7 +116,7 @@ struct	Prog
 	uchar	as;
 	uchar	scond;
 	uchar	reg;
-	uchar	align;
+	uchar	align;	// unused
 };
 
 #define	regused	u0.u0regused
@@ -136,8 +135,6 @@ struct	Sym
 	uchar	reachable;
 	uchar	dynexport;
 	uchar	leaf;
-	uchar	stkcheck;
-	uchar	hide;
 	int32	dynid;
 	int32	plt;
 	int32	got;
@@ -148,6 +145,8 @@ struct	Sym
 	int32	elfsym;
 	uchar	special;
 	uchar	fnptr;	// used as fn ptr
+	uchar	stkcheck;
+	uchar	hide;
 	Sym*	hash;	// in hash table
 	Sym*	allsym;	// in all symbol list
 	Sym*	next;	// in text or data list

コアとなるコードの解説

Prog 構造体

  • - Prog* dlink; この行が削除されました。dlinkProg 型のポインタであり、リンクリストのような構造で使われることが想定されますが、このコミットの時点で未使用と判断され、削除されました。これにより、ポインタ分のメモリ(ARM 32-bitでは4バイト)が節約されます。

  • + uchar align; // unused align フィールド自体は変更されていませんが、// unused というコメントが追加されました。これは、このフィールドが現在使用されていないことを明示し、将来のコードレビューやメンテナンスの際に役立つ情報となります。このフィールドが削除されなかったのは、構造体のアライメント要件により、削除しても全体のサイズが変わらないためです。

Sym 構造体

  • - uchar stkcheck;

  • - uchar hide; これらの行が削除されました。これは、stkcheckhide の2つの uchar 型フィールドが、構造体のより前の位置から削除されたことを示します。

  • + uchar stkcheck;

  • + uchar hide; これらの行が追加されました。これは、stkcheckhide の2つの uchar 型フィールドが、構造体のより後ろの位置(fnptr の後)に移動されたことを示します。この移動により、uchar 型のフィールドがメモリ上でより密接に配置され、その後に続く Sym* hash などのポインタ型フィールドとの間のパディングが最適化され、結果として Sym 構造体全体のサイズが削減されました。

これらの変更は、C言語の構造体定義におけるフィールドの順序が、コンパイラによるメモリレイアウトとパディングの挿入にどのように影響するかを理解していることを示しています。未使用フィールドの削除と、フィールドの再配置によるアライメントの最適化は、メモリ効率を向上させるための一般的な手法です。

関連リンク

参考にした情報源リンク

  • Go言語のリンカの内部構造に関するブログ記事や解説(一般的な情報源)
  • C言語における構造体のアライメントとパディングに関する技術記事
  • Go言語のコミット履歴と関連する議論(GerritのCLページなど)
  • https://golang.org/cl/7106050 (元のGerrit Change-List)
  • Go言語の cmd/link の進化に関する情報(5l などが link に統合された経緯など)
  • Go言語のソースコード内の src/cmd/5l/l.h ファイル (コミット対象ファイル)