From 18d4c1f044a4422fde5dde381e0812296bf2b619 Mon Sep 17 00:00:00 2001 From: akr Date: Thu, 5 Jun 2008 13:52:02 +0000 Subject: [PATCH] * gc.c (os_obj_of): heaps may be modified in yield. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++++ gc.c | 19 +++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a875d3f81e..a80f1d4917 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Jun 5 22:50:50 2008 Tanaka Akira + + * gc.c (os_obj_of): heaps may be modified in yield. + Thu Jun 5 21:46:50 2008 Yusuke Endoh * st.c (st_reverse_foreach): comment out unused function. diff --git a/gc.c b/gc.c index d095c5e8c4..245b8ee2d9 100644 --- a/gc.c +++ b/gc.c @@ -1856,9 +1856,19 @@ os_obj_of(rb_objspace_t *objspace, VALUE of) { size_t i; size_t n = 0; + RVALUE *membase = 0; + RVALUE *p, *pend; + volatile VALUE v; - for (i = 0; i < heaps_used; i++) { - RVALUE *p, *pend; + i = 0; + while (i < heaps_used) { + while (0 < i && (uintptr_t)membase < (uintptr_t)heaps[i-1].membase) + i--; + while (i < heaps_used && (uintptr_t)heaps[i].membase <= (uintptr_t)membase ) + i++; + if (heaps_used <= i) + break; + membase = heaps[i].membase; p = heaps[i].slot; pend = p + heaps[i].limit; for (;p < pend; p++) { @@ -1872,8 +1882,9 @@ os_obj_of(rb_objspace_t *objspace, VALUE of) if (FL_TEST(p, FL_SINGLETON)) continue; default: if (!p->as.basic.klass) continue; - if (!of || rb_obj_is_kind_of((VALUE)p, of)) { - rb_yield((VALUE)p); + v = (VALUE)p; + if (!of || rb_obj_is_kind_of(v, of)) { + rb_yield(v); n++; } }