2012年12月22日土曜日

言語C でスコープドポインタを実現する(その4)

リファレンスの生成

リファレンスの生成は次のように行っている。
Reference NO_INSTRUMENT new_Reference(void* object,
 void (*destructor)(void* object))
{
 Reference this = (Reference)malloc(sizeof(struct Reference));
 if (this != null) {
  this->object = object;
  this->frames = frames;
  this->referenceCounter = 1;
  this->destructor = destructor;
 }
 add(this);
 return this;
}
ヒープ領域からメモリを割り当て、オブジェクトとデストラクタ、framesを記憶し、参照カウンタは1で初期化する。
この実験コードでの framesはグローバル変数であり、複数スレッドに対応していないが、マルチスレッド化するときには framesは TLSに配置される予定である。その場合、Referenceがどの framesに対応しているか素早く探すためのものである。
TLSからキーで検索するならこれは不要である。

つぎに生成したリファレンスを framesに登録するために add関数を呼ぶ。
メモリ割り当てに失敗したときにも addししまうのは暫定のためである。
再帰呼び出しされる関数の中でリファレンスが作られるなら、単純に if文の中に入れれば良いと言うわけにはいかない(復帰時に他の階層のリファレンスを破棄する恐れがある)ので、何らかの配慮が必要になる。

その add関数はつぎの通り。
private void add(Reference r) {
 int top = ArrayList_size(frames) - 1;
 Frame frame = ArrayList_get(frames, top);
 ArrayList_add(frame->references, r);
}

framesリストの先頭にある frameリストを取り出す。
frameリストにリファレンスを追加する。

framesと frameの各リストの構造を(その2)の例題 testAutoCollectを例に図式化すると次のようになる。





洗濯機が貰えるなら僕らもノーベル賞取ろうよ。

0 件のコメント:

コメントを投稿