[インデックス 14291] ファイルの概要
このコミットは、Goコンパイラのsrc/cmd/gc/racewalk.c
ファイルに対する変更です。racewalk.c
は、Goのデータ競合検出器(Race Detector)に関連するコードを生成する部分を担っています。具体的には、関数エントリーポイントにデータ競合検出のためのフック(racefuncenter
)を挿入する処理が含まれています。
コミット
cmd/gc: fix build
R=golang-dev
CC=golang-dev
https://golang.org/cl/6826047
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/936498e5dcd8a329a5da8cd743f60bdb820e6c22
元コミット内容
commit 936498e5dcd8a329a5da8cd743f60bdb820e6c22
Author: Dmitriy Vyukov <dvyukov@google.com>
Date: Thu Nov 1 22:59:53 2012 +0400
cmd/gc: fix build
R=golang-dev
CC=golang-dev
https://golang.org/cl/6826047
変更の背景
このコミットの主な背景は、src/cmd/gc/racewalk.c
ファイル内で発生したマージコンフリクトの解決です。コミットメッセージの「fix build」という記述と、差分に含まれる<<<<<<< local
、=======
、>>>>>>> other
といったマージコンフリクトマーカーが、この事実を明確に示しています。
Goコンパイラの開発過程で、複数のブランチや変更が同時に進められる中で、racewalk.c
の同じ箇所に対して異なる変更が加えられた結果、コンフリクトが発生しました。このコンフリクトは、racefuncenter
という関数呼び出しを関数のエントリーポイントに追加する際の、ノード(ASTノード)のリスト操作に関するものでした。
具体的には、fn->enter
というリストに新しいノードnd
を追加する際に、concat(list1(nd), fn->enter)
とlist(fn->enter, nd)
という2つの異なる方法が提案され、これらが競合していました。このコミットは、concat(list1(nd), fn->enter)
の方を採用することで、ビルドエラーを解消し、コンパイラが正常に動作するように修正することを目的としています。
前提知識の解説
Goコンパイラ (cmd/gc
)
Go言語の公式コンパイラは、主にcmd/gc
というディレクトリに格納されています。これはGo言語で書かれたソースコードを機械語に変換する役割を担っています。コンパイラは、字句解析、構文解析、意味解析、中間コード生成、最適化、コード生成といった複数のフェーズを経て、最終的な実行可能ファイルを生成します。
Go Race Detector (データ競合検出器)
Go言語には、並行処理におけるデータ競合(data race)を検出するための組み込みツールである「Race Detector」があります。データ競合とは、複数のゴルーチンが同時に同じメモリ位置にアクセスし、少なくとも1つのアクセスが書き込みであり、かつそれらのアクセスが同期メカニズムによって順序付けされていない場合に発生するバグです。データ競合はプログラムの予測不能な動作やクラッシュを引き起こす可能性があります。
Race Detectorは、コンパイル時に特別なインストゥルメンテーション(計測コードの挿入)を行うことで、実行時にデータ競合を監視します。このインストゥルメンテーションは、メモリへのアクセス(読み書き)や同期プリミティブ(ミューテックス、チャネルなど)の操作を記録し、それらのイベントの順序を分析することで競合を検出します。
racewalk.c
src/cmd/gc/racewalk.c
は、Goコンパイラの一部であり、Race Detectorのインストゥルメンテーションに関連する処理を担当しています。このファイル内のコードは、Goプログラムの抽象構文木(AST)を走査し、データ競合検出に必要なフック(関数呼び出し)を適切な場所に挿入します。例えば、関数のエントリーポイントやエグジットポイント、メモリへのアクセス箇所などに、Race Detectorのランタイム関数(例: racefuncenter
, racefuncexit
)の呼び出しを埋め込みます。
racefuncenter
と racefuncexit
これらはGoランタイムの一部として提供される関数で、Race Detectorが有効な場合に、関数の開始時と終了時に呼び出されるようにコンパイラによって挿入されます。
racefuncenter
: 関数が実行を開始する際に呼び出され、現在のゴルーチンやスタックフレームに関する情報をRace Detectorに通知します。racefuncexit
: 関数が実行を終了する際に呼び出され、Race Detectorにその関数の実行が完了したことを通知します。
これらのフックを通じて、Race Detectorは関数の呼び出しスタックやメモリアクセスの履歴を追跡し、データ競合のパターンを特定します。
getcallerpc
と nodpc
getcallerpc
: 呼び出し元のプログラムカウンタ(PC)を取得するためのメカニズムです。Race Detectorは、競合が発生した際に、どのコードパスが関与していたかを特定するために、呼び出し元のPC情報を必要とします。nodpc
:getcallerpc
によって取得されたPC値を保持するためのノード(ASTノード)を指します。
widthptr
と FP
FP
(Frame Pointer): 関数呼び出しスタックにおける現在のスタックフレームの基準点を示すレジスタまたは概念です。ローカル変数や引数は、このフレームポインタからのオフセットでアクセスされます。widthptr
: ポインタのサイズ(バイト単位)を表します。例えば、64ビットシステムでは8バイトです。xoffset = -widthptr
: これは、スタックフレーム内で呼び出し元のPCが格納されているメモリ位置を指すオフセット計算です。FP
から負のオフセットでアクセスされるのは、通常、引数やリターンアドレスがスタックフレームの開始点(FP
が指す場所)よりも低いアドレスに配置されるためです。
マージコンフリクト
Gitなどのバージョン管理システムにおいて、同じファイルの同じ行または近い行が複数のブランチで独立して変更され、それらのブランチをマージしようとした際に、Gitが自動的に変更を統合できない状況を指します。この場合、開発者が手動で競合を解決する必要があります。マージコンフリクトが発生すると、ファイル内に<<<<<<<
, =======
, >>>>>>>
といった特殊なマーカーが挿入され、競合する変更の範囲と、それぞれのブランチからの内容が示されます。
技術的詳細
このコミットは、Goコンパイラのsrc/cmd/gc/racewalk.c
ファイルにおけるマージコンフリクトの解決に焦点を当てています。このファイルは、Goのデータ競合検出器が有効な場合に、コンパイルされるGoプログラムに関数エントリー/エグジットフックを挿入する役割を担っています。
問題の箇所は、racewalk
関数内でracefuncenter
呼び出しを生成し、それを現在の関数のエントリーポイントのリスト(fn->enter
)に追加する部分でした。
マージコンフリクトが発生していたのは以下のコードブロックです。
-<<<<<<< local
-// TODO(dvyukov): ideally this should be:
-// racefuncenter(getreturnaddress())
-// because it's much more costly to obtain from runtime library.
-nd = mkcall("racefuncenter", T, nil);
-fn->enter = concat(list1(nd), fn->enter);
-=======
// nodpc is the PC of the caller as extracted by
// getcallerpc. We use -widthptr(FP) for x86.
// BUG: this will not work on arm.
nodpc = temp(types[TUINTPTR]);
nodpc->type = types[TUINTPTR];
nodpc->xoffset = -widthptr;
nd = mkcall("racefuncenter", T, nil, nodpc);
-fn->enter = list(fn->enter, nd);
->>>>>>> other
このコンフリクトは、racefuncenter
に渡す引数と、生成されたノードnd
をfn->enter
リストに追加する方法の2点に関するものでした。
-
racefuncenter
の引数:local
側のバージョンでは、racefuncenter
は引数なしで呼び出されていました (mkcall("racefuncenter", T, nil)
)。これは、コメントにあるようにgetreturnaddress()
を理想としていましたが、ランタイムライブラリから取得するのがコスト高であるため、一時的に引数なしで実装されていた可能性があります。other
側のバージョンでは、nodpc
というノードを引数として渡していました (mkcall("racefuncenter", T, nil, nodpc)
)。nodpc
は呼び出し元のPC(プログラムカウンタ)を表し、getcallerpc
によって取得される値です。これは、Race Detectorがより正確なコンテキスト情報(どの呼び出し元から関数が実行されたか)を得るために重要です。
-
ノードのリストへの追加方法:
local
側のバージョンでは、fn->enter = concat(list1(nd), fn->enter);
を使用していました。これは、新しいノードnd
を含む単一要素リストを既存のfn->enter
リストの先頭に連結することを意味します。other
側のバージョンでは、fn->enter = list(fn->enter, nd);
を使用していました。これは、既存のfn->enter
リストに新しいノードnd
を末尾に追加することを意味します。
このコミットでは、other
側の変更(racefuncenter
にnodpc
を引数として渡す)と、local
側のリスト連結方法(concat(list1(nd), fn->enter)
)を組み合わせる形で解決されています。
最終的に採用されたコードは以下のようになります。
nodpc = temp(types[TUINTPTR]);
nodpc->type = types[TUINTPTR];
nodpc->xoffset = -widthptr;
nd = mkcall("racefuncenter", T, nil, nodpc);
fn->enter = concat(list1(nd), fn->enter);
これにより、racefuncenter
は呼び出し元のPC情報を受け取るようになり、かつ、新しいフックが関数のエントリーポイントのリストの先頭に適切に追加されるようになりました。この修正によって、ビルドが正常に完了し、Race Detectorのインストゥルメンテーションが意図通りに行われるようになりました。
コメントで言及されているBUG: this will not work on arm.
は、getcallerpc
がx86
アーキテクチャのスタックフレーム構造に依存している可能性を示唆しており、ARMアーキテクチャでは異なるアプローチが必要であることを示しています。このコミット自体はこのARMに関するバグを修正するものではありませんが、将来的な課題として認識されていたことがわかります。
コアとなるコードの変更箇所
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index a09b7adf43..9e942498ba 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -43,13 +43,6 @@ racewalk(Node *fn)
}
}
--<<<<<<< local
-// TODO(dvyukov): ideally this should be:
-// racefuncenter(getreturnaddress())
-// because it's much more costly to obtain from runtime library.
-nd = mkcall("racefuncenter", T, nil);
-fn->enter = concat(list1(nd), fn->enter);
-=======
// nodpc is the PC of the caller as extracted by
// getcallerpc. We use -widthptr(FP) for x86.
// BUG: this will not work on arm.
@@ -58,8 +51,7 @@ racewalk(Node *fn)
nodpc->type = types[TUINTPTR];
nodpc->xoffset = -widthptr;
nd = mkcall("racefuncenter", T, nil, nodpc);
-- fn->enter = list(fn->enter, nd);
->>>>>>> other
-+ fn->enter = concat(list1(nd), fn->enter);
nd = mkcall("racefuncexit", T, nil);
fn->exit = list(fn->exit, nd);
racewalklist(curfn->nbody, nil);
コアとなるコードの解説
この差分は、src/cmd/gc/racewalk.c
ファイル内のracewalk
関数におけるマージコンフリクトの解決を示しています。
元のコードには、Gitのマージコンフリクトマーカー(<<<<<<< local
、=======
、>>>>>>> other
)が含まれていました。これは、異なるブランチで同じコードブロックが変更され、Gitが自動的にマージできなかったことを意味します。
削除された行(-
で始まる行):
-<<<<<<< local
-// TODO(dvyukov): ideally this should be:
-// racefuncenter(getreturnaddress())
-// because it's much more costly to obtain from runtime library.
-nd = mkcall("racefuncenter", T, nil);
-fn->enter = concat(list1(nd), fn->enter);
-=======
このブロックは、local
ブランチ側の変更を示しています。ここでは、racefuncenter
が引数なしで呼び出され、その結果のノードnd
がconcat(list1(nd), fn->enter)
を使ってfn->enter
リストの先頭に追加されていました。
- fn->enter = list(fn->enter, nd);
->>>>>>> other
この行は、other
ブランチ側の変更の一部です。other
ブランチでは、racefuncenter
にnodpc
(呼び出し元のPC)が引数として渡されており、その結果のノードnd
がlist(fn->enter, nd)
を使ってfn->enter
リストの末尾に追加されていました。
追加された行(+
で始まる行):
+ fn->enter = concat(list1(nd), fn->enter);
この行が、マージコンフリクトを解決するために最終的に採用されたコードです。
この修正では、other
ブランチで導入されたracefuncenter
へのnodpc
引数の渡し方(これは差分の上の方で残されています)と、local
ブランチで使われていたリスト連結の方法であるconcat(list1(nd), fn->enter)
を組み合わせています。
つまり、このコミットは以下の変更を統合しています。
racefuncenter
呼び出しに、呼び出し元のPCを表すnodpc
を引数として渡す。これにより、Race Detectorがより詳細なコンテキスト情報を得られるようになります。- 生成された
racefuncenter
のノードを、fn->enter
リストの先頭に追加する。これは、concat(list1(nd), fn->enter)
という関数呼び出しによって実現されます。list1(nd)
はnd
を唯一の要素とする新しいリストを作成し、それを既存のfn->enter
リストと連結することで、nd
がリストの先頭に来るようにします。
この修正により、コンパイラのビルドが正常に行われるようになり、Race Detectorのインストゥルメンテーションが意図通りに機能するようになりました。
関連リンク
- Go Race Detector Documentation: Go言語の公式ドキュメントにおけるRace Detectorの解説。
- Go Compiler Source Code: Goコンパイラのソースコードリポジトリ。
- Go CL 6826047: このコミットに対応するGoのコードレビューシステム(Gerrit)のチェンジリスト。
参考にした情報源リンク
- Go Race Detector Documentation: https://go.dev/doc/articles/race_detector
- Go Compiler Source Code (GitHub): https://github.com/golang/go
- Go Code Review (Gerrit): https://go.googlesource.com/go/+/refs/heads/master/CONTRIBUTING.md#code-reviews
- Git Merge Conflicts: https://git-scm.com/docs/git-merge
mkcall
andconcat
in Go compiler: (General understanding from Go compiler source code analysis, no specific external link)getcallerpc
and stack frames: (General understanding of compiler internals and assembly, no specific external link)golang.org/cl/6826047
(as provided in the commit message)
[インデックス 14291] ファイルの概要
このコミットは、Goコンパイラのsrc/cmd/gc/racewalk.c
ファイルに対する変更です。racewalk.c
は、Goのデータ競合検出器(Race Detector)に関連するコードを生成する部分を担っています。具体的には、関数エントリーポイントにデータ競合検出のためのフック(racefuncenter
)を挿入する処理が含まれています。
コミット
cmd/gc: fix build
R=golang-dev
CC=golang-dev
https://golang.org/cl/6826047
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/936498e5dcd8a329a5da8cd743f60bdb820e6c22
元コミット内容
commit 936498e5dcd8a329a5da8cd743f60bdb820e6c22
Author: Dmitriy Vyukov <dvyukov@google.com>
Date: Thu Nov 1 22:59:53 2012 +0400
cmd/gc: fix build
R=golang-dev
CC=golang-dev
https://golang.org/cl/6826047
変更の背景
このコミットの主な背景は、src/cmd/gc/racewalk.c
ファイル内で発生したマージコンフリクトの解決です。コミットメッセージの「fix build」という記述と、差分に含まれる<<<<<<< local
、=======
、>>>>>>> other
といったマージコンフリクトマーカーが、この事実を明確に示しています。
Goコンパイラの開発過程で、複数のブランチや変更が同時に進められる中で、racewalk.c
の同じ箇所に対して異なる変更が加えられた結果、コンフリクトが発生しました。このコンフリクトは、racefuncenter
という関数呼び出しを関数のエントリーポイントに追加する際の、ノード(ASTノード)のリスト操作に関するものでした。
具体的には、fn->enter
というリストに新しいノードnd
を追加する際に、concat(list1(nd), fn->enter)
とlist(fn->enter, nd)
という2つの異なる方法が提案され、これらが競合していました。このコミットは、concat(list1(nd), fn->enter)
の方を採用することで、ビルドエラーを解消し、コンパイラが正常に動作するように修正することを目的としています。
前提知識の解説
Goコンパイラ (cmd/gc
)
Go言語の公式コンパイラは、主にcmd/gc
というディレクトリに格納されています。これはGo言語で書かれたソースコードを機械語に変換する役割を担っています。コンパイラは、字句解析、構文解析、意味解析、中間コード生成、最適化、コード生成といった複数のフェーズを経て、最終的な実行可能ファイルを生成します。
Go Race Detector (データ競合検出器)
Go言語には、並行処理におけるデータ競合(data race)を検出するための組み込みツールである「Race Detector」があります。データ競合とは、複数のゴルーチンが同時に同じメモリ位置にアクセスし、少なくとも1つのアクセスが書き込みであり、かつそれらのアクセスが同期メカニズムによって順序付けされていない場合に発生するバグです。データ競合はプログラムの予測不能な動作やクラッシュを引き起こす可能性があります。
Race Detectorは、コンパイル時に特別なインストゥルメンテーション(計測コードの挿入)を行うことで、実行時にデータ競合を監視します。このインストゥルメンテーションは、メモリへのアクセス(読み書き)や同期プリミティブ(ミューテックス、チャネルなど)の操作を記録し、それらのイベントの順序を分析することで競合を検出します。
racewalk.c
src/cmd/gc/racewalk.c
は、Goコンパイラの一部であり、Race Detectorのインストゥルメンテーションに関連する処理を担当しています。このファイル内のコードは、Goプログラムの抽象構文木(AST)を走査し、データ競合検出に必要なフック(関数呼び出し)を適切な場所に挿入します。例えば、関数のエントリーポイントやエグジットポイント、メモリへのアクセス箇所などに、Race Detectorのランタイム関数(例: racefuncenter
, racefuncexit
)の呼び出しを埋め込みます。
racefuncenter
と racefuncexit
これらはGoランタイムの一部として提供される関数で、Race Detectorが有効な場合に、関数の開始時と終了時に呼び出されるようにコンパイラによって挿入されます。
racefuncenter
: 関数が実行を開始する際に呼び出され、現在のゴルーチンやスタックフレームに関する情報をRace Detectorに通知します。racefuncexit
: 関数が実行を終了する際に呼び出され、Race Detectorにその関数の実行が完了したことを通知します。
これらのフックを通じて、Race Detectorは関数の呼び出しスタックやメモリアクセスの履歴を追跡し、データ競合のパターンを特定します。
getcallerpc
と nodpc
getcallerpc
: 呼び出し元のプログラムカウンタ(PC)を取得するためのメカニズムです。Race Detectorは、競合が発生した際に、どのコードパスが関与していたかを特定するために、呼び出し元のPC情報を必要とします。nodpc
:getcallerpc
によって取得されたPC値を保持するためのノード(ASTノード)を指します。
widthptr
と FP
FP
(Frame Pointer): 関数呼び出しスタックにおける現在のスタックフレームの基準点を示すレジスタまたは概念です。ローカル変数や引数は、このフレームポインタからのオフセットでアクセスされます。widthptr
: ポインタのサイズ(バイト単位)を表します。例えば、64ビットシステムでは8バイトです。xoffset = -widthptr
: これは、スタックフレーム内で呼び出し元のPCが格納されているメモリ位置を指すオフセット計算です。FP
から負のオフセットでアクセスされるのは、通常、引数やリターンアドレスがスタックフレームの開始点(FP
が指す場所)よりも低いアドレスに配置されるためです。
マージコンフリクト
Gitなどのバージョン管理システムにおいて、同じファイルの同じ行または近い行が複数のブランチで独立して変更され、それらのブランチをマージしようとした際に、Gitが自動的に変更を統合できない状況を指します。この場合、開発者が手動で競合を解決する必要があります。マージコンフリクトが発生すると、ファイル内に<<<<<<<
, =======
, >>>>>>>
といった特殊なマーカーが挿入され、競合する変更の範囲と、それぞれのブランチからの内容が示されます。
技術的詳細
このコミットは、Goコンパイラのsrc/cmd/gc/racewalk.c
ファイルにおけるマージコンフリクトの解決に焦点を当てています。このファイルは、Goのデータ競合検出器が有効な場合に、コンパイルされるGoプログラムに関数エントリー/エグジットフックを挿入する役割を担っています。
問題の箇所は、racewalk
関数内でracefuncenter
呼び出しを生成し、それを現在の関数のエントリーポイントのリスト(fn->enter
)に追加する部分でした。
マージコンフリクトが発生していたのは以下のコードブロックです。
-<<<<<<< local
-// TODO(dvyukov): ideally this should be:
-// racefuncenter(getreturnaddress())
-// because it's much more costly to obtain from runtime library.
-nd = mkcall("racefuncenter", T, nil);
-fn->enter = concat(list1(nd), fn->enter);
-=======
// nodpc is the PC of the caller as extracted by
// getcallerpc. We use -widthptr(FP) for x86.
// BUG: this will not work on arm.
nodpc = temp(types[TUINTPTR]);
nodpc->type = types[TUINTPTR];
nodpc->xoffset = -widthptr;
nd = mkcall("racefuncenter", T, nil, nodpc);
-fn->enter = list(fn->enter, nd);
->>>>>>> other
このコンフリクトは、racefuncenter
に渡す引数と、生成されたノードnd
をfn->enter
リストに追加する方法の2点に関するものでした。
-
racefuncenter
の引数:local
側のバージョンでは、racefuncenter
は引数なしで呼び出されていました (mkcall("racefuncenter", T, nil)
)。これは、コメントにあるようにgetreturnaddress()
を理想としていましたが、ランタイムライブラリから取得するのがコスト高であるため、一時的に引数なしで実装されていた可能性があります。other
側のバージョンでは、nodpc
というノードを引数として渡していました (mkcall("racefuncenter", T, nil, nodpc)
)。nodpc
は呼び出し元のPC(プログラムカウンタ)を表し、getcallerpc
によって取得される値です。これは、Race Detectorがより正確なコンテキスト情報(どの呼び出し元から関数が実行されたか)を得るために重要です。
-
ノードのリストへの追加方法:
local
側のバージョンでは、fn->enter = concat(list1(nd), fn->enter);
を使用していました。これは、新しいノードnd
を含む単一要素リストを既存のfn->enter
リストの先頭に連結することを意味します。other
側のバージョンでは、fn->enter = list(fn->enter, nd);
を使用していました。これは、既存のfn->enter
リストに新しいノードnd
を末尾に追加することを意味します。
このコミットでは、other
側の変更(racefuncenter
にnodpc
を引数として渡す)と、local
側のリスト連結方法(concat(list1(nd), fn->enter)
)を組み合わせる形で解決されています。
最終的に採用されたコードは以下のようになります。
nodpc = temp(types[TUINTPTR]);
nodpc->type = types[TUINTPTR];
nodpc->xoffset = -widthptr;
nd = mkcall("racefuncenter", T, nil, nodpc);
fn->enter = concat(list1(nd), fn->enter);
これにより、racefuncenter
は呼び出し元のPC情報を受け取るようになり、かつ、新しいフックが関数のエントリーポイントのリストの先頭に適切に追加されるようになりました。この修正によって、ビルドが正常に完了し、Race Detectorのインストゥルメンテーションが意図通りに行われるようになりました。
コメントで言及されているBUG: this will not work on arm.
は、getcallerpc
がx86
アーキテクチャのスタックフレーム構造に依存している可能性を示唆しており、ARMアーキテクチャでは異なるアプローチが必要であることを示しています。このコミット自体はこのARMに関するバグを修正するものではありませんが、将来的な課題として認識されていたことがわかります。
コアとなるコードの変更箇所
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index a09b7adf43..9e942498ba 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -43,13 +43,6 @@ racewalk(Node *fn)
}
}
--<<<<<<< local
-// TODO(dvyukov): ideally this should be:
-// racefuncenter(getreturnaddress())
-// because it's much more costly to obtain from runtime library.
-nd = mkcall("racefuncenter", T, nil);
-fn->enter = concat(list1(nd), fn->enter);
-=======
// nodpc is the PC of the caller as extracted by
// getcallerpc. We use -widthptr(FP) for x86.
// BUG: this will not work on arm.
@@ -58,8 +51,7 @@ racewalk(Node *fn)
nodpc->type = types[TUINTPTR];
nodpc->xoffset = -widthptr;
nd = mkcall("racefuncenter", T, nil, nodpc);
-- fn->enter = list(fn->enter, nd);
->>>>>>> other
-+ fn->enter = concat(list1(nd), fn->enter);
nd = mkcall("racefuncexit", T, nil);
fn->exit = list(fn->exit, nd);
racewalklist(curfn->nbody, nil);
コアとなるコードの解説
この差分は、src/cmd/gc/racewalk.c
ファイル内のracewalk
関数におけるマージコンフリクトの解決を示しています。
元のコードには、Gitのマージコンフリクトマーカー(<<<<<<< local
、=======
、>>>>>>> other
)が含まれていました。これは、異なるブランチで同じコードブロックが変更され、Gitが自動的にマージできなかったことを意味します。
削除された行(-
で始まる行):
-<<<<<<< local
-// TODO(dvyukov): ideally this should be:
-// racefuncenter(getreturnaddress())
-// because it's much more costly to obtain from runtime library.
-nd = mkcall("racefuncenter", T, nil);
-fn->enter = concat(list1(nd), fn->enter);
-=======
このブロックは、local
ブランチ側の変更を示しています。ここでは、racefuncenter
が引数なしで呼び出され、その結果のノードnd
がconcat(list1(nd), fn->enter)
を使ってfn->enter
リストの先頭に追加されていました。
- fn->enter = list(fn->enter, nd);
->>>>>>> other
この行は、other
ブランチ側の変更の一部です。other
ブランチでは、racefuncenter
にnodpc
(呼び出し元のPC)が引数として渡されており、その結果のノードnd
がlist(fn->enter, nd)
を使ってfn->enter
リストの末尾に追加されていました。
追加された行(+
で始まる行):
+ fn->enter = concat(list1(nd), fn->enter);
この行が、マージコンフリクトを解決するために最終的に採用されたコードです。
この修正では、other
ブランチで導入されたracefuncenter
へのnodpc
引数の渡し方(これは差分の上の方で残されています)と、local
ブランチで使われていたリスト連結の方法であるconcat(list1(nd), fn->enter)
を組み合わせています。
つまり、このコミットは以下の変更を統合しています。
racefuncenter
呼び出しに、呼び出し元のPCを表すnodpc
を引数として渡す。これにより、Race Detectorがより詳細なコンテキスト情報を得られるようになります。- 生成された
racefuncenter
のノードを、fn->enter
リストの先頭に追加する。これは、concat(list1(nd), fn->enter)
という関数呼び出しによって実現されます。list1(nd)
はnd
を唯一の要素とする新しいリストを作成し、それを既存のfn->enter
リストと連結することで、nd
がリストの先頭に来るようにします。
この修正により、コンパイラのビルドが正常に行われるようになり、Race Detectorのインストゥルメンテーションが意図通りに機能するようになりました。
関連リンク
- Go Race Detector Documentation: Go言語の公式ドキュメントにおけるRace Detectorの解説。
- Go Compiler Source Code: Goコンパイラのソースコードリポジトリ。
- Go CL 6826047: このコミットに対応するGoのコードレビューシステム(Gerrit)のチェンジリスト。
参考にした情報源リンク
- Go Race Detector Documentation: https://go.dev/doc/articles/race_detector
- Go Compiler Source Code (GitHub): https://github.com/golang/go
- Go Code Review (Gerrit): https://go.googlesource.com/go/+/refs/heads/master/CONTRIBUTING.md#code-reviews
- Git Merge Conflicts: https://git-scm.com/docs/git-merge
mkcall
andconcat
in Go compiler: (General understanding from Go compiler source code analysis, no specific external link)getcallerpc
and stack frames: (General understanding of compiler internals and assembly, no specific external link)golang.org/cl/6826047
(as provided in the commit message)