Example #1
0
static l_mem singlestep (lua_State *L) {
  global_State *g = G(L);
  switch (g->gcstate) {
    case GCSpause: {
      if (!isgenerational(g))
        markroot(g);  /* start a new collection */
      /* in any case, root must be marked */
      lua_assert(!iswhite(obj2gco(g->mainthread))
              && !iswhite(gcvalue(&g->l_registry)));
      g->gcstate = GCSpropagate;
      return GCROOTCOST;
    }
    case GCSpropagate: {
      if (g->gray)
        return propagatemark(g);
      else {  /* no more `gray' objects */
        g->gcstate = GCSatomic;  /* finish mark phase */
        atomic(L);
        return GCATOMICCOST;
      }
    }
    case GCSsweepstring: {
      if (g->sweepstrgc < g->strt.size) {
        sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
        return GCSWEEPCOST;
      }
      else {  /* no more strings to sweep */
        g->sweepgc = &g->finobj;  /* prepare to sweep finalizable objects */
        g->gcstate = GCSsweepudata;
        return 0;
      }
    }
    case GCSsweepudata: {
      if (*g->sweepgc) {
        g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
        return GCSWEEPMAX*GCSWEEPCOST;
      }
      else {
        g->sweepgc = &g->allgc;  /* go to next phase */
        g->gcstate = GCSsweep;
        return GCSWEEPCOST;
      }
    }
    case GCSsweep: {
      if (*g->sweepgc) {
        g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
        return GCSWEEPMAX*GCSWEEPCOST;
      }
      else {
        /* sweep main thread */
        GCObject *mt = obj2gco(g->mainthread);
        sweeplist(L, &mt, 1);
        checkSizes(L);
        g->gcstate = GCSpause;  /* finish collection */
        return GCSWEEPCOST;
      }
    }
    default: lua_assert(0); return 0;
  }
}
Example #2
0
File: lgc.c Project: gitrider/wxsj2
static size_t mark (lua_State *L) {
  size_t deadmem;
  GCState st;
  GCObject *wkv;
  st.L = L;
  st.g = G(L);
  st.tmark = NULL;
  st.wkv = st.wk = st.wv = NULL;
  markroot(&st, L);
  propagatemarks(&st);  /* mark all reachable objects */
  cleartablevalues(L, st.wkv);
  cleartablevalues(L, st.wv);
  wkv = st.wkv;  /* keys must be cleared after preserving udata */
  st.wkv = NULL;
  st.wv = NULL;
  deadmem = luaC_separateudata(L);  /* separate userdata to be preserved */
  marktmu(&st);  /* mark `preserved' userdata */
  propagatemarks(&st);  /* remark, to propagate `preserveness' */
  cleartablekeys(L, wkv);
  /* `propagatemarks' may resuscitate some weak tables; clear them too */
  cleartablekeys(L, st.wk);
  cleartablevalues(L, st.wv);
  cleartablekeys(L, st.wkv);
  cleartablevalues(L, st.wkv);
  return deadmem;
}
Example #3
0
void luaC_fullgc (lua_State *L) {
  global_State *g = G(L);
  if(is_block_gc(L)) return;
  set_block_gc(L);
  if (g->gcstate <= GCSpropagate) {
    /* reset sweep marks to sweep all elements (returning them to white) */
    g->sweepstrgc = 0;
    g->sweepgc = &g->rootgc;
    /* reset other collector lists */
    g->gray = NULL;
    g->grayagain = NULL;
    g->weak = NULL;
    g->gcstate = GCSsweepstring;
  }
  lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
  /* finish any pending sweep phase */
  while (g->gcstate != GCSfinalize) {
    lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
    singlestep(L);
  }
  markroot(L);
  while (g->gcstate != GCSpause) {
    singlestep(L);
  }
  setthreshold(g);
  unset_block_gc(L);
}
Example #4
0
static l_mem singlestep(lua_State *L) {
    global_State *g = G(L);
    /*lua_checkmemory(L);*/
    switch (g->gcstate) {
    case GCSpause: {
        markroot(L); /* start a new collection */
        return 0;
    }
    case GCSpropagate: {
        if (g->gray)
            return propagatemark(g);
        else { /* no more `gray' objects */
            atomic(L); /* finish mark phase */
            return 0;
        }
    }
    case GCSsweepstring: {
        lu_mem old = g->totalbytes;
        sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
        if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
            g->gcstate = GCSsweep; /* end sweep-string phase */
        lua_assert(old >= g->totalbytes);
        g->estimate -= old - g->totalbytes;
        return GCSWEEPCOST;
    }
    case GCSsweep: {
        lu_mem old = g->totalbytes;
        g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
        if (*g->sweepgc == NULL) { /* nothing more to sweep? */
            checkSizes(L);
            g->gcstate = GCSfinalize; /* end sweep phase */
        }
        lua_assert(old >= g->totalbytes);
        g->estimate -= old - g->totalbytes;
        return GCSWEEPMAX * GCSWEEPCOST;
    }
    case GCSfinalize: {
        if (g->tmudata) {
            GCTM(L);
            if (g->estimate > GCFINALIZECOST)
                g->estimate -= GCFINALIZECOST;
            return GCFINALIZECOST;
        } else {
            g->gcstate = GCSpause; /* end collection */
            g->gcdept = 0;
            return 0;
        }
    }
    default:
        lua_assert(0);
        return 0;
    }
}
Example #5
0
// lua的gc状态机,执行顺序和下面的状态的从大到小开始一致
static l_mem singlestep (lua_State *L) {
  global_State *g = G(L);
  /*lua_checkmemory(L);*/
  switch (g->gcstate) {
    case GCSpause: {// 初始状态
      markroot(L);  /* start a new collection */// 主要就是标记主线程对象(也就是从白色染成灰色)
      return 0;
    }
    case GCSpropagate: {// 这个状态也是一个标记过程,并且会被进入多次,也就是分布迭代
      if (g->gray)// 如果gray对象一直存在的话,反复调用propagatemark函数,等所有的gray对象都被标记了,就会进入atomic函数处理
        return propagatemark(g);
      else {  /* no more `gray' objects */
        atomic(L);  /* finish mark phase */// 原子操作
        return 0;
      }
    }
    case GCSsweepstring: {// 清理字符串的阶段
      lu_mem old = g->totalbytes;
      sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
      if (g->sweepstrgc >= g->strt.size)  /* nothing more to sweep? */
        g->gcstate = GCSsweep;  /* end sweep-string phase */
      lua_assert(old >= g->totalbytes);
      g->estimate -= old - g->totalbytes;
      return GCSWEEPCOST;
    }
    case GCSsweep: {
      lu_mem old = g->totalbytes;
      g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
      if (*g->sweepgc == NULL) {  /* nothing more to sweep? */
        checkSizes(L);
        g->gcstate = GCSfinalize;  /* end sweep phase */
      }
      lua_assert(old >= g->totalbytes);
      g->estimate -= old - g->totalbytes;
      return GCSWEEPMAX*GCSWEEPCOST;
    }
    case GCSfinalize: {
      if (g->tmudata) {
        GCTM(L);
        if (g->estimate > GCFINALIZECOST)
          g->estimate -= GCFINALIZECOST;
        return GCFINALIZECOST;
      }
      else {
        g->gcstate = GCSpause;  /* end collection */
        g->gcdept = 0;
        return 0;
      }
    }
    default: lua_assert(0); return 0;
  }
}
Example #6
0
static lu_mem singlestep (lua_State *L) {
  global_State *g = G(L);
  switch (g->gcstate) {
    case GCSpause: {
      g->GCmemtrav = 0;  /* start to count memory traversed */
      if (!isgenerational(g))
        markroot(g);  /* start a new collection */
      /* in any case, root must be marked at this point */
      lua_assert(!iswhite(obj2gco(g->mainthread))
              && !iswhite(gcvalue(&g->l_registry)));
      g->gcstate = GCSpropagate;
      return g->GCmemtrav;
    }
    case GCSpropagate: {
      if (g->gray) {
        lu_mem oldtrav = g->GCmemtrav;
        propagatemark(g);
        return g->GCmemtrav - oldtrav;  /* memory traversed in this step */
      }
      else {  /* no more `gray' objects */
        lu_mem work;
        int sw;
        g->gcstate = GCSatomic;  /* finish mark phase */
        g->GCestimate = g->GCmemtrav;  /* save what was counted */;
        work = atomic(L);  /* add what was traversed by 'atomic' */
        g->GCestimate += work;  /* estimate of total memory traversed */ 
        sw = entersweep(L);
        return work + sw * GCSWEEPCOST;
      }
    }
    case GCSsweepstring: {
      int i;
      for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
        sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
      g->sweepstrgc += i;
      if (g->sweepstrgc >= g->strt.size)  /* no more strings to sweep? */
        g->gcstate = GCSsweepudata;
      return i * GCSWEEPCOST;
    }
    case GCSsweepudata: {
      if (g->sweepfin) {
        g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
        return GCSWEEPMAX*GCSWEEPCOST;
      }
      else {
        g->gcstate = GCSsweep;
        return 0;
      }
    }
    case GCSsweep: {
      if (g->sweepgc) {
        g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
        return GCSWEEPMAX*GCSWEEPCOST;
      }
      else {
        /* sweep main thread */
        GCObject *mt = obj2gco(g->mainthread);
        sweeplist(L, &mt, 1);
        checkSizes(L);
        g->gcstate = GCSpause;  /* finish collection */
        return GCSWEEPCOST;
      }
    }
    default: lua_assert(0); return 0;
  }
}