MMgc内でもtemplateはよく見かけるけど、実際に使われていないものも多いみたい。
普段はおしゃべりなコメントも、template部分では寡黙になる。
重要そうなtemplateをメモ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// ライトバリア // # define DWB(type) MMgc::WriteBarrier< type > template<class T> 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<T>& wb) { 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<T>() const { return t; } REALLY_INLINE bool operator!=(T other) const { return other != t; } REALLY_INLINE T operator->() const { return t; } private: // コピーを防ぐ (宣言のみで実装はされない) WriteBarrier(const WriteBarrier<T>& toCopy); T t; }; template<class T> 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 T> class GCWeakRefPtr { public: GCWeakRefPtr() {} GCWeakRefPtr(T t) { set(t); } ~GCWeakRefPtr() { t = NULL; } T operator=(const GCWeakRefPtr<T>& wb) { return set(wb.t); } 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; }; |
* Fat Pointer
通常の1 ワードから2 ワードに拡張したポインタ。1 ワード目は常にメモリブロックの先頭を指す「Base」、2 ワード目はポインタの指しているメモリがベースから何バイト離れているかを示す「Offset」になっている。これを使うとメモリアクセスの際に境界チェックが高速に行える。 また、ヘッダは必ずBase の手前に置かれるので、ヘッダへのアクセスを安全かつ高速に行うことができる。
* 関連記事
Flashのガベージコレクション – 遅延参照カウント