[#14922] alias $gvar — Koji Arai <JCA02266@...>

新井です。

19 messages 2001/10/14

[#15006] Re: eval.c (rb_stack_check): prohibit recursive raising error — WATANABE Hirofumi <eban@...>

わたなべです。

13 messages 2001/10/26
[#15008] Re: eval.c (rb_stack_check): prohibit recursive raising error — Shugo Maeda <shugo@...> 2001/10/26

前田です。

[ruby-dev:14986] Re: [PATCH] stack overflow while GC marking.

From: nobu.nakada@...
Date: 2001-10-23 08:05:07 UTC
List: ruby-dev #14986
なかだです。

At Tue, 23 Oct 2001 14:43:15 +0900,
K.Kosako <kosako@sofnec.co.jp> wrote:
> during_gcが立ったままになるので、
> スタックが溢れた後は二度とGCできなくなりますが、
> これは意図的なものでしょうか?
> (もうスタックオーバーフローを起こさせないために)

 現状でも、GCでマークしてる最中に例外が起きるとそうなりますね。
というか、あれだけじゃやっぱりちょっと悲しいので、もう少し足掻
いてみました。

> # 昨日のaliasの修正、私の名前になっていました。
> # どうもありがとうございます。

 いや、やっぱChangeLogを書いた人にしとこうかなとか、ふと思った
もので。

* eval.c (rb_stack_overflow_p): return whether stack is near
  overflow.  [new]

* gc.c (rb_gc_mark): defer marking when stack is near overflow.
  [ruby-talk:22532]

* gc.c (rb_gc_mark_deferred): mark deferred objects.  [new]

* gc.c (rb_gc): mark deferred objects before sweep.

* intern.h (rb_stack_overflow_p): added.


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.216
diff -u -2 -p -u -r1.216 eval.c
--- eval.c	2001/10/22 16:28:51	1.216
+++ eval.c	2001/10/23 04:56:55
@@ -4288,4 +4288,11 @@ stack_length(p)
 }
 
+int
+rb_stack_overflow_p()
+{
+    if (stack_length(0) > STACK_LEVEL_MAX) return Qtrue;
+    return Qfalse;
+}
+
 void
 rb_stack_check()
Index: gc.c
===================================================================
RCS file: /cvs/ruby/src/ruby/gc.c,v
retrieving revision 1.72
diff -u -2 -p -u -r1.72 gc.c
--- gc.c	2001/07/20 15:19:28	1.72
+++ gc.c	2001/10/23 05:16:19
@@ -159,4 +159,5 @@ static int during_gc;
 static int need_call_final = 0;
 static st_table *finalizer_table = 0;
+static VALUE gc_deffered;
 
 VALUE
@@ -449,4 +450,10 @@ rb_gc_mark(ptr)
     if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
 
+    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;
+    }
+
     obj->as.basic.flags |= FL_MARK;
 
@@ -949,4 +956,14 @@ int rb_setjmp (rb_jmp_buf);
 #endif /* __GNUC__ */
 
+static void
+rb_gc_mark_deferred()
+{
+    VALUE obj;
+    if (!gc_deffered || !RARRAY(gc_deffered)->len) return;
+    while (!NIL_P(obj = rb_ary_shift(gc_deffered))) {
+	rb_gc_mark(obj);
+    }
+}
+
 void
 rb_gc()
@@ -991,10 +1008,15 @@ rb_gc()
 	    }
 	}
+	rb_gc_mark_deferred();
     }
     rb_gc_mark((VALUE)ruby_class);
+    rb_gc_mark_deferred();
     rb_gc_mark((VALUE)ruby_scope);
+    rb_gc_mark_deferred();
     rb_gc_mark((VALUE)ruby_dyna_vars);
+    rb_gc_mark_deferred();
     if (finalizer_table) {
 	rb_mark_tbl(finalizer_table);
+	rb_gc_mark_deferred();
     }
 
@@ -1004,22 +1026,36 @@ rb_gc()
     mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
     rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
+    rb_gc_mark_deferred();
 #if defined(__human68k__)
     rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2),
 			 (VALUE*)((char*)STACK_END + 2));
+    rb_gc_mark_deferred();
 #endif
     rb_gc_mark_threads();
+    rb_gc_mark_deferred();
 
     /* mark protected global variables */
     for (list = Global_List; list; list = list->next) {
 	rb_gc_mark(*list->varptr);
+	rb_gc_mark_deferred();
     }
     rb_mark_end_proc();
+    rb_gc_mark_deferred();
     rb_gc_mark_global_tbl();
+    rb_gc_mark_deferred();
 
     rb_mark_tbl(rb_class_tbl);
+    rb_gc_mark_deferred();
     rb_gc_mark_trap_list();
+    rb_gc_mark_deferred();
 
     /* mark generic instance variables for special constants */
     rb_mark_generic_ivar_tbl();
+    rb_gc_mark_deferred();
+
+    if (gc_deffered) {
+	rb_gc_force_recycle(gc_deffered);
+	gc_deffered = 0;
+    }
 
     gc_sweep();
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.67
diff -u -2 -p -u -r1.67 intern.h
--- intern.h	2001/10/16 15:14:37	1.67
+++ intern.h	2001/10/23 04:57:11
@@ -113,4 +113,5 @@ VALUE rb_exc_new _((VALUE, const char*, 
 VALUE rb_exc_new2 _((VALUE, const char*));
 VALUE rb_exc_new3 _((VALUE, VALUE));
+int rb_stack_overflow_p _((void));
 void rb_stack_check _((void));
 NORETURN(void rb_loaderror __((const char*, ...)));


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread