diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | gc.c | 21 |
2 files changed, 20 insertions, 5 deletions
@@ -1,3 +1,7 @@ +Thu Jun 5 22:50:50 2008 Tanaka Akira <akr@fsij.org> + + * gc.c (os_obj_of): heaps may be modified in yield. + Thu Jun 5 21:46:50 2008 Yusuke Endoh <mame@tsg.ne.jp> * st.c (st_reverse_foreach): comment out unused function. @@ -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++; } } |