diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-05-20 17:54:07 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2013-05-20 17:54:07 +0900 |
| commit | 5c0b9b703c9d1a08d7219b057b809bda4bc89f8a (patch) | |
| tree | ab610a2988ef928c02bfc50e31aedc5a707f008e /src/gc.c | |
| parent | 35ee85164dd19143d4b47a34f13ad2bb71fed369 (diff) | |
| download | mruby-5c0b9b703c9d1a08d7219b057b809bda4bc89f8a.tar.gz mruby-5c0b9b703c9d1a08d7219b057b809bda4bc89f8a.zip | |
primary mruby fiber implementation
Diffstat (limited to 'src/gc.c')
| -rw-r--r-- | src/gc.c | 95 |
1 files changed, 73 insertions, 22 deletions
@@ -387,6 +387,35 @@ add_gray_list(mrb_state *mrb, struct RBasic *obj) } static void +mark_context(mrb_state *mrb, struct mrb_context *c) +{ + size_t i; + size_t e; + mrb_callinfo *ci; + + /* mark stack */ + e = c->stack - c->stbase; + if (c->ci) e += c->ci->nregs; + if (c->stbase + e > c->stend) e = c->stend - c->stbase; + for (i=0; i<e; i++) { + mrb_gc_mark_value(mrb, c->stbase[i]); + } + /* mark ensure stack */ + e = (c->ci) ? c->ci->eidx : 0; + for (i=0; i<e; i++) { + mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); + } + /* mark closure */ + for (ci = c->cibase; ci <= c->ci; ci++) { + if (!ci) continue; + mrb_gc_mark(mrb, (struct RBasic*)ci->env); + mrb_gc_mark(mrb, (struct RBasic*)ci->proc); + mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); + } + if (c->prev) mark_context(mrb, c->prev); +} + +static void gc_mark_children(mrb_state *mrb, struct RBasic *obj) { gc_assert(is_gray(obj)); @@ -438,6 +467,15 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) } break; + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber*)obj)->cxt; + + mark_context(mrb, c); + ((struct RFiber*)obj)->cxt = NULL; + } + break; + case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; @@ -517,6 +555,14 @@ obj_free(mrb_state *mrb, struct RBasic *obj) } break; + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber*)obj)->cxt; + + mrb_free_context(mrb, c); + } + break; + case MRB_TT_ARRAY: if (obj->flags & MRB_ARY_SHARED) mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared); @@ -557,9 +603,7 @@ static void root_scan_phase(mrb_state *mrb) { int j; - size_t i; - size_t e; - mrb_callinfo *ci; + size_t i, e; if (!is_minor_gc(mrb)) { mrb->gray_list = 0; @@ -577,25 +621,8 @@ root_scan_phase(mrb_state *mrb) mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); /* mark exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); - /* mark stack */ - e = mrb->stack - mrb->stbase; - if (mrb->ci) e += mrb->ci->nregs; - if (mrb->stbase + e > mrb->stend) e = mrb->stend - mrb->stbase; - for (i=0; i<e; i++) { - mrb_gc_mark_value(mrb, mrb->stbase[i]); - } - /* mark ensure stack */ - e = (mrb->ci) ? mrb->ci->eidx : 0; - for (i=0; i<e; i++) { - mrb_gc_mark(mrb, (struct RBasic*)mrb->ensure[i]); - } - /* mark closure */ - for (ci = mrb->cibase; ci <= mrb->ci; ci++) { - if (!ci) continue; - mrb_gc_mark(mrb, (struct RBasic*)ci->env); - mrb_gc_mark(mrb, (struct RBasic*)ci->proc); - mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); - } + + mark_context(mrb, mrb->c); /* mark irep pool */ if (mrb->irep) { size_t len = mrb->irep_len; @@ -643,6 +670,30 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj) children += (int)obj->flags; break; + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber*)obj)->cxt; + size_t i; + mrb_callinfo *ci; + + /* mark stack */ + i = c->stack - c->stbase; + if (c->ci) i += c->ci->nregs; + if (c->stbase + i > c->stend) i = c->stend - c->stbase; + children += i; + + /* mark ensure stack */ + children += (c->ci) ? c->ci->eidx : 0; + + /* mark closure */ + if (c->cibase) { + for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++) + ; + } + children += i; + } + break; + case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; |
