ARRAY-TOTAL-SIZE-LIMIT


Tags: 定数, 制限

array-total-size-limitは配列に入れることができる要素の最大数より1大きい数です。すべての配列に共通する制限で、変更はできません。具体的な値は処理系によって異なりますが、少なくとも1024より大きい数にするように決められています。

あまり関わりがないと思いがちですが、(unsigned-byte 8)の配列に大きめのデータを読み込んだり、長い文字列を作ったりすると(文字列は文字の配列なので)、主に32ビットの環境で、この制限にかかる場合があります。

プラットフォーム リミット
CLISP 2.49 32-bit 2^24 - 1 = 16777215
CLISP 2.49 64-bit 2^32 - 1 = 4294967295
Clozure CL? 1.7 64-bit 2^56 = 72057594037927936
Clozure CL? 1.7 32-bit 2^24 = 16777216
LispWorks? 6.0.1 32-bit 67108337 (≒ 2^26)
LispWorks? 7.1 64-bit 2^29 - 1 = 536870911
Steel Bank Common Lisp? 1.0.53 64-bit 4611686018427387901 (≒ 2^62)
Allegro CL? 32-bit 2^29 - 1 = 536870911
Allegro CL? 64-bit 2^60 - 1 = 1152921504606846975
XCL 64-bit 2^61 - 1 = 2305843009213693951
CMUCL 20c 32-bit 2^29 - 1 = 536870911
ABCL 1.0.0 2^31 - 1 = 2147483647
Scieneer CL 1.3.9 64-bit 2^60 - 1 = 1152921504606846975
GCL 2.6.7 CLtL1 64-bit 2^31 - 1 = 2147483647

Clozure CL?

64ビットの環境で2^56(72057594037927936)、32ビットの環境で2^24(16777216)に設定されています。

17.2. Register usage and taggingの"17.2.4. Tagging scheme"で詳しく説明されていますが、即値(環境ごとに何が即値かは異なります)とコンスセル以外のLispオブジェクトは、Clozure CLではuvectorというデータ構造で表現されています。

uvectorでは、データ構造の最初の1[[$$wp ワード]]に内容の型を表す情報(8ビット)と要素の数(1ワード - 8ビット)が入るように決まっています。そして、配列は即値でもコンスセルでもありませんから、uvectorとして扱われます。そのため、配列の要素の数も1ワード - 8ビットの領域に記録されることになり、64ビットの環境では56ビット(0~2^56 - 1)、32ビットの環境では24ビット(0~2^24 - 1)の範囲に要素の数も制限されます。

■32ビット環境でのuvectorの構造

 0  1  2  3  4  5  6  7  8  9 10  ... 28 29 30 31 32 33 34 35 36 ...
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━
┃       型情報         ┃       要素の数         ┃  実際のデータ
┗━━━━━━━━━━━┻━━━━━━━━━━━━┻━━━━━━━━

参考文献