From 18d4c1f044a4422fde5dde381e0812296bf2b619 Mon Sep 17 00:00:00 2001 From: akr Date: Thu, 5 Jun 2008 13:52:02 +0000 Subject: * 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 --- gc.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'gc.c') 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; - - for (i = 0; i < heaps_used; i++) { - RVALUE *p, *pend; + RVALUE *membase = 0; + RVALUE *p, *pend; + volatile VALUE v; + + 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++; } } -- cgit v1.2.3