Beispiel #1
0
static void reallymarkobject (global_State *g, GCObject *o) {
  lua_assert(iswhite(o) && !isdead(g, o));
  white2gray(o);
  switch (o->gch.tt) {
    case LUA_TSTRING: {
      return;
    }
    case LUA_TUSERDATA: {
      Table *mt = gco2u(o)->metatable;
      gray2black(o);  /* udata are never gray */
      if (mt && !luaR_isrotable(mt)) markobject(g, mt);
      markobject(g, gco2u(o)->env);
      return;
    }
    case LUA_TUPVAL: {
      UpVal *uv = gco2uv(o);
      markvalue(g, uv->v);
      if (uv->v == &uv->u.value)  /* closed? */
        gray2black(o);  /* open upvalues are never black */
      return;
    }
    case LUA_TFUNCTION: {
      gco2cl(o)->c.gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TTABLE: {
      gco2h(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TTHREAD: {
      gco2th(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TPROTO: {
      gco2p(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    default: lua_assert(0);
  }
}
Beispiel #2
0
static void traversestack (GCState *st, lua_State *L1) {
  StkId o, lim;
  CallInfo *ci;
  lua_State *L = st->L;
  (void)L;
  markobject(st, gt(L1));
  lim = L1->top;
  for (ci = L1->base_ci; ci <= L1->ci; ci++) {
    lua_assert(ci->top <= L1->stack_last);
    lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC));
    if (lim < ci->top)
      lim = ci->top;
  }
  for (o = L1->stack; o < L1->top; o++)
    markobject(st, o);
  for (; o <= lim; o++)
    setnilvalue(o);
  checkstacksizes(L1, lim);
}
Beispiel #3
0
/*
** mark an object. Userdata and closed upvalues are visited and turned
** black here. Strings remain gray (it is the same as making them
** black). Other objects are marked gray and added to appropriate list
** to be visited (and turned black) later. (Open upvalues are already
** linked in 'headuv' list.)
*/
static void reallymarkobject (global_State *g, GCObject *o) {
  lua_assert(iswhite(o) && !isdead(g, o));
  white2gray(o);
  switch (gch(o)->tt) {
    case LUA_TSTRING: {
      return;  /* for strings, gray is as good as black */
    }
    case LUA_TUSERDATA: {
      Table *mt = gco2u(o)->metatable;
      markobject(g, mt);
      markobject(g, gco2u(o)->env);
      gray2black(o);  /* all pointers marked */
      return;
    }
    case LUA_TUPVAL: {
      UpVal *uv = gco2uv(o);
      markvalue(g, uv->v);
      if (uv->v == &uv->u.value)  /* closed? (open upvalues remain gray) */
        gray2black(o);  /* make it black */
      return;
    }
    case LUA_TFUNCTION: {
      gco2cl(o)->c.gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TTABLE: {
      linktable(gco2t(o), &g->gray);
      break;
    }
    case LUA_TTHREAD: {
      gco2th(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TPROTO: {
      gco2p(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    default: lua_assert(0);
  }
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
static int traverseproto (global_State *g, Proto *f) {
	int i;
	if (f->cache && iswhite(obj2gco(f->cache)))
	f->cache = NULL;  /* allow cache to be collected */
	markobject(g, f->source);
	for (i = 0; i < f->sizek; i++)  /* mark literals */
	markvalue(g, &f->k[i]);
	for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
	markobject(g, f->upvalues[i].name);
	for (i = 0; i < f->sizep; i++)  /* mark nested protos */
	markobject(g, f->p[i]);
	for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
	markobject(g, f->locvars[i].varname);
	return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
							sizeof(Proto *) * f->sizep +
							sizeof(TValue) * f->sizek +
							sizeof(int) * f->sizelineinfo +
							sizeof(LocVar) * f->sizelocvars +
							sizeof(Upvaldesc) * f->sizeupvalues;
}
Beispiel #6
0
/*
** mark root set and reset all gray lists, to start a new collection
*/
static void restartcollection (global_State *g) {
    g->gray = g->grayagain = NULL;
    g->weak = g->allweak = g->ephemeron = NULL;
    markobject(g, g->mainthread);
    markvalue(g, &g->l_registry);
#if LUA_FASTREF_SUPPORT
    markvalue(g, &g->l_refs);
#endif /* LUA_FASTREF_SUPPORT */
    markmt(g);
    markbeingfnz(g);  /* mark any finalizing object left from previous cycle */
}
Beispiel #7
0
static void globalmark (void)
{
  TaggedString *g;
  for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next){
    LUA_ASSERT(g->constindex >= 0, "userdata in global list");
    if (g->u.s.globalval.ttype != LUA_T_NIL) {
      markobject(&g->u.s.globalval);
      strmark(g);  /* cannot collect non nil global variables */
    }
  }
}
Beispiel #8
0
static void traverseclosure (GCState *st, Closure *cl) {
  if (cl->c.isC) {
    int i;
    for (i=0; i<cl->c.nupvalues; i++)  /* mark its upvalues */
      markobject(st, &cl->c.upvalue[i]);
  }
  else {
    int i;
    lua_assert(cl->l.nupvalues == cl->l.p->nups);
    markvalue(st, hvalue(&cl->l.g));
    markvalue(st, cl->l.p);
    for (i=0; i<cl->l.nupvalues; i++) {  /* mark its upvalues */
      UpVal *u = cl->l.upvals[i];
      if (!u->marked) {
        markobject(st, &u->value);
        u->marked = 1;
      }
    }
  }
}
Beispiel #9
0
/*
** open upvalues point to values in a thread, so those values should
** be marked when the thread is traversed except in the atomic phase
** (because then the value cannot be changed by the thread and the
** thread may not be traversed again)
*/
static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
  int i;
  markobject(g, cl->p);  /* mark its prototype */
  for (i = 0; i < cl->nupvalues; i++) {  /* mark its upvalues */
    UpVal *uv = cl->upvals[i];
    if (uv != NULL) {
      if (upisopen(uv) && g->gcstate != GCSinsideatomic)
        uv->u.open.touched = 1;  /* can be marked in 'remarkupvals' */
      else
        markvalue(g, uv->v);
    }
  }
  return sizeLclosure(cl->nupvalues);
}
Beispiel #10
0
void LuaPlusGCFunction(void* s)
{
	GCState* st = (GCState*)s;
	LuaState* state = (LuaState*)lua_getstateuserdata(st->L);
	if (!state)
		return;

	LuaObject* curObj = state->GetHeadObject()->m_next;
	while (curObj != state->GetTailObject())
	{
		markobject(st, &curObj->m_object);
		curObj = curObj->m_next;		
	}
}
Beispiel #11
0
/*
** mark an object. Userdata, strings, and closed upvalues are visited
** and turned black here. Other objects are marked gray and added
** to appropriate list to be visited (and turned black) later. (Open
** upvalues are already linked in 'headuv' list.)
*/
static void reallymarkobject (global_State *g, GCObject *o) {
 reentry:
  white2gray(o);
  switch (gch(o)->tt) {
    case LUA_TSHRSTR:
    case LUA_TLNGSTR: {
      gray2black(o);
      g->GCmemtrav += sizestring(gco2ts(o));
      break;
    }
    case LUA_TUSERDATA: {
      TValue uvalue;
      markobject(g, gco2u(o)->metatable);  /* mark its metatable */
      gray2black(o);
      g->GCmemtrav += sizeudata(gco2u(o));
      getuservalue(g->mainthread, rawgco2u(o), &uvalue);
      if (valiswhite(&uvalue)) {  /* markvalue(g, &uvalue); */
        o = gcvalue(&uvalue);
        goto reentry;
      }
      break;
    }
    case LUA_TLCL: {
      gco2lcl(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TCCL: {
      gco2ccl(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TTABLE: {
      linktable(gco2t(o), &g->gray);
      break;
    }
    case LUA_TTHREAD: {
      gco2th(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TPROTO: {
      gco2p(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    default: lua_assert(0); break;
  }
}
Beispiel #12
0
/* 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));
#if LUA_FASTREF_SUPPORT
  markvalue(g, &G(L)->l_refs);
#endif /* LUA_FASTREF_SUPPORT */
  markmt(g);
  g->gcstate = GCSpropagate;
}
Beispiel #13
0
static int traverseproto (global_State *g, Proto *f) {
  int i;
  if (f->cache && iswhite(obj2gco(f->cache)))
    f->cache = NULL;  /* allow cache to be collected */
  stringmark(f->source);
  for (i = 0; i < f->sizek; i++)  /* mark literals */
    markvalue(g, &f->k[i]);
  for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
    stringmark(f->upvalues[i].name);
  for (i = 0; i < f->sizep; i++)  /* mark nested protos */
    markobject(g, f->p[i]);
  for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
    stringmark(f->locvars[i].varname);
  return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars;
}
Beispiel #14
0
/* 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);
#if LUAPLUS_EXTENSIONS
  if (G(L)->userGCFunction)
    G(L)->userGCFunction(L);
#endif /* LUAPLUS_EXTENSIONS */
  g->gcstate = GCSpropagate;
}
Beispiel #15
0
static l_mem atomic (lua_State *L) {
    global_State *g = G(L);
    l_mem work;
    GCObject *origweak, *origall;
    GCObject *grayagain = g->grayagain;  /* save original list */
    lua_assert(g->ephemeron == NULL && g->weak == NULL);
    lua_assert(!iswhite(g->mainthread));
    g->gcstate = GCSinsideatomic;
    g->GCmemtrav = 0;  /* start counting work */
    markobject(g, L);  /* mark running thread */
    /* registry and global metatables may be changed by API */
    markvalue(g, &g->l_registry);
    markmt(g);  /* mark global metatables */
    /* remark occasional upvalues of (maybe) dead threads */
    remarkupvals(g);
    propagateall(g);  /* propagate changes */
    work = g->GCmemtrav;  /* stop counting (do not recount 'grayagain') */
    g->gray = grayagain;
    propagateall(g);  /* traverse 'grayagain' list */
    g->GCmemtrav = 0;  /* restart counting */
    convergeephemerons(g);
    /* at this point, all strongly accessible objects are marked. */
    /* Clear values from weak tables, before checking finalizers */
    clearvalues(g, g->weak, NULL);
    clearvalues(g, g->allweak, NULL);
    origweak = g->weak;
    origall = g->allweak;
    work += g->GCmemtrav;  /* stop counting (objects being finalized) */
    separatetobefnz(g, 0);  /* separate objects to be finalized */
    g->gcfinnum = 1;  /* there may be objects to be finalized */
    markbeingfnz(g);  /* mark objects that will be finalized */
    propagateall(g);  /* remark, to propagate 'resurrection' */
    g->GCmemtrav = 0;  /* restart counting */
    convergeephemerons(g);
    /* at this point, all resurrected objects are marked. */
    /* remove dead objects from weak tables */
    clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
    clearkeys(g, g->allweak, NULL);  /* clear keys from all 'allweak' tables */
    /* clear values from resurrected weak tables */
    clearvalues(g, g->weak, origweak);
    clearvalues(g, g->allweak, origall);
    luaS_clearcache(g);
    g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
    work += g->GCmemtrav;  /* complete counting */
    return work;  /* estimate of memory marked by 'atomic' */
}
Beispiel #16
0
static void protomark(TProtoFunc *f) {
	if (!f->head.marked) {
		LocVar *v = f->locvars;
		int32 i;
		f->head.marked = 1;
		if (f->fileName)
			strmark(f->fileName);
		for (i = 0; i < f->nconsts; i++)
			markobject(&f->consts[i]);
		if (v) {
			for (; v->line != -1; v++) {
				if (v->varname)
					strmark(v->varname);
			}
		}
	}
}
Beispiel #17
0
/*
** All marks are conditional because a GC may happen while the
** prototype is still being created
*/
static void traverseproto (global_State *g, Proto *f) {
  int i;
  if (f->source) stringmark(f->source);
  for (i=0; i<f->sizek; i++)  /* mark literals */
    markvalue(g, &f->k[i]);
  for (i=0; i<f->sizeupvalues; i++) {  /* mark upvalue names */
    if (f->upvalues[i])
      stringmark(f->upvalues[i]);
  }
  for (i=0; i<f->sizep; i++) {  /* mark nested protos */
    if (f->p[i])
      markobject(g, f->p[i]);
  }
  for (i=0; i<f->sizelocvars; i++) {  /* mark local-variable names */
    if (f->locvars[i].varname)
      stringmark(f->locvars[i].varname);
  }
}
Beispiel #18
0
static int traversetable(global_State *g, Table *h) {
    int i;
    int weakkey = 0;
    int weakvalue = 0;
    const TValue *mode;
    if (h->metatable)
        markobject(g, h->metatable);
    mode = gfasttm(g, h->metatable, TM_MODE);
    if (mode && ttisstring(mode)) { /* is there a weak mode? */
        weakkey = (strchr(svalue(mode), 'k') != NULL);
        weakvalue = (strchr(svalue(mode), 'v') != NULL);
        if (weakkey || weakvalue) { /* is really weak? */
            h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
            h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
                                   (weakvalue << VALUEWEAKBIT));
            h->gclist = g->weak; /* must be cleared after GC, ... */
            g->weak = obj2gco(h); /* ... so put in the appropriate list */
        }
    }
    if (weakkey && weakvalue)
        return 1;
    if (!weakvalue) {
        i = h->sizearray;
        while (i--)
            markvalue(g, &h->array[i]);
    }
    i = sizenode(h);
    while (i--) {
        Node *n = gnode(h, i);
        lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
        if (ttisnil(gval(n)))
            removeentry(n); /* remove empty entries */
        else {
            lua_assert(!ttisnil(gkey(n)));
            if (!weakkey)
                markvalue(g, gkey(n));
            if (!weakvalue)
                markvalue(g, gval(n));
        }
    }
    return weakkey || weakvalue;
}
Beispiel #19
0
static lu_mem traversetable (global_State *g, Table *h) {
	const char *weakkey, *weakvalue;
	const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
	markobject(g, h->metatable);
	if (mode && ttisstring(mode) &&  /* is there a weak mode? */
		((weakkey = strchr(svalue(mode), 'k')),
		(weakvalue = strchr(svalue(mode), 'v')),
		(weakkey || weakvalue))) {  /* is really weak? */
	black2gray(obj2gco(h));  /* keep table gray */
	if (!weakkey)  /* strong keys? */
		traverseweakvalue(g, h);
	else if (!weakvalue)  /* strong values? */
		traverseephemeron(g, h);
	else  /* all weak */
		linktable(h, &g->allweak);  /* nothing to traverse now */
	}
	else  /* not weak */
	traversestrongtable(g, h);
	return sizeof(Table) + sizeof(TValue) * h->sizearray +
							sizeof(Node) * cast(size_t, sizenode(h));
}
Beispiel #20
0
static l_mem atomic (lua_State *L) {
	global_State *g = G(L);
	l_mem work = -cast(l_mem, g->GCmemtrav);  /* start counting work */
	GCObject *origweak, *origall;
	lua_assert(!iswhite(obj2gco(g->mainthread)));
	markobject(g, L);  /* mark running thread */
	/* registry and global metatables may be changed by API */
	markvalue(g, &g->l_registry);
	markmt(g);  /* mark basic metatables */
	/* remark occasional upvalues of (maybe) dead threads */
	remarkupvals(g);
	propagateall(g);  /* propagate changes */
	work += g->GCmemtrav;  /* stop counting (do not (re)count grays) */
	/* traverse objects caught by write barrier and by 'remarkupvals' */
	retraversegrays(g);
	work -= g->GCmemtrav;  /* restart counting */
	convergeephemerons(g);
	/* at this point, all strongly accessible objects are marked. */
	/* clear values from weak tables, before checking finalizers */
	clearvalues(g, g->weak, NULL);
	clearvalues(g, g->allweak, NULL);
	origweak = g->weak; origall = g->allweak;
	work += g->GCmemtrav;  /* stop counting (objects being finalized) */
	separatetobefnz(L, 0);  /* separate objects to be finalized */
	markbeingfnz(g);  /* mark objects that will be finalized */
	propagateall(g);  /* remark, to propagate `preserveness' */
	work -= g->GCmemtrav;  /* restart counting */
	convergeephemerons(g);
	/* at this point, all resurrected objects are marked. */
	/* remove dead objects from weak tables */
	clearkeys(g, g->ephemeron, NULL);  /* clear keys from all ephemeron tables */
	clearkeys(g, g->allweak, NULL);  /* clear keys from all allweak tables */
	/* clear values from resurrected weak tables */
	clearvalues(g, g->weak, origweak);
	clearvalues(g, g->allweak, origall);
	g->currentwhite = cast_byte(otherwhite(g));  /* flip current white */
	work += g->GCmemtrav;  /* complete counting */
	return work;  /* estimate of memory marked by 'atomic' */
}
Beispiel #21
0
static void traversetable (GCState *st, Table *h) {
  int i;
  int weakkey = 0;
  int weakvalue = 0;
  const TObject *mode;
  markvalue(st, h->metatable);
  lua_assert(h->lsizenode || h->node == st->g->dummynode);
  mode = gfasttm(st->g, h->metatable, TM_MODE);
  if (mode && ttisstring(mode)) {  /* is there a weak mode? */
    weakkey = (strchr(svalue(mode), 'k') != NULL);
    weakvalue = (strchr(svalue(mode), 'v') != NULL);
    if (weakkey || weakvalue) {  /* is really weak? */
      GCObject **weaklist;
      h->marked &= ~(KEYWEAK | VALUEWEAK);  /* clear bits */
      h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
                                 (weakvalue << VALUEWEAKBIT));
      weaklist = (weakkey && weakvalue) ? &st->wkv :
                              (weakkey) ? &st->wk :
                                          &st->wv;
      h->gclist = *weaklist;  /* must be cleared after GC, ... */
      *weaklist = valtogco(h);  /* ... so put in the appropriate list */
    }
  }
  if (!weakvalue) {
    i = h->sizearray;
    while (i--)
      markobject(st, &h->array[i]);
  }
  i = sizenode(h);
  while (i--) {
    Node *n = gnode(h, i);
    if (!ttisnil(gval(n))) {
      lua_assert(!ttisnil(gkey(n)));
      condmarkobject(st, gkey(n), !weakkey);
      condmarkobject(st, gval(n), !weakvalue);
    }
  }
}
Beispiel #22
0
LUA_API int lua_ref (lua_State *L,  int lock) {
  int ref;
  if (ttype(L->top-1) == LUA_TNIL)
    ref = LUA_REFNIL;
  else {
    if (L->refFree != NONEXT) {  /* is there a free place? */
      ref = L->refFree;
      L->refFree = L->refArray[ref].st;
    }
    else {  /* no more free places */
      luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
                      "reference table overflow", MAX_INT);
      L->nblocks += sizeof(struct Ref);
      ref = L->refSize++;
    }
    L->refArray[ref].o = *(L->top-1);
    L->refArray[ref].st = lock ? LOCK : HOLD;

    markobject(&L->refArray[ref].o, L, 0);
  }
  L->top--;
  return ref;
}
Beispiel #23
0
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) */
#if LUAPLUS_EXTENSIONS
  if (G(L)->userGCFunction)
    G(L)->userGCFunction(L);
#endif /* LUAPLUS_EXTENSIONS */
  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' */
#if LUA_REFCOUNT
  cleartable(L, g->weak);  /* remove collected objects from weak tables */
#else
  cleartable(g->weak);  /* remove collected objects from weak tables */
#endif /* LUA_REFCOUNT */
  /* 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 */
}
Beispiel #24
0
static void markmt (global_State *g) {
  int i;
  for (i=0; i<NUM_TAGS; i++)
    if (g->mt[i]) markobject(g, g->mt[i]);
}
Beispiel #25
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 */
#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);
  }
}
Beispiel #26
0
/*
** mark all objects in list of being-finalized
*/
static void markbeingfnz (global_State *g) {
  GCObject *o;
  for (o = g->tobefnz; o != NULL; o = o->next)
    markobject(g, o);
}
Beispiel #27
0
static void markmt (global_State *g) {
  int i;
  for (i=0; i<NUM_TAGS; i++)
    if (g->mt[i] && !luaR_isrotable(g->mt[i])) markobject(g, g->mt[i]);
}
Beispiel #28
0
static void markstack (lua_State *L, GCState *st) {
  StkId o;
  for (o=L->stack; o<L->top; o++)
    markobject(st, o);
}
Beispiel #29
0
/*
** mark metamethods for basic types
*/
static void markmt (global_State *g) {
	int i;
	for (i=0; i < LUA_NUMTAGS; i++)
	markobject(g, g->mt[i]);
}