MMgc内でもtemplateはよく見かけるけど、実際に使われていないものも多いみたい。
普段はおしゃべりなコメントも、template部分では寡黙になる。
重要そうなtemplateをメモ。
[cpp]
// ライトバリア
// # define DWB(type) MMgc::WriteBarrier< type >
template
class WriteBarrier {
private:
// ここのインライン化は重要らしい
REALLY_INLINE
T set(const T tNew) {
GC::WriteBarrier(&t, (const void*)tNew); // t を更新
return tNew;
}
public:
explicit REALLY_INLINE WriteBarrier() : t(0) {
}
explicit REALLY_INLINE WriteBarrier(T _t) {
set(_t);
}
REALLY_INLINE ~WriteBarrier() {
t = 0;
}
REALLY_INLINE T operator=(const WriteBarrier
return set(wb.t);
}
REALLY_INLINE T operator=(T tNew) {
return set(tNew);
}
// 目を背けてはいけない
REALLY_INLINE operator T() const { return t; }
REALLY_INLINE T value() const { return t; }
REALLY_INLINE operator ZeroPtr
REALLY_INLINE bool operator!=(T other) const { return other != t; }
REALLY_INLINE T operator->() const { return t; }
private:
// コピーを防ぐ (宣言のみで実装はされない)
WriteBarrier(const WriteBarrier
T t;
};
template
class ZeroPtr {
public:
ZeroPtr() { t = NULL; }
ZeroPtr(T _t) : t(_t) { }
~ZeroPtr() { t = NULL; }
operator T() { return t; }
bool operator!=(T other) { return other != t; }
T operator->() const { return t; }
private:
T t;
};
// ———————————————————–
// 弱参照
template
class GCWeakRefPtr {
public:
GCWeakRefPtr() {}
GCWeakRefPtr(T t) { set(t); }
~GCWeakRefPtr() { t = NULL; }
T operator=(const GCWeakRefPtr
T operator=(T tNew) { return set(tNew); }
operator T() const { return (T) t->get(); }
bool operator!=(T other) const { return other != t; }
T operator->() const { return (T) t->get(); }
private:
T set(const T tNew) {
t = tNew->GetWeakRef();
}
// GCObject への Fat Pointer、GCはハッシュテーブルを持つ({weakref:object, …})
GCWeakRef* t;
};
[/cpp]
* Fat Pointer
通常の1 ワードから2 ワードに拡張したポインタ。1 ワード目は常にメモリブロックの先頭を指す「Base」、2 ワード目はポインタの指しているメモリがベースから何バイト離れているかを示す「Offset」になっている。これを使うとメモリアクセスの際に境界チェックが高速に行える。 また、ヘッダは必ずBase の手前に置かれるので、ヘッダへのアクセスを安全かつ高速に行うことができる。
* 関連記事
Flashのガベージコレクション – 遅延参照カウント