⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lgc.c

📁 lua的即时编译器。支持lua 5.1.2版本
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (testbit(h->marked, VALUEWEAKBIT)) {      while (i--) {        TValue *o = &h->array[i];        if (iscleared(o, 0))  /* value was collected? */          setnilvalue(o);  /* remove value */      }    }    i = sizenode(h);    while (i--) {      Node *n = gnode(h, i);      if (!ttisnil(gval(n)) &&  /* non-empty entry? */          (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {        setnilvalue(gval(n));  /* remove value ... */        removeentry(n);  /* remove entry from table */      }    }    l = h->gclist;  }}static void freeobj (lua_State *L, GCObject *o) {  switch (o->gch.tt) {    case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;    case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;    case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;    case LUA_TTABLE: luaH_free(L, gco2h(o)); break;    case LUA_TTHREAD: {      lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);      luaE_freethread(L, gco2th(o));      break;    }    case LUA_TSTRING: {      G(L)->strt.nuse--;      luaM_freemem(L, o, sizestring(gco2ts(o)));      break;    }    case LUA_TUSERDATA: {      luaM_freemem(L, o, sizeudata(gco2u(o)));      break;    }    default: lua_assert(0);  }}#define sweepwholelist(L,p)	sweeplist(L,p,MAX_LUMEM)static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {  GCObject *curr;  global_State *g = G(L);  int deadmask = otherwhite(g);  while ((curr = *p) != NULL && count-- > 0) {    if (curr->gch.tt == LUA_TTHREAD)  /* sweep open upvalues of each thread */      sweepwholelist(L, &gco2th(curr)->openupval);    if ((curr->gch.marked ^ WHITEBITS) & deadmask) {  /* not dead? */      lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));      makewhite(g, curr);  /* make it white (for next cycle) */      p = &curr->gch.next;    }    else {  /* must erase `curr' */      lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));      *p = curr->gch.next;      if (curr == g->rootgc)  /* is the first element of the list? */        g->rootgc = curr->gch.next;  /* adjust first */      freeobj(L, curr);    }  }  return p;}static void checkSizes (lua_State *L) {  global_State *g = G(L);  /* check size of string hash */  if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&      g->strt.size > MINSTRTABSIZE*2)    luaS_resize(L, g->strt.size/2);  /* table is too big */  /* check size of buffer */  if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) {  /* buffer too big? */    size_t newsize = luaZ_sizebuffer(&g->buff) / 2;    luaZ_resizebuffer(L, &g->buff, newsize);  }}static void GCTM (lua_State *L) {  global_State *g = G(L);  GCObject *o = g->tmudata->gch.next;  /* get first element */  Udata *udata = rawgco2u(o);  const TValue *tm;  /* remove udata from `tmudata' */  if (o == g->tmudata)  /* last element? */    g->tmudata = NULL;  else    g->tmudata->gch.next = udata->uv.next;  udata->uv.next = g->mainthread->next;  /* return it to `root' list */  g->mainthread->next = o;  makewhite(g, o);  tm = fasttm(L, udata->uv.metatable, TM_GC);  if (tm != NULL) {    lu_byte oldah = L->allowhook;    lu_mem oldt = g->GCthreshold;    L->allowhook = 0;  /* stop debug hooks during GC tag method */    g->GCthreshold = 2*g->totalbytes;  /* avoid GC steps */    setobj2s(L, L->top, tm);    setuvalue(L, L->top+1, udata);    L->top += 2;    luaD_call(L, L->top - 2, 0);    L->allowhook = oldah;  /* restore hooks */    g->GCthreshold = oldt;  /* restore threshold */  }}/*** Call all GC tag methods*/void luaC_callGCTM (lua_State *L) {  while (G(L)->tmudata)    GCTM(L);}void luaC_freeall (lua_State *L) {  global_State *g = G(L);  int i;  g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT);  /* mask to collect all elements */  sweepwholelist(L, &g->rootgc);  for (i = 0; i < g->strt.size; i++)  /* free all string lists */    sweepwholelist(L, &g->strt.hash[i]);}static void markmt (global_State *g) {  int i;  for (i=0; i<NUM_TAGS; i++)    if (g->mt[i]) markobject(g, g->mt[i]);}/* mark root set */static void markroot (lua_State *L) {  global_State *g = G(L);  g->gray = NULL;  g->grayagain = NULL;  g->weak = NULL;  markobject(g, g->mainthread);  /* make global table be traversed before main stack */  markvalue(g, gt(g->mainthread));  markvalue(g, registry(L));  markmt(g);  g->gcstate = GCSpropagate;}static void remarkupvals (global_State *g) {  UpVal *uv;  for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {    lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);    if (isgray(obj2gco(uv)))      markvalue(g, uv->v);  }}static void atomic (lua_State *L) {  global_State *g = G(L);  size_t udsize;  /* total size of userdata to be finalized */  /* remark occasional upvalues of (maybe) dead threads */  remarkupvals(g);  /* traverse objects cautch by write barrier and by 'remarkupvals' */  propagateall(g);  /* remark weak tables */  g->gray = g->weak;  g->weak = NULL;  lua_assert(!iswhite(obj2gco(g->mainthread)));  markobject(g, L);  /* mark running thread */  markmt(g);  /* mark basic metatables (again) */  propagateall(g);  /* remark gray again */  g->gray = g->grayagain;  g->grayagain = NULL;  propagateall(g);  udsize = luaC_separateudata(L, 0);  /* separate userdata to be finalized */  marktmu(g);  /* mark `preserved' userdata */  udsize += propagateall(g);  /* remark, to propagate `preserveness' */  cleartable(g->weak);  /* remove collected objects from weak tables */  /* flip current white */  g->currentwhite = cast_byte(otherwhite(g));  g->sweepstrgc = 0;  g->sweepgc = &g->rootgc;  g->gcstate = GCSsweepstring;  g->estimate = g->totalbytes - udsize;  /* first estimate */}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;  }}void luaC_step (lua_State *L) {  global_State *g = G(L);  l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;  if (lim == 0)    lim = (MAX_LUMEM-1)/2;  /* no limit */  g->gcdept += g->totalbytes - g->GCthreshold;  do {    lim -= singlestep(L);    if (g->gcstate == GCSpause)      break;  } while (lim > 0);  if (g->gcstate != GCSpause) {    if (g->gcdept < GCSTEPSIZE)      g->GCthreshold = g->totalbytes + GCSTEPSIZE;  /* - lim/g->gcstepmul;*/    else {      g->gcdept -= GCSTEPSIZE;      g->GCthreshold = g->totalbytes;    }  }  else {    lua_assert(g->totalbytes >= g->estimate);    setthreshold(g);  }}void luaC_fullgc (lua_State *L) {  global_State *g = G(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);}void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {  global_State *g = G(L);  lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));  lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);  lua_assert(ttype(&o->gch) != LUA_TTABLE);  /* must keep invariant? */  if (g->gcstate == GCSpropagate)    reallymarkobject(g, v);  /* restore invariant */  else  /* don't mind */    makewhite(g, o);  /* mark as white just to avoid other barriers */}void luaC_barrierback (lua_State *L, Table *t) {  global_State *g = G(L);  GCObject *o = obj2gco(t);  lua_assert(isblack(o) && !isdead(g, o));  lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);  black2gray(o);  /* make table gray (again) */  t->gclist = g->grayagain;  g->grayagain = o;}void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {  global_State *g = G(L);  o->gch.next = g->rootgc;  g->rootgc = o;  o->gch.marked = luaC_white(g);  o->gch.tt = tt;}void luaC_linkupval (lua_State *L, UpVal *uv) {  global_State *g = G(L);  GCObject *o = obj2gco(uv);  o->gch.next = g->rootgc;  /* link upvalue into `rootgc' list */  g->rootgc = o;  if (isgray(o)) {     if (g->gcstate == GCSpropagate) {      gray2black(o);  /* closed upvalues need barrier */      luaC_barrier(L, uv, uv->v);    }    else {  /* sweep phase: sweep it (turning it into white) */      makewhite(g, o);      lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -