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

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

このコミットは、Go言語のテストスイートにおいて、int型が常に32ビットであるという仮定を排除し、64ビット整数環境への対応を準備するための変更を含んでいます。具体的には、境界チェックのテスト、make組み込み関数によるスライス、マップ、チャネルの作成時のサイズ関連のバグテスト、およびスタックフレームサイズに関するテストが修正されています。

コミット

commit 0d82e698112464ea99bdd8cc2e695902b32e8e61
Author: Russ Cox <rsc@golang.org>
Date:   Mon Sep 24 00:06:41 2012 -0400

    test: prepare for 64-bit ints
    
    Minor tweaks to avoid assuming that int is always 32 bits.
    
    Update #2188.
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/6553062

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

https://github.com/golang/go/commit/0d82e698112464ea99bdd8cc2e695902b32e8e61

元コミット内容

test: prepare for 64-bit ints

Minor tweaks to avoid assuming that int is always 32 bits.

Update #2188.

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

変更の背景

Go言語はクロスプラットフォーム対応を重視しており、異なるアーキテクチャ(32ビットシステムと64ビットシステム)で一貫した動作を保証する必要があります。Goのint型は、その実行環境のネイティブな整数サイズに依存します。つまり、32ビットシステムではintは32ビット、64ビットシステムではintは64ビットになります。

このコミットが行われた2012年当時、Goのテストスイートの一部には、int型が常に32ビットであるという暗黙の仮定が含まれていました。この仮定は、特にメモリ割り当て、配列のインデックス計算、チャネルのバッファサイズ計算など、サイズに敏感な操作において問題を引き起こす可能性がありました。64ビットシステムでこれらのテストを実行すると、期待されるエラーが発生しなかったり、異なる動作を示したりする可能性がありました。

この変更の主な目的は、int型のサイズに依存しない堅牢なテストを作成し、Go言語が将来的に64ビットシステムでより適切に動作するように準備することです。コミットメッセージにある「Update #2188」は、この変更が特定の課題(Go issue 2188)に対応していることを示唆していますが、現時点でのWeb検索では、このコミットと直接関連するGoの公式なissue #2188の具体的な内容は特定できませんでした。しかし、文脈から判断すると、intのサイズに関する問題や、それによって引き起こされるテストの不安定性に対処するためのものと考えられます。

前提知識の解説

  • Go言語のint: Go言語のint型は、プラットフォームに依存する整数型です。32ビットシステムでは32ビット幅、64ビットシステムでは64ビット幅を持ちます。これは、C言語のint型が通常、システムによってサイズが異なるのと同様です。
  • int64: int64型は、Go言語において常に64ビット幅を持つ符号付き整数型です。プラットフォームに依存せず、常に同じサイズを保証します。
  • 境界チェック (Bounds Checking): Go言語は、スライスや配列へのアクセス時に、インデックスが有効な範囲内にあるかを自動的にチェックします。これにより、無効なメモリ領域へのアクセスを防ぎ、プログラムの安全性を高めます。コンパイラは、インデックスが常に有効であることが静的に判断できる場合、このチェックを最適化(elide)して実行時のオーバーヘッドを削減することがあります。
  • make組み込み関数: Go言語のmake関数は、スライス、マップ、チャネルといった組み込みの参照型を初期化するために使用されます。
    • make([]T, len, cap): スライスを作成します。lenは初期の長さ、capは容量です。
    • make(map[K]V, cap): マップを作成します。capは初期容量のヒントです。
    • make(chan T, cap): チャネルを作成します。capはバッファ容量です。 これらの関数に負の値や非常に大きな値を渡すと、パニック(実行時エラー)が発生することが期待されます。
  • unsafe.Sizeof: unsafeパッケージは、Goの型システムの安全性をバイパスする低レベルな操作を提供します。unsafe.Sizeofは、Goの値のメモリサイズをバイト単位で返します。この関数は、特定のアーキテクチャに依存するコードを書く際に使用されることがありますが、ポータビリティを損なう可能性があります。

技術的詳細

このコミットは、主にGoのテストコードに変更を加えており、int型が32ビットであるという仮定を取り除くことで、64ビットシステムでのテストの信頼性を向上させています。

test/bounds.go の変更

このファイルは、コンパイラが境界チェックを省略(elide)できるかどうかをテストするためのものです。 変更前は、use(a100k[ui/1e6]) // ERROR "index bounds check elided" のように、特定のインデックスアクセスに対して「境界チェックが省略される」ことを期待するコメントが付いていました。

  • 変更内容: ERROR "index bounds check elided" というコメントが削除されました。
  • 技術的意味: これは、intが64ビットになる環境では、以前はコンパイラが静的に安全と判断して境界チェックを省略していたケースでも、もはや省略できない可能性があることを示唆しています。あるいは、テストの意図が「境界チェックが省略されること」ではなく、「コードが正しく動作すること」に変わったことを意味するかもしれません。intが64ビットになると、ui/1e6のような計算結果が32ビットの範囲を超える可能性があり、その結果、コンパイラがより保守的になり、境界チェックを省略しなくなることが考えられます。

test/fixedbugs/bug273.go の変更

このファイルは、make関数に無効な引数(負の値や非常に大きな値)を渡した場合に、期待通りパニックが発生するかどうかをテストするものです。

  • import "unsafe" の削除: unsafe.Sizeofの使用がなくなったため、関連するインポートも削除されました。

  • g1 の型変更: var g1 []int から var g1 []block に変更されました。ここで type block [1<<19]byte は、1<<19バイト(512KB)の固定サイズのバイト配列です。

  • g3 の型変更: var g3 map[int]int から var g3 map[block]block に変更されました。

  • g4 の型変更: var g4 chan int から var g4 chan cblock に変更されました。ここで type cblock [1<<16-1]byte は、1<<16-1バイト(65535バイト、約64KB)の固定サイズのバイト配列です。

  • overflowchan 関数の変更:

    • 以前は addrBits == 32 の条件分岐があり、32ビットシステムでのみチャネルのオーバーフローをテストしていました。これは、32ビットシステムではintが32ビットであり、チャネルの最大値サイズが64KBであるため、make(chan [1<<15]byte, 1<<20) のような大きなチャネルを作成しようとするとオーバーフローする可能性があったためです。
    • 変更後、この条件分岐は削除され、g4 = make(chan cblock, 1<<30) となりました。cblockは固定サイズ(約64KB)であり、1<<30という非常に大きなバッファ容量を指定することで、intのサイズに関わらず、チャネルの作成がメモリ制限や内部的な最大値を超過してパニックを引き起こすことを意図しています。
  • 技術的意味:

    • 以前のテストは、intが32ビットであることを前提に、make関数に渡される引数がオーバーフローするかどうかを検証していました。しかし、intが64ビットになると、これらの引数はオーバーフローしなくなり、テストが失敗する(パニックが発生しない)可能性がありました。
    • 新しいテストでは、intの代わりに、blockcblockのような固定サイズの大きな型を使用しています。これにより、make関数に渡される引数(スライス、マップ、チャネルの要素のサイズや容量)が、intのサイズに依存せず、常に十分な大きさを持つようになります。これにより、32ビットシステムでも64ビットシステムでも、期待されるパニックが確実に発生するようになります。
    • 特にoverflowchanの変更は、intのサイズに依存するunsafe.Sizeofの使用を排除し、よりポータブルな方法でチャネルの容量オーバーフローをテストするように改善されています。

test/fixedbugs/bug385_64.go の変更

このファイルは、非常に大きな配列をスタック上に割り当てようとした場合に、「スタックフレームが大きすぎる」というエラー(ERROR "stack frame too large")が発生するかどうかをテストするものです。

  • 変更内容: var arr [1000200030]int から var arr [1000200030]int32 に変更されました。
  • 技術的意味:
    • 以前のコードでは、配列の要素型がintでした。64ビットシステムではintが64ビットになるため、1000200030 * 8バイトという非常に大きなメモリがスタックに割り当てられようとします。これは32ビットシステムでの1000200030 * 4バイトよりもさらに大きくなります。
    • int32を明示的に使用することで、配列の各要素が常に32ビット(4バイト)であることを保証します。これにより、1000200030 * 4バイトという、32ビットシステムでも64ビットシステムでも一貫して「スタックフレームが大きすぎる」と判断されるようなサイズを意図的に作成しています。
    • この変更により、テストがintのサイズに依存せず、異なるアーキテクチャで一貫して同じエラーを検出できるようになります。

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

このコミットは、Go言語のランタイムやコンパイラのコアコードではなく、主にテストコードに変更を加えています。

  • test/bounds.go: 境界チェックの最適化に関するテストのコメント修正。
  • test/fixedbugs/bug273.go: make関数によるスライス、マップ、チャネルの作成時のサイズ関連のバグテストの修正。int型への依存を排除し、固定サイズの大きな型を使用するように変更。
  • test/fixedbugs/bug385_64.go: スタックフレームが大きすぎるエラーをテストする際の配列要素型をintからint32に明示的に変更。

コアとなるコードの解説

このコミットの「コア」は、Go言語のテストの堅牢性を高めるためのアプローチにあります。

  1. int型への依存の排除: 以前のテストは、int型が32ビットであるという暗黙の仮定に基づいていました。これは、32ビットシステムでは問題ありませんでしたが、64ビットシステムではintが64ビットになるため、テストの意図が損なわれたり、期待されるエラーが発生しなくなったりする可能性がありました。このコミットでは、intの代わりにint32を明示的に使用したり、blockcblockのような固定サイズの大きな型を導入したりすることで、intのサイズに依存しないテストを実現しています。
  2. ポータビリティの向上: unsafe.Sizeofの使用を避け、特定のアーキテクチャに依存する条件分岐を削除することで、テストコードのポータビリティが向上しています。これにより、Go言語がサポートするすべてのアーキテクチャで、テストが期待通りに動作することが保証されます。
  3. テストの正確性の維持: make関数に無効な引数を渡した場合のパニックテストや、スタックフレームが大きすぎる場合のテストなど、特定の実行時エラーを検出するテストにおいて、intのサイズ変更によってテストの意図が曖昧になることを防ぎ、正確にエラーを検出できるように修正されています。

これらの変更は、Go言語が異なるアーキテクチャで一貫した動作を提供するための基盤を強化し、将来的なGo言語の進化に対応するための重要なステップと言えます。

関連リンク

(注:コミットメッセージに記載されているGo issue #2188の具体的な内容は、現時点でのWeb検索では特定できませんでした。)

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Gitのコミットログと差分
  • Go言語のテストコードの慣習に関する一般的な知識
  • Go言語のint型の特性に関する一般的な知識