* 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
This commit is contained in:
nobu 2004-09-27 12:25:21 +00:00
parent 2352c318ca
commit 6f42276d05
4 changed files with 75 additions and 42 deletions

View File

@ -1,3 +1,11 @@
Mon Sep 27 21:25:12 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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 <aamine@loveruby.net> Mon Sep 27 15:01:59 2004 Minero Aoki <aamine@loveruby.net>
* parse.y [ripper]: missing ';'. * parse.y [ripper]: missing ';'.

1
eval.c
View File

@ -5466,6 +5466,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
if ((++tick & 0xff) == 0) { if ((++tick & 0xff) == 0) {
CHECK_INTS; /* better than nothing */ CHECK_INTS; /* better than nothing */
stack_check(); stack_check();
rb_gc_finalize_deferred();
} }
PUSH_ITER(itr); PUSH_ITER(itr);
PUSH_FRAME(); PUSH_FRAME();

107
gc.c
View File

@ -92,6 +92,7 @@ static unsigned long malloc_increase = 0;
static unsigned long malloc_limit = GC_MALLOC_LIMIT; static unsigned long malloc_limit = GC_MALLOC_LIMIT;
static void run_final(); static void run_final();
static VALUE nomem_error; static VALUE nomem_error;
static void gc_internal();
void void
rb_memerror() rb_memerror()
@ -119,11 +120,11 @@ ruby_xmalloc(size)
malloc_increase += size; malloc_increase += size;
if (malloc_increase > malloc_limit) { if (malloc_increase > malloc_limit) {
rb_gc(); gc_internal();
} }
RUBY_CRITICAL(mem = malloc(size)); RUBY_CRITICAL(mem = malloc(size));
if (!mem) { if (!mem) {
rb_gc(); gc_internal();
RUBY_CRITICAL(mem = malloc(size)); RUBY_CRITICAL(mem = malloc(size));
if (!mem) { if (!mem) {
rb_memerror(); rb_memerror();
@ -160,7 +161,7 @@ ruby_xrealloc(ptr, size)
malloc_increase += size; malloc_increase += size;
RUBY_CRITICAL(mem = realloc(ptr, size)); RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) { if (!mem) {
rb_gc(); gc_internal();
RUBY_CRITICAL(mem = realloc(ptr, size)); RUBY_CRITICAL(mem = realloc(ptr, size));
if (!mem) { if (!mem) {
rb_memerror(); rb_memerror();
@ -380,7 +381,7 @@ rb_newobj()
{ {
VALUE obj; VALUE obj;
if (!freelist) rb_gc(); if (!freelist) gc_internal();
obj = (VALUE)freelist; obj = (VALUE)freelist;
freelist = freelist->as.free.next; freelist = freelist->as.free.next;
@ -992,6 +993,41 @@ gc_mark_children(ptr, lev)
static void obj_free _((VALUE)); 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 static void
gc_sweep() gc_sweep()
{ {
@ -1064,35 +1100,10 @@ gc_sweep()
/* clear finalization list */ /* clear finalization list */
if (final_list) { if (final_list) {
RVALUE *tmp; deferred_final_list = final_list;
return;
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++;
}
} }
free_unused_heaps();
} }
void void
@ -1276,8 +1287,8 @@ int rb_setjmp (rb_jmp_buf);
#endif /* __human68k__ or DJGPP */ #endif /* __human68k__ or DJGPP */
#endif /* __GNUC__ */ #endif /* __GNUC__ */
void static void
rb_gc() gc_internal()
{ {
struct gc_list *list; struct gc_list *list;
struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */ struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
@ -1389,6 +1400,13 @@ rb_gc()
gc_sweep(); gc_sweep();
} }
void
rb_gc()
{
gc_internal();
rb_gc_finalize_deferred();
}
/* /*
* call-seq: * call-seq:
* GC.start => nil * GC.start => nil
@ -1773,6 +1791,18 @@ run_final(obj)
rb_thread_critical = critical_save; 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 void
rb_gc_call_finalizer_at_exit() rb_gc_call_finalizer_at_exit()
{ {
@ -1781,14 +1811,7 @@ rb_gc_call_finalizer_at_exit()
/* run finalizers */ /* run finalizers */
if (need_call_final) { if (need_call_final) {
if (deferred_final_list) { finalize_list(deferred_final_list);
p = deferred_final_list;
while (p) {
RVALUE *tmp = p;
p = p->as.free.next;
run_final((VALUE)tmp);
}
}
for (i = 0; i < heaps_used; i++) { for (i = 0; i < heaps_used; i++) {
p = heaps[i].slot; pend = p + heaps[i].limit; p = heaps[i].slot; pend = p + heaps[i].limit;
while (p < pend) { while (p < pend) {

View File

@ -247,6 +247,7 @@ void rb_gc_mark _((VALUE));
void rb_gc_force_recycle _((VALUE)); void rb_gc_force_recycle _((VALUE));
void rb_gc _((void)); void rb_gc _((void));
void rb_gc_copy_finalizer _((VALUE,VALUE)); void rb_gc_copy_finalizer _((VALUE,VALUE));
void rb_gc_finalize_deferred _((void));
void rb_gc_call_finalizer_at_exit _((void)); void rb_gc_call_finalizer_at_exit _((void));
VALUE rb_gc_enable _((void)); VALUE rb_gc_enable _((void));
VALUE rb_gc_disable _((void)); VALUE rb_gc_disable _((void));