Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/src/gc.c

    r331 r439  
    1111#include <mruby/class.h>
    1212#include <mruby/data.h>
     13#include <mruby/istruct.h>
    1314#include <mruby/hash.h>
    1415#include <mruby/proc.h>
     
    110111    struct RRange range;
    111112    struct RData data;
     113    struct RIStruct istruct;
    112114    struct RProc proc;
    113115    struct REnv env;
     116    struct RFiber fiber;
    114117    struct RException exc;
    115118    struct RBreak brk;
    116119#ifdef MRB_WORD_BOXING
     120#ifndef MRB_WITHOUT_FLOAT
    117121    struct RFloat floatv;
     122#endif
    118123    struct RCptr cptr;
    119124#endif
     
    176181#define GC_STEP_SIZE 1024
    177182
    178 /* white: 011, black: 100, gray: 000 */
     183/* white: 001 or 010, black: 100, gray: 000 */
    179184#define GC_GRAY 0
    180185#define GC_WHITE_A 1
     
    273278}
    274279
     280MRB_API void*
     281mrb_alloca(mrb_state *mrb, size_t size)
     282{
     283  struct RString *s;
     284  s = (struct RString*)mrb_obj_alloc(mrb, MRB_TT_STRING, mrb->string_class);
     285  return s->as.heap.ptr = (char*)mrb_malloc(mrb, size);
     286}
     287
     288static mrb_bool
     289heap_p(mrb_gc *gc, struct RBasic *object)
     290{
     291  mrb_heap_page* page;
     292
     293  page = gc->heaps;
     294  while (page) {
     295    RVALUE *p;
     296
     297    p = objects(page);
     298    if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) {
     299      return TRUE;
     300    }
     301    page = page->next;
     302  }
     303  return FALSE;
     304}
     305
    275306MRB_API mrb_bool
    276307mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) {
    277   return is_dead(&mrb->gc, object);
     308  mrb_gc *gc = &mrb->gc;
     309  if (!heap_p(gc, object)) return TRUE;
     310  return is_dead(gc, object);
    278311}
    279312
     
    343376#define DEFAULT_GC_INTERVAL_RATIO 200
    344377#define DEFAULT_GC_STEP_RATIO 200
    345 #define DEFAULT_MAJOR_GC_INC_RATIO 200
     378#define MAJOR_GC_INC_RATIO 120
     379#define MAJOR_GC_TOOMANY 10000
    346380#define is_generational(gc) ((gc)->generational)
    347381#define is_major_gc(gc) (is_generational(gc) && (gc)->full)
     
    374408static void obj_free(mrb_state *mrb, struct RBasic *obj, int end);
    375409
    376 void
     410static void
    377411free_heap(mrb_state *mrb, mrb_gc *gc)
    378412{
     
    413447  if (gc->arena_idx >= gc->arena_capa) {
    414448    /* extend arena */
    415     gc->arena_capa = (int)(gc->arena_capa * 1.5);
     449    gc->arena_capa = (int)(gc->arena_capa * 3 / 2);
    416450    gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa);
    417451  }
     
    441475mrb_gc_register(mrb_state *mrb, mrb_value obj)
    442476{
    443   mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
    444   mrb_value table = mrb_gv_get(mrb, root);
    445 
    446   if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) {
     477  mrb_sym root;
     478  mrb_value table;
     479
     480  if (mrb_immediate_p(obj)) return;
     481  root = mrb_intern_lit(mrb, GC_ROOT_NAME);
     482  table = mrb_gv_get(mrb, root);
     483  if (mrb_nil_p(table) || !mrb_array_p(table)) {
    447484    table = mrb_ary_new(mrb);
    448485    mrb_gv_set(mrb, root, table);
     
    455492mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
    456493{
    457   mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
    458   mrb_value table = mrb_gv_get(mrb, root);
     494  mrb_sym root;
     495  mrb_value table;
    459496  struct RArray *a;
    460497  mrb_int i;
    461498
     499  if (mrb_immediate_p(obj)) return;
     500  root = mrb_intern_lit(mrb, GC_ROOT_NAME);
     501  table = mrb_gv_get(mrb, root);
    462502  if (mrb_nil_p(table)) return;
    463   if (mrb_type(table) != MRB_TT_ARRAY) {
     503  if (!mrb_array_p(table)) {
    464504    mrb_gv_set(mrb, root, mrb_nil_value());
    465505    return;
     
    467507  a = mrb_ary_ptr(table);
    468508  mrb_ary_modify(mrb, a);
    469   for (i = 0; i < a->len; i++) {
    470     if (mrb_obj_eq(mrb, a->ptr[i], obj)) {
    471       a->len--;
    472       memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i]));
     509  for (i = 0; i < ARY_LEN(a); i++) {
     510    if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) {
     511      mrb_int len = ARY_LEN(a)-1;
     512      mrb_value *ptr = ARY_PTR(a);
     513
     514      ARY_SET_LEN(a, len);
     515      memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value));
    473516      break;
    474517    }
     
    480523{
    481524  struct RBasic *p;
    482   static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
     525  static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } };
    483526  mrb_gc *gc = &mrb->gc;
    484527
     
    501544        ttype != MRB_TT_ENV &&
    502545        ttype != tt) {
    503       mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls));
     546      mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %C", cls);
    504547    }
    505548  }
     
    543586}
    544587
     588static int
     589ci_nregs(mrb_callinfo *ci)
     590{
     591  struct RProc *p = ci->proc;
     592  int n = 0;
     593
     594  if (!p) {
     595    if (ci->argc < 0) return 3;
     596    return ci->argc+2;
     597  }
     598  if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
     599    n = p->body.irep->nregs;
     600  }
     601  if (ci->argc < 0) {
     602    if (n < 3) n = 3; /* self + args + blk */
     603  }
     604  if (ci->argc > n) {
     605    n = ci->argc + 2; /* self + blk */
     606  }
     607  return n;
     608}
     609
    545610static void
    546611mark_context_stack(mrb_state *mrb, struct mrb_context *c)
     
    549614  size_t e;
    550615  mrb_value nil;
    551   int nregs;
    552616
    553617  if (c->stack == NULL) return;
    554618  e = c->stack - c->stbase;
    555619  if (c->ci) {
    556     nregs = c->ci->argc + 2;
    557     if (c->ci->nregs > nregs)
    558       nregs = c->ci->nregs;
    559     e += nregs;
     620    e += ci_nregs(c->ci);
    560621  }
    561622  if (c->stbase + e > c->stend) e = c->stend - c->stbase;
     
    579640  int i;
    580641  mrb_callinfo *ci;
     642
     643 start:
     644  if (c->status == MRB_FIBER_TERMINATED) return;
    581645
    582646  /* mark VM stack */
     
    592656  }
    593657  /* mark ensure stack */
    594   for (i=0; i<c->esize; i++) {
    595     if (c->ensure[i] == NULL) break;
     658  for (i=0; i<c->eidx; i++) {
    596659    mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
    597660  }
     
    599662  mrb_gc_mark(mrb, (struct RBasic*)c->fib);
    600663  if (c->prev) {
    601     mark_context(mrb, c->prev);
     664    c = c->prev;
     665    goto start;
    602666  }
    603667}
     
    614678    {
    615679      struct RClass *c = (struct RClass*)obj;
    616       if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN))
     680      if (MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_ORIGIN))
    617681        mrb_gc_mark_mt(mrb, c);
    618682      mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super);
     
    641705      struct RProc *p = (struct RProc*)obj;
    642706
    643       mrb_gc_mark(mrb, (struct RBasic*)p->env);
    644       mrb_gc_mark(mrb, (struct RBasic*)p->target_class);
     707      mrb_gc_mark(mrb, (struct RBasic*)p->upper);
     708      mrb_gc_mark(mrb, (struct RBasic*)p->e.env);
    645709    }
    646710    break;
     
    651715      mrb_int i, len;
    652716
    653       if (MRB_ENV_STACK_SHARED_P(e)) {
    654         if (e->cxt.c->fib) {
    655           mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib);
    656         }
    657         break;
     717      if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) {
     718        mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib);
    658719      }
    659720      len = MRB_ENV_STACK_LEN(e);
     
    677738      size_t i, e;
    678739
    679       for (i=0,e=a->len; i<e; i++) {
    680         mrb_gc_mark_value(mrb, a->ptr[i]);
     740      for (i=0,e=ARY_LEN(a); i<e; i++) {
     741        mrb_gc_mark_value(mrb, ARY_PTR(a)[i]);
    681742      }
    682743    }
     
    689750
    690751  case MRB_TT_STRING:
     752    if (RSTR_FSHARED_P(obj)) {
     753      struct RString *s = (struct RString*)obj;
     754      mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared);
     755    }
    691756    break;
    692757
    693758  case MRB_TT_RANGE:
    694     {
    695       struct RRange *r = (struct RRange*)obj;
    696 
    697       if (r->edges) {
    698         mrb_gc_mark_value(mrb, r->edges->beg);
    699         mrb_gc_mark_value(mrb, r->edges->end);
    700       }
    701     }
     759    mrb_gc_mark_range(mrb, (struct RRange*)obj);
    702760    break;
    703761
     
    728786    return;
    729787
     788#ifndef MRB_WITHOUT_FLOAT
    730789  case MRB_TT_FLOAT:
    731790#ifdef MRB_WORD_BOXING
     
    733792#else
    734793    return;
     794#endif
    735795#endif
    736796
     
    748808    mrb_gc_free_mt(mrb, (struct RClass*)obj);
    749809    mrb_gc_free_iv(mrb, (struct RObject*)obj);
     810    mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
    750811    break;
    751812  case MRB_TT_ICLASS:
    752     if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN))
     813    if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN))
    753814      mrb_gc_free_mt(mrb, (struct RClass*)obj);
     815    mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
    754816    break;
    755817  case MRB_TT_ENV:
     
    759821      if (MRB_ENV_STACK_SHARED_P(e)) {
    760822        /* cannot be freed */
    761         return;
     823        e->stack = NULL;
     824        break;
    762825      }
    763826      mrb_free(mrb, e->stack);
     
    770833      struct mrb_context *c = ((struct RFiber*)obj)->cxt;
    771834
    772       if (!end && c && c != mrb->root_c) {
    773         mrb_callinfo *ci = c->ci;
    774         mrb_callinfo *ce = c->cibase;
    775 
    776         while (ce <= ci) {
    777           struct REnv *e = ci->env;
    778           if (e && !is_dead(&mrb->gc, e) &&
    779               e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
    780             mrb_env_unshare(mrb, e);
     835      if (c && c != mrb->root_c) {
     836        if (!end && c->status != MRB_FIBER_TERMINATED) {
     837          mrb_callinfo *ci = c->ci;
     838          mrb_callinfo *ce = c->cibase;
     839
     840          while (ce <= ci) {
     841            struct REnv *e = ci->env;
     842            if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) &&
     843                e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
     844              mrb_env_unshare(mrb, e);
     845            }
     846            ci--;
    781847          }
    782           ci--;
    783848        }
    784849        mrb_free_context(mrb, c);
     
    789854  case MRB_TT_ARRAY:
    790855    if (ARY_SHARED_P(obj))
    791       mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared);
    792     else
    793       mrb_free(mrb, ((struct RArray*)obj)->ptr);
     856      mrb_ary_decref(mrb, ((struct RArray*)obj)->as.heap.aux.shared);
     857    else if (!ARY_EMBED_P(obj))
     858      mrb_free(mrb, ((struct RArray*)obj)->as.heap.ptr);
    794859    break;
    795860
     
    808873
    809874      if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
    810         mrb_irep_decref(mrb, p->body.irep);
     875        mrb_irep *irep = p->body.irep;
     876        if (end) {
     877          mrb_irep_cutref(mrb, irep);
     878        }
     879        mrb_irep_decref(mrb, irep);
    811880      }
    812881    }
     
    814883
    815884  case MRB_TT_RANGE:
    816     mrb_free(mrb, ((struct RRange*)obj)->edges);
     885    mrb_gc_free_range(mrb, ((struct RRange*)obj));
    817886    break;
    818887
     
    858927  mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class);
    859928  mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class);
    860 
     929  mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class);
     930
     931#ifndef MRB_WITHOUT_FLOAT
    861932  mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class);
     933#endif
    862934  mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class);
    863935  mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class);
     
    918990
    919991  case MRB_TT_ENV:
    920     children += (int)obj->flags;
     992    children += MRB_ENV_STACK_LEN(obj);
    921993    break;
    922994
     
    927999      mrb_callinfo *ci;
    9281000
    929       if (!c) break;
     1001      if (!c || c->status == MRB_FIBER_TERMINATED) break;
     1002
    9301003      /* mark stack */
    9311004      i = c->stack - c->stbase;
    932       if (c->ci) i += c->ci->nregs;
     1005
     1006      if (c->ci) {
     1007        i += ci_nregs(c->ci);
     1008      }
    9331009      if (c->stbase + i > c->stend) i = c->stend - c->stbase;
    9341010      children += i;
     
    9491025    {
    9501026      struct RArray *a = (struct RArray*)obj;
    951       children += a->len;
     1027      children += ARY_LEN(a);
    9521028    }
    9531029    break;
     
    11901266
    11911267    if (is_major_gc(gc)) {
    1192       gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
     1268      size_t threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO;
     1269
    11931270      gc->full = FALSE;
     1271      if (threshold < MAJOR_GC_TOOMANY) {
     1272        gc->majorgc_old_threshold = threshold;
     1273      }
     1274      else {
     1275        /* too many objects allocated during incremental GC, */
     1276        /* instead of increasing threshold, invoke full GC. */
     1277        mrb_full_gc(mrb);
     1278      }
    11941279    }
    11951280    else if (is_minor_gc(gc)) {
     
    12291314
    12301315  if (is_generational(gc)) {
    1231     gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
     1316    gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO;
    12321317    gc->full = FALSE;
    12331318  }
     
    12401325{
    12411326  mrb_full_gc(mrb);
    1242 }
    1243 
    1244 MRB_API int
    1245 mrb_gc_arena_save(mrb_state *mrb)
    1246 {
    1247   return mrb->gc.arena_idx;
    1248 }
    1249 
    1250 MRB_API void
    1251 mrb_gc_arena_restore(mrb_state *mrb, int idx)
    1252 {
    1253   mrb_gc *gc = &mrb->gc;
    1254 
    1255 #ifndef MRB_GC_FIXED_ARENA
    1256   int capa = gc->arena_capa;
    1257 
    1258   if (idx < capa / 2) {
    1259     capa = (int)(capa * 0.66);
    1260     if (capa < MRB_GC_ARENA_SIZE) {
    1261       capa = MRB_GC_ARENA_SIZE;
    1262     }
    1263     if (capa != gc->arena_capa) {
    1264       gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);
    1265       gc->arena_capa = capa;
    1266     }
    1267   }
    1268 #endif
    1269   gc->arena_idx = idx;
    12701327}
    12711328
     
    14071464
    14081465  mrb_get_args(mrb, "i", &ratio);
    1409   mrb->gc.interval_ratio = ratio;
     1466  mrb->gc.interval_ratio = (int)ratio;
    14101467  return mrb_nil_value();
    14111468}
     
    14401497
    14411498  mrb_get_args(mrb, "i", &ratio);
    1442   mrb->gc.step_ratio = ratio;
     1499  mrb->gc.step_ratio = (int)ratio;
    14431500  return mrb_nil_value();
    14441501}
     
    14581515  else if (!is_generational(gc) && enable) {
    14591516    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
    1460     gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
     1517    gc->majorgc_old_threshold = gc->live_after_mark/100 * MAJOR_GC_INC_RATIO;
    14611518    gc->full = FALSE;
    14621519  }
     
    15231580  mrb_bool iterating = mrb->gc.iterating;
    15241581
     1582  mrb_full_gc(mrb);
    15251583  mrb->gc.iterating = TRUE;
    15261584  if (iterating) {
     
    15351593      gc_each_objects(mrb, &mrb->gc, callback, data);
    15361594      mrb->jmp = prev_jmp;
    1537       mrb->gc.iterating = iterating; 
     1595      mrb->gc.iterating = iterating;
    15381596   } MRB_CATCH(&c_jmp) {
    15391597      mrb->gc.iterating = iterating;
     
    15541612{
    15551613  struct RClass *gc;
     1614
     1615  mrb_static_assert(sizeof(RVALUE) <= sizeof(void*) * 6,
     1616                    "RVALUE size must be within 6 words");
    15561617
    15571618  gc = mrb_define_module(mrb, "GC");
Note: See TracChangeset for help on using the changeset viewer.