diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-11-01 22:33:15 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-11-01 22:36:06 +0900 |
| commit | d68da042b3666c1e46e4d3cf1a14e708df89f440 (patch) | |
| tree | 851992b2b4367cdc72f7f669dbd7d3499a307c47 /src/gc.c | |
| parent | 830321fed554c437b0b6d670ee0389ca405190e2 (diff) | |
| download | mruby-d68da042b3666c1e46e4d3cf1a14e708df89f440.tar.gz mruby-d68da042b3666c1e46e4d3cf1a14e708df89f440.zip | |
The `env` object referenced from fibers may be freed; fix #4154
By dffa203 that reclaim `env` objects from heaps, there's more chance
for `env` objects referenced from fibers may be freed from heap pages.
Diffstat (limited to 'src/gc.c')
| -rw-r--r-- | src/gc.c | 24 |
1 files changed, 22 insertions, 2 deletions
@@ -274,9 +274,29 @@ mrb_free(mrb_state *mrb, void *p) (mrb->allocf)(mrb, p, 0, mrb->allocf_ud); } +static mrb_bool +heap_p(mrb_gc *gc, struct RBasic *object) +{ + mrb_heap_page* page; + + page = gc->heaps; + while (page) { + RVALUE *p; + + p = objects(page); + if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) { + return TRUE; + } + page = page->next; + } + return FALSE; +} + MRB_API mrb_bool mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { - return is_dead(&mrb->gc, object); + mrb_gc *gc = &mrb->gc; + if (!heap_p(gc, object)) return TRUE; + return is_dead(gc, object); } static void @@ -807,7 +827,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) while (ce <= ci) { struct REnv *e = ci->env; - if (e && !is_dead(&mrb->gc, e) && + if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { mrb_env_unshare(mrb, e); } |
