GC in C++0x
-
Upload
yak1ex -
Category
Technology
-
view
4.386 -
download
1
Transcript of GC in C++0x
GC in C++0x
2010/8/8 GC本読書会
新 康孝yak_ex
自己紹介
氏名: 新 康孝 (あたらし やすたか) Twitter ID: yak_ex Web: http://yak3.myhome.cx:8080/junks
C++ / Perl が主戦場 某自動車部品メーカーから某自動車メーカーへ出向中 現在、仕事でコードに触れていない 競技プログラミング(TopCoder、Codeforces)で潤い補充
GC は「ど素人」
渡る世間は GC ばかり
Google Code Jam 2010 Qualifier 使用言語
1位 C++ 4911 6位 Ruby 221
2位 Java 2762 7位 PHP 170
3位 Python 1459 8位 Perl 146
4位 C 751 9位 Haskell 118
5位 C# 648 10位 Pascal 95
渡る世間は GC ばかり
Google Code Jam 2010 Qualifier 使用言語
黄色ハイライト=GC有り言語
1位 C++ 4911 6位 Ruby 221
2位 Java 2762 7位 PHP 170
3位 Python 1459 8位 Perl 146
4位 C 751 9位 Haskell 118
5位 C# 648 10位 Pascal 95
渡る世間は GC ばかり
Google Code Jam 2010 Qualifier 使用言語
黄色ハイライト=GC有り言語
1位 C++ 4911 6位 Ruby 221
2位 Java 2762 7位 PHP 170
3位 Python 1459 8位 Perl 146
4位 C 751 9位 Haskell 118
5位 C# 648 10位 Pascal 95
超一線級言語でありながら GC 無し : C++は孤高
C++は孤高
そんな C++ を支える C++er 達
C++は孤高
そんな C++ を支える C++er 達
闇
C++は孤高
そんな C++ を支える C++er 達
闇
の
C++は孤高
そんな C++ を支える C++er 達
闇
の
軍
C++は孤高
そんな C++ を支える C++er 達
闇
の
軍
団
C++は孤高
そんな C++ を支える C++er 達
闇へ
の ん
軍た
団い
マルチパラダイム変態言語C++
次期標準規格 C++ 0x では
Garbage Collection
and
Reachability-Based Leak Detection
Support for
マルチパラダイム変態言語C++
次期標準規格 C++ 0x では
Minimal
Garbage Collection
and
Reachability-Based Leak Detection
Support for
Minimal Support for GC 以下略
いくつかの概念
Traceable pointer object
Safely-derived pointer (value)
5つの関数
get_pointer_safety()
(un)declare_no_pointers()
(un)declare_reachable()
いくつかの概念(1)
Traceable pointer object
ポインタobj
ポインタを格納するのに十分なサイズの整数obj
キャラクタ型の配列の一部分キャラクタ型だけな理由は恐らく strict aliasing rule
→ポインタ値が入っているかもしれないと処理系に認識してもらえるobject
=他の部分にはポインタ値が入っていない前提
いくつかの概念(2)
Safely-derived pointer (value) ::operator new で返ってきた値 (例: new T)
Safely-derived pointer value に対する
逆参照→参照の結果 (例: &*p)
ポインタ値の well-defined な演算結果 (例: p+1)
ポインタ間の well-defined な変換結果(例: static_cast<void*>(p))
ポインタ・整数値間の reinterpret_cast による変換結果(例: reinterpret_cast<intptr_t>(p))
→::operator new で確保された領域でかつ有効であることが処理系から確実に追跡可能なポインタ値
いくつかの概念(3)
Safely-derived pointer (value)
T *p = new T;intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555a:T *q = reinterpret_cast<T*>(x ^ 0x555);T y = *q;
これは safely-derived pointer value
こっちは safely-derived pointer value ではない
これも safely-derived pointer value ではない!※値としては p と同じだが、結果ではなくて過程で判断
Minimal Support for GC 以下略
いくつかの概念
Traceable pointer object
Safely-derived pointer (value)
5つの関数
get_pointer_safety()
(un)declare_no_pointers()
(un)declare_reachable()
関数: get_pointer_safety()
処理系のポインタ安全性(pointer safety)を返す
relaxed:
preferred:
strict:
Safely-derived pointer であるかによって処理が変わらない=C++03相当※relaxed と preferred は処理系定義
preferred だと leak detector があったりするかもしれない
※VC2010 は relaxed 返して他の関数も何もしない
safely-derived pointer でないポインタ値(かつ後述の declare_reachable() が呼ばれていない値)を介して動的確保された領域を逆参照、解放すると未定義動作
Strict pointer safety
Safely-derived pointer (value)
T *p = new T;intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555a:T *q = reinterpret_cast<T*>(x ^ 0x555);T y = *q;
これは safely-derived pointer value
こっちは safely-derived pointer value ではない
これも safely-derived pointer value ではない!※値としては p と同じだが、結果ではなくて過程で判断
未定義動作
関数: (un)declare_no_pointers()
void declare_no_pointers(char *p, size_t n);
void undeclare_no_pointers(char *p, size_t n);
指定された領域内にポインタ値がないことを指定 or 指定解除する
→GC のスキャン範囲を狭められる
関数: (un)declare_reachable
void declare_reachable(void *p); safely-derived な pointer 値 p の参照先を
reachable だと宣言する
→参照先を GC 対象からはずす
template<class T>T* undeclare_reachable(T *p); 参照先が reachable な p に対して、
safely-derived な pointer 値(pと同じ値)を返す
→参照先が GC 対象に復帰する
(※返値が safely-derived なので有効である間はGCされない)
(un)declare_reachable()の使い方
どうして必要なの?
T *p = new T;intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555a:T *q = reinterpret_cast<T*>(x ^ 0x555);T y = *q;
これは safely-derived pointer value
こっちは safely-derived pointer value ではない
これも safely-derived pointer value ではない!※値としては p と同じだが、結果ではなくて過程で判断
未定義動作
「ラベル a: の位置で GC がかかると p の参照先が回収される」 ???
(un)declare_reachable()の使い方
どうして必要なの?
T *p = new T;intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555a:T *q = reinterpret_cast<T*>(x ^ 0x555);T y = *q;
これは safely-derived pointer value
こっちは safely-derived pointer value ではない
これも safely-derived pointer value ではない!※値としては p と同じだが、結果ではなくて過程で判断
未定義動作
「ラベル a: の位置で GC がかかると p の参照先が回収される」 問題は最適化
(un)declare_reachable()の使い方
どうして必要なの?
T *p = new T;intptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555a:T *q = reinterpret_cast<T*>(x ^ 0x555);T y = *q;
「ラベル a: の位置で GC がかかると p の参照先が回収される」 問題は最適化
以降 p の値は使われない
※ p, x, q を同じレジスタに割り当てることが可能→ラベル a: の時点で p の値がどこにも存在しない→p の参照先 = q の参照先が GC の回収対象になる!!→*q で未定義動作
以降 x の値は使われない
(un)declare_reachable()の使い方
C++0xでの正しいコード
T *p = new T;declare_reachable(p); // 偽装前に declare_reachable() を呼ぶintptr_t x = reinterpret_cast<intptr_t>(p) ^ 0x555a:// T z = *reinterpret_cast<T*>(x ^ 0x555); // 合法// 偽装終了時に undeclare_reachable() を呼ぶT *q = undeclare_reachable(reinterpret_cast<T*>(x ^ 0x555));T y = *q;
注※ declare_reachable した値と同じであれば safely-derived でなくとも逆参照が可能※ undeclare_reachable の引数は safely-derived でなくとも reachable であれば良い※ declare_reachable については「ポインタ値を偽装する」点が問題
a: で関数が別れている場合を考えれば最適化なしで議論は一緒
*p はreachable=GC対象外
まとめ
C++0x では最小限の GC サポートがある Safely-derived pointer という概念= GC されていない生きているポインタ値
5 つの関数が追加
C++03相当でも規格合致(relaxed)
しばらくそれ以上の実装はでなさそう?
ポインタ値を偽装するコードはdeclare_reachable() / undeclare_reachable()を使って修正する必要がある
参考文献
N2670: Minimal Support for Garbage Collection and Reachability-Based Leak Detection (revised)http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm
Garbage Collection in the Next C++ Standardhttp://www.hpl.hp.com/techreports/2009/HPL-2009-360.pdf