From: KOSAKI Motohiro Date: 2011-07-02T17:37:42+09:00 Subject: [ruby-dev:44015] Re: [ruby-core:37707] [Ruby 1.9 - Bug #3781] FIBER_USE_NATIVE が有効だと落ちるスクリプトがある > 続いて(2)です。 > > gc.cのstack_check()の役割としては > 「lev(gc_mark()に渡される引数)がGC_LEVEL_MAX(250)の範囲でgc_mark() > を呼び出せるほどの余りがマシンスタックにあるかチェックする」 > のように読めます。 > > static int > stack_check(void) > { > ... > SET_STACK_END; > ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK; > > ただ、GC_WATER_MARKが512しかないので、そのチェックがうまくいってません。 > GC_WATER_MARK = (gc_mark()フレームサイズ + gc_mark_children()フレームサイズ) * GC_LEVEL_MAX > となるべきだと思います。 > > 私の環境(Linux 2.6.39-0-generic x86_64, gcc 4.5.2)ではgc_mark()と > gc_mark_children()のフレームが28ワードだったので、とりあえず以下のよう > に修正したいのですが、どうでしょうか? > > この場合、GC_WATER_MARKは7000(64bit環境だと56KB)になります。 > 本当はgc_mark()の際に毎回stack_check()するのがいいと思うのですが、 > そうするとGCの性能が落ちてしまうので、大体で決めてしまうしかないのか > なと思ってます。 GC用に56KB必要だとすると、Fiberでスタックが64KBしかつくらないのは ダメじゃないかという気がするんですが、大丈夫でしょうか。CPUが64bitの ときはアドレス空間サイズに余裕があるので64KBなんてケチケチしたことは やめるべきだと思います。 32bitのときに、実質スタック36KB(64KB - 28KB)で足りるかどうかは、ささださんの 見解がほしいですが、わたしは足りないんじゃないかと疑っています。ささださん、 どうでしょう? あと、nariさん、32bit のときにGC_LEVEL_MAXへらすという処理をすると、ぎゃっ となりそうな処理ってどのようなものでしょうか。獏とした意見でかまわないので 教えてもらえませんか。 すいません、疎いのでこのあたりのトレードオフの勘所がどうも把握できていません