[Python-ml-jp 2327] Re: [OT] Re: Ruby/Swig

suzuki611 @ okisoft.co.jp suzuki611 @ okisoft.co.jp
2003年 6月 6日 (金) 16:44:20 JST


In <1054695074.221311.28636.nullmailer @ picachu.netlab.jp>,
Yukihiro Matsumoto wrote:
>In message "[Python-ml-jp 2314] Re: Python/C APIについて"
>    on 03/06/04, Shibukawa Yoshiki <yoshiki @ shibu.jp> writes:
>
>|C++のアプリケーションにRubyインタプリタをリンクして、アプリケーションの
>|マクロ言語としてRubyを利用する、というやり方です。SWIGの通常の利用法(拡
>|張ライブラリを作る)ではない方法です。これも大丈夫なんでしょうか?
>|
>|マーク&スイープ方式はスタック中のメモリも走査すると書いてあったのでちょ
>|っと怖いなぁ、と思っていました。確か最初に出たRuby本だと、グローバル変数
>|に登録したりする、と書いてあった気がしましたけど。

この不安感は,python 等の _かっちりした_ メモリ管理を行う処理系
の使い手にとって共通のものではないかと思います。

>起動時にruby_init()を呼び出すか、Init_stack()関数を呼んでお
>けば大丈夫です。ただし、native threadには対応してません。

ruby-1.6.8 のソースを見ました。ruby_init() は
  int state;
  ...
  Init_stack(&state);
をしており,呼び出された Init_stack(addr) は
  rb_gc_stack_start = addr;
をしていました。

つまり ruby_init() のスタックの位置をローカル変数の番地から得て,
それをグローバル変数に (おそらく) C のスタック領域の先頭番地とし
て登録しているわけですね。

すると,もしもアプリケーションの main() 直下ではなく,初期化フッ
クの奥深く何重にも関数を呼び出した果てに ruby_init() をする一方,
実際の ruby コードの呼び出しは main() から数えて割と浅いところか
ら行い,かつその ruby コードから C 拡張ライブラリを呼び出す場合,
問題が起こるのではないでしょうか?

(python が Tkinter で tcl/tk インタープリタ一式を組み込んでいる
 例を考えて下さい。初期化時とメソッド呼び出し時のスタックの深さ
 は一般には保証されない実装詳細です)

この場合,ローカル変数経由で ruby オブジェクトを参照しているかも
しれない C 拡張ライブラリが,登録されたスタック先頭番地よりも浅
い位置にそのローカル変数をもっているかもしれません。

するとこの参照は gc の走査範囲外ですから,参照しているはずの 
ruby オブジェクトが誤ってゴミ回収されるのではないでしょうか?

ここで,C 拡張のローカル変数の存命中に ruby の gc は発生しない,
と仮定することは一般にできません。先日書いた testlib.testrun の
例で PyObject_CallObject() が C 拡張から再帰的にインタープリタの
メインループを呼び出したようなことを行えば,スタックが C 拡張を
はさんでサンドイッチ構造になるからです。

   --(スタックトップ)--
  ruby インタープリタ用フレーム
  C 拡張ライブラリ用フレーム
  ruby インタープリタ用フレーム
  [C アプリケーション用フレーム]
  --(スタックボトム)--

もちろん,この問題は,ruby インタープリタが,自分自身で,登録先
頭番地よりもスタックが浅かったら登録しなおす,というようなことを
するならば回避できそうですが,少しソースを読んだ限りではそうして
なさそうでした。

もちろん,そもそも ruby_init() はスタックの浅いところから呼び出
すべし,と使用制限をかければよいわけですが,応用の自由度のために,
制限はないに越したことはないわけです。

あと,たまたま C スタックの値が,ruby の中の大規模なデータ構造
の根もとへの参照と同じになったら,アプリケーションが気まぐれで
メモリリークを起こすかもしれない,という不安もあると思います。

>あ、すいません。ここはPythonメーリングリストですね。
>これでおしまいにします。

アプリケーションへの組込み方法の比較という観点からは,それほどオ
フトピックではなかったかもしれません。

 たとえば,python でも ruby でも,プロセスのオーバヘッドなしに
 java から JNI 経由で利用できたら素敵 :-) かもしれません。
 python には阻害要因はなさそうですが…

-- SUZUKI Hisao




Python-ml-jp メーリングリストの案内