From: nobu.nakada@... Date: 2001-10-24T22:50:03+09:00 Subject: [ruby-dev:14994] Re: [PATCH] stack overflow while GC marking. なかだです。 At Tue, 23 Oct 2001 17:05:07 +0900, Nobuyoshi-Nakada wrote: > > during_gcが立ったままになるので、 > > スタックが溢れた後は二度とGCできなくなりますが、 > > これは意図的なものでしょうか? > > (もうスタックオーバーフローを起こさせないために) > >  現状でも、GCでマークしてる最中に例外が起きるとそうなりますね。 > というか、あれだけじゃやっぱりちょっと悲しいので、もう少し足掻 > いてみました。  単純にrb_gc_mark()の回数を数えるだけじゃあんまり意味がないの で、ネストレベルを数えるようにしてみました。マークの最中にエラー が起きたときに実行を継続できるものかどうか、いささか疑問ですが。 --- gc.c- Wed Oct 24 22:39:25 2001 +++ gc.c Wed Oct 24 22:45:23 2001 @@ -445,14 +445,19 @@ rb_gc_mark(ptr) register RVALUE *obj = RANY(ptr); - Top: - if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */ - if (obj->as.basic.flags == 0) return; /* free cell */ - if (obj->as.basic.flags & FL_MARK) return; /* already marked */ - - if ((during_gc++ & 0xff) == 0 && rb_stack_overflow_p()) { + if ((during_gc & 0xff) == 0 && rb_stack_overflow_p()) { if (!gc_deffered) gc_deffered = rb_ary_new2(256); rb_ary_push(gc_deffered, (VALUE)obj); return; } + during_gc++; + + Top: + if (rb_special_const_p((VALUE)obj) || /* special const not marked */ + (obj->as.basic.flags == 0) || /* free cell */ + (obj->as.basic.flags & FL_MARK)) /* already marked */ + { + --during_gc; + return; + } obj->as.basic.flags |= FL_MARK; @@ -465,4 +470,5 @@ rb_gc_mark(ptr) case T_NIL: case T_FIXNUM: + --during_gc; rb_bug("rb_gc_mark() called for broken object"); break; @@ -600,4 +606,5 @@ rb_gc_mark(ptr) } } + --during_gc; return; /* no need to mark class. */ } @@ -686,8 +693,10 @@ rb_gc_mark(ptr) default: + --during_gc; rb_bug("rb_gc_mark(): unknown data type 0x%x(0x%x) %s", obj->as.basic.flags & T_MASK, obj, is_pointer_to_heap(obj)?"corrupted object":"non object"); } + --during_gc; } @@ -966,6 +975,6 @@ rb_gc_mark_deferred() } -void -rb_gc() +static void +rb_gc_internal() { struct gc_list *list; @@ -1058,5 +1067,15 @@ rb_gc() gc_deffered = 0; } +} +VALUE +rb_gc() +{ + int state = 0; + rb_protect(rb_gc_internal, Qnil, &state); + if (state) { + during_gc = 0; + rb_jump_tag(state); + } gc_sweep(); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦