* 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:
parent
2352c318ca
commit
6f42276d05
@ -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
1
eval.c
@ -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
107
gc.c
@ -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) {
|
||||||
|
1
intern.h
1
intern.h
@ -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));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user