예제 #1
0
/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L, int all) {
  global_State *g = G(L);
  size_t deadmem = 0;
  GCObject **p = &g->mainthread->next;
  GCObject *curr;
  while ((curr = *p) != NULL) {
    if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
      p = &curr->gch.next;  /* don't bother with them */
    else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
      markfinalized(gco2u(curr));  /* don't need finalization */
      p = &curr->gch.next;
    }
    else {  /* must call its gc method */
      deadmem += sizeudata(gco2u(curr));
      markfinalized(gco2u(curr));
      *p = curr->gch.next;
      /* link `curr' at the end of `tmudata' list */
      if (g->tmudata == NULL)  /* list is empty? */
        g->tmudata = curr->gch.next = curr;  /* creates a circular list */
      else {
        curr->gch.next = g->tmudata->gch.next;
        g->tmudata->gch.next = curr;
        g->tmudata = curr;
      }
    }
  }
  return deadmem;
}
예제 #2
0
/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L) {
    size_t deadmem = 0;
    GCObject **p = &G(L)->rootudata;
    GCObject *curr;
    GCObject *collected = NULL;  /* to collect udata with gc event */
    GCObject **lastcollected = &collected;
    while ((curr = *p) != NULL) {
        lua_assert(curr->gch.tt == LUA_TUSERDATA);
        if (ismarked(curr) || isfinalized(gcotou(curr)))
            p = &curr->gch.next;  /* don't bother with them */

        else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
            markfinalized(gcotou(curr));  /* don't need finalization */
            p = &curr->gch.next;
        }
        else {  /* must call its gc method */
            deadmem += sizeudata(gcotou(curr)->uv.len);
            *p = curr->gch.next;
            curr->gch.next = NULL;  /* link `curr' at the end of `collected' list */
            *lastcollected = curr;
            lastcollected = &curr->gch.next;
        }
    }
    /* insert collected udata with gc event into `tmudata' list */
    *lastcollected = G(L)->tmudata;
    G(L)->tmudata = collected;
    return deadmem;
}
예제 #3
0
void luaC_callGCTM (lua_State *L) {
    lu_byte oldah = L->allowhook;
    L->allowhook = 0;  /* stop debug hooks during GC tag methods */
    L->top++;  /* reserve space to keep udata while runs its gc method */
    while (G(L)->tmudata != NULL) {
        GCObject *o = G(L)->tmudata;
        Udata *udata = gcotou(o);
        G(L)->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
        udata->uv.next = G(L)->rootudata;  /* return it to `root' list */
        G(L)->rootudata = o;
        setuvalue(L->top - 1, udata);  /* keep a reference to it */
        unmark(o);
        markfinalized(udata);
        do1gcTM(L, udata);
    }
    L->top--;
    L->allowhook = oldah;  /* restore hooks */
}
예제 #4
0
파일: lj_cdata.c 프로젝트: 03050903/Urho3D
/* Free a C data object. */
void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd)
{
  if (LJ_UNLIKELY(cd->marked & LJ_GC_CDATA_FIN)) {
    GCobj *root;
    makewhite(g, obj2gco(cd));
    markfinalized(obj2gco(cd));
    if ((root = gcref(g->gc.mmudata)) != NULL) {
      setgcrefr(cd->nextgc, root->gch.nextgc);
      setgcref(root->gch.nextgc, obj2gco(cd));
      setgcref(g->gc.mmudata, obj2gco(cd));
    } else {
      setgcref(cd->nextgc, obj2gco(cd));
      setgcref(g->gc.mmudata, obj2gco(cd));
    }
  } else if (LJ_LIKELY(!cdataisv(cd))) {
    CType *ct = ctype_raw(ctype_ctsG(g), cd->ctypeid);
    CTSize sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR;
    lua_assert(ctype_hassize(ct->info) || ctype_isfunc(ct->info) ||
	       ctype_isextern(ct->info));
    lj_mem_free(g, cd, sizeof(GCcdata) + sz);
  } else {
    lj_mem_free(g, memcdatav(cd), sizecdatav(cd));
  }
}
예제 #5
0
파일: lgc.c 프로젝트: gitrider/wxsj2
void luaC_callGCTM (lua_State *L) {
  lu_byte oldah = L->allowhook;
  L->allowhook = 0;  /* stop debug hooks during GC tag methods */
  L->top++;  /* reserve space to keep udata while runs its gc method */
#if LUA_REFCOUNT
  while (G(L)->tmudata_head.next != (GCObject*)&G(L)->tmudata_tail) {
    GCObject *o = G(L)->tmudata_head.next;
    Udata *udata = gcotou(o);
    G(L)->tmudata_head.next = udata->uv.next;  /* remove udata from `tmudata' */
    udata->uv.prev = (GCObject*)&G(L)->rootudata_head;
    udata->uv.next = G(L)->rootudata_head.next;
	if (udata->uv.next)
      udata->uv.next->uv.prev = o;
    G(L)->rootudata_head.next = o;
#else !LUA_REFCOUNT
  while (G(L)->tmudata != NULL) {
    GCObject *o = G(L)->tmudata;
    Udata *udata = gcotou(o);
    G(L)->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
    udata->uv.next = G(L)->rootudata;  /* return it to `root' list */
    G(L)->rootudata = o;
#endif LUA_REFCOUNT
    setuvalue(L->top - 1, udata);  /* keep a reference to it */
    unmark(o);
    markfinalized(udata);
    do1gcTM(L, udata);
  }
  L->top--;
  L->allowhook = oldah;  /* restore hooks */
}


void luaC_sweep (lua_State *L, int all) {
  if (all) all = 256;  /* larger than any mark */
#if LUA_REFCOUNT
  sweeplist(L, &G(L)->rootudata_head.next, (GCObject*)&G(L)->rootudata_tail, all);
#else !LUA_REFCOUNT
  sweeplist(L, &G(L)->rootudata, NULL, all);
#endif LUA_REFCOUNT
  sweepstrings(L, all);
#if LUA_REFCOUNT
  sweeplist(L, &G(L)->rootgc_head.next, (GCObject*)&G(L)->rootgc_tail, all);
#else !LUA_REFCOUNT
  sweeplist(L, &G(L)->rootgc, NULL, all);
#endif LUA_REFCOUNT
}


/* mark root set */
static void markroot (GCState *st, lua_State *L) {
  int i;
  global_State *g = st->g;
  markobject(st, defaultmeta(L));
  for (i = 0; i < LUA_NTYPES; i++)
  {
    markobject(st, defaultmetatypes(L, i));
  }
  markobject(st, registry(L));
  traversestack(st, g->mainthread);
  if (L != g->mainthread)  /* another thread is running? */
    markvalue(st, L);  /* cannot collect it */
  if (G(L)->userGCFunction)
  {
	st->L = g->mainthread;
    G(L)->userGCFunction(st);
  }
}
예제 #6
0
파일: lgc.c 프로젝트: gitrider/wxsj2
static void marktmu (GCState *st) {
  GCObject *u;
#if LUA_REFCOUNT
  for (u = st->g->tmudata_head.next; u != (GCObject*)&st->g->tmudata_tail; u = u->gch.next) {
#else !LUA_REFCOUNT
  for (u = st->g->tmudata; u; u = u->gch.next) {
#endif LUA_REFCOUNT
    unmark(u);  /* may be marked, if left from previous GC */
    reallymarkobject(st, u);
  }
}


/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L) {
  size_t deadmem = 0;
#if LUA_REFCOUNT
  GCObject **p = &G(L)->rootudata_head.next;
#else !LUA_REFCOUNT
  GCObject **p = &G(L)->rootudata;
#endif LUA_REFCOUNT
  GCObject *curr;
  GCObject *collected = NULL;  /* to collect udata with gc event */
#if !LUA_REFCOUNT
  GCObject **lastcollected = &collected;
  while ((curr = *p) != NULL) {
    lua_assert(curr->gch.tt == LUA_TUSERDATA);
#else LUA_REFCOUNT
  while ((curr = *p) != (GCObject*)&G(L)->rootudata_tail) {
#endif LUA_REFCOUNT
    if (ismarked(curr) || isfinalized(gcotou(curr)))
      p = &curr->gch.next;  /* don't bother with them */

    else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
      markfinalized(gcotou(curr));  /* don't need finalization */
      p = &curr->gch.next;
    }
    else {  /* must call its gc method */
      deadmem += sizeudata(gcotou(curr)->uv.len);
      *p = curr->gch.next;
#if LUA_REFCOUNT
	  Unlink(curr);
	  curr->gch.next = (GCObject*)&G(L)->tmudata_tail;  /* link `curr' at the end of `collected' list */
	  curr->gch.prev = G(L)->tmudata_tail.prev;
	  G(L)->tmudata_tail.prev->gch.next = curr;
      G(L)->tmudata_tail.prev = curr;
#else !LUA_REFCOUNT
	  curr->gch.next = NULL;  /* link `curr' at the end of `collected' list */
      *lastcollected = curr;
      lastcollected = &curr->gch.next;
#endif LUA_REFCOUNT
    }
  }
  /* insert collected udata with gc event into `tmudata' list */
#if LUA_REFCOUNT
//  *lastcollected = G(L)->tmudata_head.next;
//  G(L)->tmudata_head.next = collected;
#else !LUA_REFCOUNT
  *lastcollected = G(L)->tmudata;
  G(L)->tmudata = collected;
#endif LUA_REFCOUNT
  return deadmem;
}


static void removekey (lua_State *L, Node *n) {
  (void)L;
  setnilvalue(gval(n));  /* remove corresponding value ... */
  if (iscollectable(gkey(n)))
    setttype(gkey(n), LUA_TNONE);  /* dead key; remove it */
}