Vector heads

Vector headの設計は微妙に難しい。なぜなら、ベクタをユーザ定義可能にするとは、GCのための手続きを提供できるようにすることを示す。もちろん、通常のシチュエーションであればread,write,displayのための手続きも提供したいだろう。
Vector headは15bitsのアドレスと11bitsのタイプの組み合わせとなる。
11bitsは以下のようにつかう。

+---+---------+
|DMU|tttt tttt|
+---+---------+
  • D : dig down bit

Dがセットされていれば、GCVectorの内容をチェックする。この情報自体はtypeからオブジェクトシステムにクエリすることでも導かれるが、GCは非常に頻繁に行われるので、この1bitを消費してキャッシュすることには価値がある。
Vectorがユーザ定義の型を持つなら、GCはそのためのプロシジャを起動する。

  • M : movable bit

Fがセットされていれば、内容は安全に移動できる可能性がある。直感的にはD = 0ならばポインタを含んでいないように考えられるが、DMAバッファのように移動は安全でないがポインタを含まないというケースも存在する。
メモリ領域を移動してまで空き領域を確保することには賛否両論がある。暫くは実装しない。

  • U : user type flag

Uがセットされていれば、ユーザ定義の型であることを示す。

  • t : type field

タイプの値を入れる。

セグメント

Vector headは"セグメント"と呼ばれるメモリブロックを指す。これは要するに普通のmallocで確保されるようなメモリブロックで、次のような構造を持つ(すべて16bit幅) :

  +------------------+
-2|NEXT SEGMENT HDR|F|
  +------------------+
-1|    REVERSE PTR   |
  +------------------+
+0|       Data       |
  +------------------+
+1|         :        |

次のセグメントヘッダの位置や、フリーブロックかどうかのフラグ、自身を指すVector headへのポインタなどを含む。

system types

幾つかのtypeはユーザには見えないところで使われる。つまり、

  • 0 : free
  • 1 : cells
  • 2 : number
  • 3 : string
  • 4 : vector
  • 5 : bytevector
  • 6 : ...

metacell

atomのtype = 7を使って"meta" cellを定義する。セグメントを利用するよりもlistや他の構造を再解釈することの方が望ましいデータのために、タグを付ける。構造はVector headと同様。
こちらのtypeは、

  • 1 : ratnum
  • 2 : Z
  • 3 : string list
  • 4 : ...

のように使う。stringが両方にあるのは、いわゆるrope構造のように複数の文字列を連結した文字列の実現のため。