[インデックス 14192] ファイルの概要
このコミットは、Goコンパイラの一部である cmd/gc
における builtin.c
ファイルの再構築に関するものです。具体的には、builtin.c
が runtime.go
と同期していなかった状態を修正し、いくつかの組み込み関数のシグネチャが更新されています。
コミット
commit 922c0b47557db7d686bfebe0e128a7a1dd6116e3
Author: Russ Cox <rsc@golang.org>
Date: Sun Oct 21 17:15:56 2012 -0400
cmd/gc: rebuild builtin.c
Was not in sync with runtime.go, but the diffs
didn't really matter, so nothing broke.
R=ken2
CC=golang-dev
https://golang.org/cl/6733057
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/922c0b47557db7d686bfebe0e128a7a1dd6116e3
元コミット内容
cmd/gc: rebuild builtin.c
Was not in sync with runtime.go, but the diffs
didn't really matter, so nothing broke.
R=ken2
CC=golang-dev
https://golang.org/cl/6733057
変更の背景
このコミットの主な背景は、Goコンパイラの cmd/gc
ディレクトリにある builtin.c
ファイルが、Goランタイムの runtime.go
ファイルと同期が取れていなかったことです。コミットメッセージによると、この同期のずれは「差分が実際には重要ではなかったため、何も壊れていなかった」とされています。しかし、コードベースの一貫性と正確性を保つために、この builtin.c
を runtime.go
の最新の状態に合わせて再構築する必要がありました。
builtin.c
は、Go言語の組み込み関数(append
, copy
, new
など)の内部的な宣言や、コンパイラがこれらの関数をどのように扱うかを定義するC言語のファイルです。一方、runtime.go
はGoランタイムの主要な部分を定義しており、Goプログラムの実行環境、ガベージコレクション、ゴルーチンのスケジューリングなどを管理します。これら二つのファイルは密接に関連しており、Go言語の組み込み関数の動作や、それらがランタイムとどのように連携するかに影響を与えます。
同期のずれは、Go言語の進化に伴う内部的な変更、特にランタイムの型定義や関数のシグネチャの変更が builtin.c
に適切に反映されていなかったことを示唆しています。このコミットは、将来的な問題を防ぎ、コンパイラとランタイム間の整合性を確保するためのメンテナンス作業の一環として行われました。
前提知識の解説
このコミットを理解するためには、以下のGo言語の内部構造と型に関する知識が役立ちます。
cmd/gc
と builtin.c
cmd/gc
はGo言語の公式コンパイラの一部です。Goのソースコードを機械語に変換する役割を担っています。builtin.c
は、このコンパイラ内部で使用されるC言語のファイルで、Go言語の組み込み関数(例: append
, copy
, len
など)の内部的な宣言や、それらの関数がコンパイラによってどのように処理されるかに関する情報を含んでいます。これらの組み込み関数は、Go言語の仕様の一部であり、明示的なインポートなしに利用できます。コンパイラは、これらの組み込み関数への呼び出しを、より最適化された内部関数やランタイム関数への呼び出しに変換することがよくあります。
runtime.go
runtime.go
はGoランタイムの主要なソースファイルの一つです。Goランタイムは、Goプログラムの実行に不可欠な部分であり、ゴルーチンのスケジューリング、ガベージコレクション、メモリ管理、チャネル操作、システムコールとの連携など、低レベルの機能を提供します。Goランタイムは主にGo言語で書かれていますが、一部の低レベルな処理にはC言語やアセンブリ言語も使用されます。builtin.c
と runtime.go
は、Goの組み込み関数がどのように実装され、ランタイムとどのように連携するかという点で密接に関連しています。
uint32
と uintptr
Go言語には、様々な数値型があります。
uint32
: 符号なし32ビット整数型です。0から4,294,967,295までの値を保持できます。特定のビット幅が必要な場合(例: ネットワークプロトコル、ファイルフォーマット、C言語との相互運用)に使用されます。uintptr
: ポインタのビットパターンを保持するのに十分な大きさの符号なし整数型です。これは、メモリアドレスを数値として表現するために使用されます。通常のGoのポインタ (*T
) とは異なり、uintptr
は型情報を持たず、Goのガベージコレクタによって追跡されません。主に低レベルのプログラミング(unsafe
パッケージと組み合わせて直接メモリを操作する場合など)や、Cライブラリとのインターフェースで使用されます。uintptr
のサイズは、実行環境のポインタサイズ(32ビットシステムでは32ビット、64ビットシステムでは64ビット)に依存します。
このコミットでは、copy
関数の内部的な引数型が uint32
から uintptr
に変更されています。これは、コピー操作のサイズ指定が、固定長の32ビット整数から、ポインタサイズに合わせたより柔軟な型に変更されたことを意味します。これにより、特に64ビットシステムでのメモリ操作の正確性が向上する可能性があります。
int
と int32
Go言語の整数型には、以下のような違いがあります。
int
: 符号付き整数型で、そのサイズはプラットフォームに依存します。32ビットシステムでは32ビット、64ビットシステムでは64ビットの幅を持ちます。Go言語では、特に指定がない限り、ほとんどの場面でint
を使用することが推奨されます。int32
: 符号付き32ビット整数型で、常に32ビットの幅を持ちます。-2,147,483,648から2,147,483,647までの値を保持できます。int32
のような固定サイズの整数型は、C言語との相互運用、バイナリデータフォーマットの処理、または特定のメモリ最適化が必要な場合に主に使用されます。
Goの型システムは厳格であり、int
と int32
は異なる型として扱われます。暗黙的な型変換は行われず、必要に応じて明示的な型変換を行う必要があります。このコミットでは、newselect
関数の内部的な引数型が int
から int32
に変更されています。これは、newselect
が扱うサイズ情報が、プラットフォーム依存の int
ではなく、常に32ビットの int32
として扱われるようになったことを示しています。これにより、異なるアーキテクチャ間での挙動の一貫性が向上する可能性があります。
Goの select
ステートメントと newselect
システムコール
Go言語には、チャネル操作のための select
ステートメントがあります。これは、複数のチャネル操作のうち、準備ができたものを待機し、実行するための高レベルな並行処理プリミティブです。
一方、newselect
は、Linuxなどのオペレーティングシステムにおけるシステムコールの一つで、I/O多重化(複数のファイルディスクリプタを監視し、I/O操作の準備ができたものを検出する)のために使用されます。これは、Goの select
ステートメントとは直接関係ありません。Goランタイムは、内部的に epoll
(Linux), kqueue
(macOS/BSD), select
/newselect
(古いシステムや特定のアーキテクチャ) といった効率的なI/O多重化システムコールを使用してI/Oイベントを処理しますが、Goの select
ステートメント自体は、Goランタイムのスケジューラによって管理される高レベルな抽象化です。
このコミットで変更されている newselect
は、Goランタイム内部の関数であり、おそらくGoの select
ステートメントの内部実装や、ランタイムがI/O多重化を扱うための低レベルなメカニズムに関連していると考えられます。
技術的詳細
このコミットは、src/cmd/gc/builtin.c
ファイルに対して行われた変更であり、GoコンパイラがGoの組み込み関数をどのように認識し、処理するかを更新しています。変更は主に以下の3点です。
-
slicestring
関連関数の削除:func @\"\\\".slicestring(? string, ? int, ? int) (? string)\\n"
func @\"\\\".slicestring1(? string, ? int) (? string)\\n"
これらの関数はbuiltin.c
から削除されました。Go言語において文字列のスライスは[low:high]
構文によって直接行われ、slicestring
という名前の組み込み関数は存在しません。これらの関数は、Goコンパイラの初期開発段階における内部的な実装の一部であった可能性があり、Go言語の進化に伴い不要になったか、より効率的な内部メカニズムに置き換えられたと考えられます。Goの文字列スライスは、言語の基本的な機能として提供されており、内部的には最適化されたランタイム関数によって処理されます。
-
copy
関数の引数型の変更:- 変更前:
func @\"\\\".copy(@\"\\\".to any, @\"\\\".fr any, @\"\\\".wid uint32) (? int)\\n"
- 変更後:
func @\"\\\".copy(@\"\\\".to any, @\"\\\".fr any, @\"\\\".wid uintptr) (? int)\\n"
copy
組み込み関数の内部的な宣言において、第3引数であるwid
の型がuint32
からuintptr
に変更されました。 uint32
からuintptr
への変更の理由:copy
関数は、スライスや文字列の要素をコピーする際に、コピーするバイト数や要素数を指定するためにこのwid
引数を使用します。uint32
は固定の32ビット幅ですが、uintptr
はポインタのサイズに合わせた幅を持つ整数型です。64ビットシステムではuintptr
は64ビット幅になります。この変更は、特に64ビットアーキテクチャにおいて、より大きなメモリ領域を正確にコピーできるようにするため、またはメモリのアドレスやサイズを扱う際に、ポインタのサイズに合わせた型を使用することで、より効率的かつ安全なメモリ操作を可能にするためのものです。Goランタイムがメモリを直接操作する際に、uintptr
を使用することは一般的であり、この変更はその慣習に合わせたものと考えられます。
- 変更前:
-
newselect
関数の引数型の変更:- 変更前:
func @\"\\\".newselect(@\"\\\".size int) (@\"\\\".sel *byte)\\n"
- 変更後:
func @\"\\\".newselect(@\"\\\".size int32) (@\"\\\".sel *byte)\\n"
newselect
関数の内部的な宣言において、第1引数であるsize
の型がint
からint32
に変更されました。 int
からint32
への変更の理由:int
型はプラットフォーム依存のサイズ(32ビットまたは64ビット)を持ちますが、int32
は常に32ビットの固定サイズです。この変更は、newselect
関数が扱うサイズ情報が、異なるアーキテクチャ間でも一貫して32ビットとして扱われることを保証するためと考えられます。これは、Goランタイムが内部的に使用するデータ構造やシステムコールとのインターフェースにおいて、特定のビット幅を要求される場合に重要となります。例えば、特定のシステムコールが32ビットの整数を期待する場合、int
が64ビットシステムで64ビットになってしまうと問題が発生する可能性があります。int32
を使用することで、このようなクロスプラットフォームでの互換性や予測可能性が向上します。
- 変更前:
これらの変更は、Goコンパイラとランタイムの内部的な整合性を保ち、Go言語の進化に合わせて低レベルの最適化と正確性を向上させるためのものです。
コアとなるコードの変更箇所
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -28,8 +28,6 @@ char *runtimeimport =
"func @\"\\\".appendstr(@\"\\\".typ *byte, @\"\\\".x []byte, @\"\\\".y string) (? []byte)\\n"
"func @\"\\\".cmpstring(? string, ? string) (? int)\\n"
"func @\"\\\".eqstring(? string, ? string) (? bool)\\n"
-" func @\"\\\".slicestring(? string, ? int, ? int) (? string)\\n"
-" func @\"\\\".slicestring1(? string, ? int) (? string)\\n"
"func @\"\\\".intstring(? int64) (? string)\\n"
"func @\"\\\".slicebytetostring(? []byte) (? string)\\n"
"func @\"\\\".slicerunetostring(? []rune) (? string)\\n"
@@ -37,7 +35,7 @@ char *runtimeimport =
"func @\"\\\".stringtoslicerune(? string) (? []rune)\\n"
"func @\"\\\".stringiter(? string, ? int) (? int)\\n"
"func @\"\\\".stringiter2(? string, ? int) (@\"\\\".retk int, @\"\\\".retv rune)\\n"
-" func @\"\\\".copy(@\"\\\".to any, @\"\\\".fr any, @\"\\\".wid uint32) (? int)\\n"
+" func @\"\\\".copy(@\"\\\".to any, @\"\\\".fr any, @\"\\\".wid uintptr) (? int)\\n"
"func @\"\\\".slicestringcopy(@\"\\\".to any, @\"\\\".fr any) (? int)\\n"
"func @\"\\\".typ2Itab(@\"\\\".typ *byte, @\"\\\".typ2 *byte, @\"\\\".cache **byte) (@\"\\\".ret *byte)\\n"
"func @\"\\\".convI2E(@\"\\\".elem any) (@\"\\\".ret any)\\n"
@@ -79,7 +77,7 @@ char *runtimeimport =
"func @\"\\\".selectnbsend(@\"\\\".chanType *byte, @\"\\\".hchan chan<- any, @\"\\\".elem any) (? bool)\\n"
"func @\"\\\".selectnbrecv(@\"\\\".chanType *byte, @\"\\\".elem *any, @\"\\\".hchan <-chan any) (? bool)\\n"
"func @\"\\\".selectnbrecv2(@\"\\\".chanType *byte, @\"\\\".elem *any, @\"\\\".received *bool, @\"\\\".hchan <-chan any) (? bool)\\n"
-" func @\"\\\".newselect(@\"\\\".size int) (@\"\\\".sel *byte)\\n"
+" func @\"\\\".newselect(@\"\\\".size int32) (@\"\\\".sel *byte)\\n"
"func @\"\\\".selectsend(@\"\\\".sel *byte, @\"\\\".hchan chan<- any, @\"\\\".elem *any) (@\"\\\".selected bool)\\n"
"func @\"\\\".selectrecv(@\"\\\".sel *byte, @\"\\\".hchan <-chan any, @\"\\\".elem *any) (@\"\\\".selected bool)\\n"
"func @\"\\\".selectrecv2(@\"\\\".sel *byte, @\"\\\".hchan <-chan any, @\"\\\".elem *any, @\"\\\".received *bool) (@\"\\\".selected bool)\\n"
コアとなるコードの解説
このコミットは、src/cmd/gc/builtin.c
ファイル内の runtimeimport
というC言語の文字列リテラルを修正しています。この文字列は、GoコンパイラがGoランタイムの内部関数を認識するために使用する、特殊な形式の関数宣言のリストを含んでいます。
変更された各行について詳しく見ていきましょう。
-
slicestring
関連関数の削除:- "func @\"\\\".slicestring(? string, ? int, ? int) (? string)\\n" - "func @\"\\\".slicestring1(? string, ? int) (? string)\\n"
この2行は、
slicestring
およびslicestring1
という名前の内部関数宣言を削除しています。これらの関数は、Go言語の文字列スライス操作に関連していたと考えられますが、Goの言語仕様では文字列スライスは[low:high]
構文によって直接サポートされており、これらの内部関数はもはや必要とされなくなったか、より抽象化された形で処理されるようになったことを示唆しています。Goコンパイラは、Goのソースコードを解析する際に、これらの内部関数宣言を参照して、適切なランタイム関数呼び出しに変換します。これらの宣言が削除されたということは、コンパイラがこれらの特定の内部関数を直接参照する必要がなくなったことを意味します。 -
copy
関数の引数型の変更:- "func @\"\\\".copy(@\"\\\".to any, @\"\\\".fr any, @\"\\\".wid uint32) (? int)\\n" + "func @\"\\\".copy(@\"\\\".to any, @\"\\\".fr any, @\"\\\".wid uintptr) (? int)\\n"
この変更は、Goの組み込み関数
copy
の内部的な宣言における第3引数wid
の型をuint32
からuintptr
に変更しています。@\"\\\".copy
: これはGoの組み込みcopy
関数に対応する内部的な名前です。@\"\\\".to any, @\"\\\".fr any
:copy
関数の最初の2つの引数は、コピー元とコピー先を表し、any
は任意の型を受け入れることを示します(Go 1.18以前ではinterface{}
に相当)。@\"\\\".wid uint32
から@\"\\\".wid uintptr
へ: ここが変更点です。wid
は "width" または "size" を意味し、コピーする要素の数やバイト数を表すと考えられます。uint32
: 符号なし32ビット整数。uintptr
: ポインタのサイズに合わせた符号なし整数。 この変更は、特に64ビットシステムにおいて、copy
関数がより大きなメモリ領域を効率的かつ正確に扱えるようにするためのものです。uintptr
はポインタのサイズと同じ幅を持つため、メモリのアドレスやサイズを扱う際に、システムアーキテクチャに合わせた最適なサイズで情報を渡すことができます。これにより、メモリ操作の正確性とパフォーマンスが向上する可能性があります。
-
newselect
関数の引数型の変更:- "func @\"\\\".newselect(@\"\\\".size int) (@\"\\\".sel *byte)\\n" + "func @\"\\\".newselect(@\"\\\".size int32) (@\"\\\".sel *byte)\\n"
この変更は、Goランタイム内部の
newselect
関数の宣言における第1引数size
の型をint
からint32
に変更しています。@\"\\\".newselect
: これはGoランタイムが内部的に使用するselect
関連の関数に対応する名前です。Goのselect
ステートメントの内部実装や、I/O多重化のメカニズムに関連している可能性があります。@\"\\\".size int
から@\"\\\".size int32
へ: ここが変更点です。size
は、newselect
が扱う何らかのサイズ情報(例: 監視するチャネルの数など)を表すと考えられます。int
: プラットフォーム依存の符号付き整数(32ビットまたは64ビット)。int32
: 常に32ビットの符号付き整数。 この変更は、newselect
関数が扱うサイズ情報が、異なるアーキテクチャ間でも一貫して32ビットとして扱われることを保証するためのものです。これにより、クロスプラットフォームでの互換性が向上し、特定のシステムコールや内部データ構造が32ビット整数を期待する場合の潜在的な問題を回避できます。
これらの変更は、Goコンパイラとランタイムの内部的な整合性を維持し、Go言語の進化と異なるアーキテクチャへの対応を考慮した、低レベルなメンテナンスと最適化の一環として行われたものです。
関連リンク
- Go CL 6733057: https://golang.org/cl/6733057
参考にした情報源リンク
- Go言語の
cmd/gc
,builtin.c
,runtime.go
に関する情報:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHoVQ_h_pOKGArnCY9AvWiqXwYVqoyGoDEw0HbmsgVLuX2UPkFwDJWmzXSbPG4v_0RDQxlF782F-4YSeveSnDm640LdD8dV18_Hn14EOz57T8pN_nb-X1pqn7W3bqdbkiWwSS1dPlYkej2BuGFGtLNVGXeXb52OB_Kx4X8A
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHW6nwp3uNHd6_sNbpSD3SW6XUSWdeqsDAiWGZCEemYhuVZGEUQjzvcAOuFk2uLM90uZdF7KhVSKV3I3BAAU7X-C0wtw9jsRRQmIHZzQwpURo-F7mfMvj7yM3heyDRtkY10z9zPbLqs5KzDzDzVTAtMP32IROxtpo23a0NSs0Jbh0yfDk2fUyE-cRYq-ve8fAngSNqWHJLn6JMeUCqIe9
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFFEH5LySphLJ-a242YmkrxOapuQyFnt--SSBygc2y5hLT245dwHHRLHkglAk9e9dlKVZy18jwGALqyu7uIbDk6KM8kNjcGBSMWrh-_5JzhDPuRm4zmSPEppHEbPtEG71YK
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQF8WrrUfFxDsTSbGQgLJbz98gKn6elFgrkqkP4W2X-yN_PfZRLb7ILPtGNYmy3fAHGhYkO9fbRffmi7CfbbH5NYSqdlzwFpXOvLa5OvpZDmaCq_vJK9atDaqdWy_wFxMy8=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHfMtAzD_2-wpUJVIyGaounYEm6Rz9nN7A0Z8StWVImr5vr_bFCJI7p2oFjL6jVt7vght7U2mVyd9mPwv3H0amZnwDlLWi_vGkmkC36eJkQW60yaVM=
- Go言語の
slicestring
に関する情報:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGT-HhJx8Di26oz5P4MZL1YHQmX4mc079K94P6zJP-zAsJ9S0uOW_kaDBpTuRdoRj9rTXPKnMmMdXMEFn4nuHGXPdhe9DPB3xqRz5vsDqjUa2iPpzJqf4D5
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHOH0-U9CEFkRZonU-PfKCOTg3mtgmhsRIGh-njpuaoUvuORQm0KwmRPYFFB2C0BWHDlo91bsA_s1jiOcRHEE3lUdN23E4RHbAe1aElvb-wpdg=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHhtv06-gc5n6V0vIakwsNT2A88oSqoR3x6W4GYZ3nOZoVHR40ak_sXkjWGCCVT24aVI5y9pSIcCEUXZu1OKiUoJ9PGErCsZAevvFyr0xgTjv84TvwvPU0NljILSwe2B5I1kGdUB6d24NPbz2lnguoYuWDYCH_fq4yfbV9iVmwx3hl2yg==
- Go言語の
uint32
とuintptr
に関する情報:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGBVqE82Vj6slY_qayxLKWrNTvIh4YyV_VjrPjWaDuSU_LE_4LgJfpNFWUpphvPOrYaWk47n1emF_wYEWzhZuDQSBuf_w2QBahNNzligXA5zX0HLrG1nmrAaYH3q4SSzpfS6mZuYVnCt3aj4b63yY_k__X4E5vvD-De
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGTM_AfFcfHmUPllHnOMXVpMuw5Hc5OqqI4VvI2B_xbjICxbmGkJHOCre2mRDUgcMLJpRXpHj53t-xER3-DIn6nhtH08n3solMrIvK2WIUs0J9KEs6gg8kGwtTi1P5ALXt0-bgvVkgBeIUGzerpPecu2CYb8fSlKfdh4SZYarHJPgmKXfuB5bokUnV6x6p1UXY3tW7MhiHqXFAuAUkD5tuyUiRKHvYk99tLv37DlL2xJvKmiBTb0AAsAg==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEFU4P1N-Uo-TDBJGY-jExOprQSXTAQ6cFlKT5MAqTJpo2QEmHu5xLeXAHEGBoWk2gRdJQyXTgwPgCrwx6EOdEZ1Jl64e9z0DpTgDlbcPKck2lwQwFd
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHYQQtwdDyyjTWWtW66SO0N0V4XY2WtA0yEAwYJdfU7gLb2S1QyUFXg9F8339bXm9SMizZVNAPl-rhfQRnv6M3Z3-qpEVwFxL2oBiw7-ANijtTO3MkM1p4esl43teyedCkzo0pWM3fm4cHPAW6iX6pOsnHh1tdsNyEbnBGs9GhzzErPHxQppam0xUhv3YsWnD4maPtuMDu_0rdxnpkd6WFacM75Kj8=
- Go言語の
int
とint32
、newselect
に関する情報:- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQE8cKBwr87pKFBPC7szbcD4kTznPsVyDzslMoUFgctXtq5uc3N_4pggfdq46-nvR3jXeM4x6Oxu4X0OADVe2OzoQOD_J2DmTJKFqmHToHgunHMd2JWlJ2Jgk1UVuFxH17szq3OpDulkPPMFQGasihfUVQBuxKphkUx9U8IVn_FRGslNKhdqLBXMjfbWJuCuSDX1HTAgnpKl
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEOFPqnDR_4OC475MYRFJda5fgXOFdfD8IN0IIlS2NjJbLAsBpNiVkhODLbCz_aVSziWMHV10eZhAkgkkIXFwuuyot6ZGKxIsef8L9zrpf81HecowI7
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHF8EOAkSeNzEtxF0rvZhCOP3IIXSLFzM6dmzQQkfmyYSJQflFipiNfbBBReBYsj3TYxtENsbItI-3ADML57Ky9kUP7feTGMJ1hfTvzjnFBZGf0a27nRrQSPHbojp5fNHhsg2pYxszzkkHnnRA==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEuLhoF1ECNPW9vAmmkWa3xmDFDA1ooGTEuwf45cbOAVnNjsMO8JoaO4lrd25tbtFIoe4om2ePCPT3Rt-ucuE5hfRfRwGc5IiXlR1XRUmNa4pWmKIm3bAydvcfntz-SU9tcCmZRwPnap_uHnVzLAY8OBWje8Fj2huGGW-3_K3bQ4M5hXOY5
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGsEli1XXQ6EiP5vCK-mO-N_0U0uH1y-e2GPcWvGvfmrI8-J2OUcEPaWUx-HvLEMe6xIlAnbzOgOHDQL10qJtpW_q2EJtZ2zdl0cXAqKhUpCShypvsfH5s3xWkNwM-cW0a67u3Lgj14srccAX_mfinbrqfHZcHI4shEAmqxvcWjS9juQdFloqW1AU3QW5tte2auHICWz88RmMmUATg=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGIlB-N3De7vxsvjJrEWOhTv6-AVzOiyyxuLv3BSdDbttp8ukgS4nJOK22xdGcP8tqobSqaARHfb_FWdbQ1hTWcQi1kFxvIQpPo-Z__mKgyeampgmQTQagpWpx2OT0WYy9WDIdmWa-8UEM3JNfplAk36eHV0f_-q7c0_VutuS2GkFuRgrRFZJArO9tM2ZMrRFvTo503ge3i1SY-xApV1_5Q
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQER9DzDparL2izq1gfUKGGyGZZKu6JZNz8DUpzty0av00TtOOylqDtN0w_QMqtTTrKH_yruEEjPUmw5jfq14OF6FJSKtAw0nQf5Z79CGblBNCwho8SqXzI-3Pg51JH29bvKCHuq_dP7-L5WsSOyaWKff0_EwJObBkZffg_Q79YO