diff options
| author | Kazuho Oku <[email protected]> | 2016-12-10 15:11:07 +0900 |
|---|---|---|
| committer | Kazuho Oku <[email protected]> | 2016-12-10 15:11:07 +0900 |
| commit | 2ef634edb5ce70331a6a66d1c36726db904492bf (patch) | |
| tree | d201548d80f59ea61bea3a2984d9fd96ec4d17f4 | |
| parent | 7b968ca893b5c24e07ba67e4e5100d93a4024418 (diff) | |
| download | mruby-2ef634edb5ce70331a6a66d1c36726db904492bf.tar.gz mruby-2ef634edb5ce70331a6a66d1c36726db904492bf.zip | |
do not destroy a page with an active TT_ENV (e.g. an env referred from TT_FIBER)
| -rw-r--r-- | src/gc.c | 18 |
1 files changed, 12 insertions, 6 deletions
@@ -741,10 +741,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj) { struct REnv *e = (struct REnv*)obj; - if (!MRB_ENV_STACK_SHARED_P(e)) { - mrb_free(mrb, e->stack); - e->stack = NULL; + if (MRB_ENV_STACK_SHARED_P(e)) { + /* cannot be freed */ + return; } + mrb_free(mrb, e->stack); + e->stack = NULL; } break; @@ -998,9 +1000,13 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) if (is_dead(gc, &p->as.basic)) { if (p->as.basic.tt != MRB_TT_FREE) { obj_free(mrb, &p->as.basic); - p->as.free.next = page->freelist; - page->freelist = (struct RBasic*)p; - freed++; + if (p->as.basic.tt == MRB_TT_FREE) { + p->as.free.next = page->freelist; + page->freelist = (struct RBasic*)p; + freed++; + } else { + dead_slot = 0; + } } } else { |
