From 6f42276d057e947c1c675da089512383adc85e52 Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 27 Sep 2004 12:25:21 +0000 Subject: [PATCH] * eval.c (rb_call0): invoke finalizers periodically. * gc.c (gc_sweep): defer running finalizers. * gc.c (rb_gc_finalize_deferred): run deferred finalizers. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6966 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++ eval.c | 1 + gc.c | 107 +++++++++++++++++++++++++++++++++--------------------- intern.h | 1 + 4 files changed, 75 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9cc10fa38..cc577a57d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Sep 27 21:25:12 2004 Nobuyoshi Nakada + + * eval.c (rb_call0): invoke finalizers periodically. + + * gc.c (gc_sweep): defer running finalizers. + + * gc.c (rb_gc_finalize_deferred): run deferred finalizers. + Mon Sep 27 15:01:59 2004 Minero Aoki * parse.y [ripper]: missing ';'. diff --git a/eval.c b/eval.c index d2b28a8f44..b074ecb0c7 100644 --- a/eval.c +++ b/eval.c @@ -5466,6 +5466,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) if ((++tick & 0xff) == 0) { CHECK_INTS; /* better than nothing */ stack_check(); + rb_gc_finalize_deferred(); } PUSH_ITER(itr); PUSH_FRAME(); diff --git a/gc.c b/gc.c index b270b8fcf2..fba3ee8fba 100644 --- a/gc.c +++ b/gc.c @@ -92,6 +92,7 @@ static unsigned long malloc_increase = 0; static unsigned long malloc_limit = GC_MALLOC_LIMIT; static void run_final(); static VALUE nomem_error; +static void gc_internal(); void rb_memerror() @@ -119,11 +120,11 @@ ruby_xmalloc(size) malloc_increase += size; if (malloc_increase > malloc_limit) { - rb_gc(); + gc_internal(); } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { - rb_gc(); + gc_internal(); RUBY_CRITICAL(mem = malloc(size)); if (!mem) { rb_memerror(); @@ -160,7 +161,7 @@ ruby_xrealloc(ptr, size) malloc_increase += size; RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { - rb_gc(); + gc_internal(); RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { rb_memerror(); @@ -380,7 +381,7 @@ rb_newobj() { VALUE obj; - if (!freelist) rb_gc(); + if (!freelist) gc_internal(); obj = (VALUE)freelist; freelist = freelist->as.free.next; @@ -992,6 +993,41 @@ gc_mark_children(ptr, lev) static void obj_free _((VALUE)); +static void +finalize_list(p) + RVALUE *p; +{ + while (p) { + RVALUE *tmp = p->as.free.next; + run_final((VALUE)p); + if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */ + p->as.free.flags = 0; + p->as.free.next = freelist; + freelist = p; + } + p = tmp; + } +} + +static void +free_unused_heaps() +{ + int i, j; + + for (i = j = 1; j < heaps_used; i++) { + if (heaps[i].limit == 0) { + free(heaps[i].slot); + heaps_used--; + } + else { + if (i != j) { + heaps[j] = heaps[i]; + } + j++; + } + } +} + static void gc_sweep() { @@ -1064,35 +1100,10 @@ gc_sweep() /* clear finalization list */ if (final_list) { - RVALUE *tmp; - - if (rb_prohibit_interrupt) { - deferred_final_list = final_list; - return; - } - - for (p = final_list; p; p = tmp) { - tmp = p->as.free.next; - run_final((VALUE)p); - if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */ - p->as.free.flags = 0; - p->as.free.next = freelist; - freelist = p; - } - } - } - for (i = j = 1; j < heaps_used; i++) { - if (heaps[i].limit == 0) { - free(heaps[i].slot); - heaps_used--; - } - else { - if (i != j) { - heaps[j] = heaps[i]; - } - j++; - } + deferred_final_list = final_list; + return; } + free_unused_heaps(); } void @@ -1276,8 +1287,8 @@ int rb_setjmp (rb_jmp_buf); #endif /* __human68k__ or DJGPP */ #endif /* __GNUC__ */ -void -rb_gc() +static void +gc_internal() { struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */ @@ -1389,6 +1400,13 @@ rb_gc() gc_sweep(); } +void +rb_gc() +{ + gc_internal(); + rb_gc_finalize_deferred(); +} + /* * call-seq: * GC.start => nil @@ -1773,6 +1791,18 @@ run_final(obj) rb_thread_critical = critical_save; } +void +rb_gc_finalize_deferred() +{ + RVALUE *p = deferred_final_list; + + deferred_final_list = 0; + if (p) { + finalize_list(p); + free_unused_heaps(); + } +} + void rb_gc_call_finalizer_at_exit() { @@ -1781,14 +1811,7 @@ rb_gc_call_finalizer_at_exit() /* run finalizers */ if (need_call_final) { - if (deferred_final_list) { - p = deferred_final_list; - while (p) { - RVALUE *tmp = p; - p = p->as.free.next; - run_final((VALUE)tmp); - } - } + finalize_list(deferred_final_list); for (i = 0; i < heaps_used; i++) { p = heaps[i].slot; pend = p + heaps[i].limit; while (p < pend) { diff --git a/intern.h b/intern.h index a798c82b13..fbf04a643b 100644 --- a/intern.h +++ b/intern.h @@ -247,6 +247,7 @@ void rb_gc_mark _((VALUE)); void rb_gc_force_recycle _((VALUE)); void rb_gc _((void)); void rb_gc_copy_finalizer _((VALUE,VALUE)); +void rb_gc_finalize_deferred _((void)); void rb_gc_call_finalizer_at_exit _((void)); VALUE rb_gc_enable _((void)); VALUE rb_gc_disable _((void));