Exemple #1
0
void reallymarkobject (global_State *g, GCObject *o) {
#else
static void reallymarkobject (global_State *g, GCObject *o) {
#endif /* LUAPLUS_EXTENSIONS */
  lua_assert(iswhite(o) && !isdead(g, o));
  white2gray(o);
  switch (o->gch.tt) {
    case LUA_TSTRING: {
      return;
    }
#if LUA_WIDESTRING
    case LUA_TWSTRING: {
      return;
    }
#endif /* LUA_WIDESTRING */
    case LUA_TUSERDATA: {
      Table *mt = gco2u(o)->metatable;
      gray2black(o);  /* udata are never gray */
      if (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);
  }
}
Exemple #2
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 (o->tt) {
    case LUA_TSHRSTR: {
        gray2black(o);
        g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
        break;
    }
    case LUA_TLNGSTR: {
        gray2black(o);
        g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
        break;
    }
    case LUA_TUSERDATA: {
        TValue uvalue;
        markobjectN(g, gco2u(o)->metatable);  /* mark its metatable */
        gray2black(o);
        g->GCmemtrav += sizeudata(gco2u(o));
        getuservalue(g->mainthread, gco2u(o), &uvalue);
        if (valiswhite(&uvalue)) {  /* markvalue(g, &uvalue); */
            o = gcvalue(&uvalue);
            goto reentry;
        }
        break;
    }
    case LUA_TLCL: {
        linkgclist(gco2lcl(o), g->gray);
        break;
    }
    case LUA_TCCL: {
        linkgclist(gco2ccl(o), g->gray);
        break;
    }
    case LUA_TTABLE: {
        linkgclist(gco2t(o), g->gray);
        break;
    }
    case LUA_TTHREAD: {
        linkgclist(gco2th(o), g->gray);
        break;
    }
    case LUA_TPROTO: {
        linkgclist(gco2p(o), g->gray);
        break;
    }
    default:
        lua_assert(0);
        break;
    }
}
Exemple #3
0
/*
** traverse one gray object, turning it to black (except for threads,
** which are always gray).
** Returns number of values traversed.
*/
static int propagatemark (global_State *g) {
  GCObject *o = g->gray;
  lua_assert(isgray(o));
  gray2black(o);
  switch (gch(o)->tt) {
    case LUA_TTABLE: {
      Table *h = gco2t(o);
      g->gray = h->gclist;
      return traversetable(g, h);
    }
    case LUA_TFUNCTION: {
      Closure *cl = gco2cl(o);
      g->gray = cl->c.gclist;
      return traverseclosure(g, cl);
    }
    case LUA_TTHREAD: {
      lua_State *th = gco2th(o);
      g->gray = th->gclist;
      th->gclist = g->grayagain;
      g->grayagain = o;
      black2gray(o);
      return traversestack(g, th);
    }
    case LUA_TPROTO: {
      Proto *p = gco2p(o);
      g->gray = p->gclist;
      return traverseproto(g, p);
    }
    default: lua_assert(0); return 0;
  }
}
Exemple #4
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;	// 不通过gc管理
    }
    case LUA_TUSERDATA: {
      Table *mt = gco2u(o)->metatable;
      gray2black(o);  /* udata are never gray */
      if (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);
  }
}
Exemple #5
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);
  }
}
Exemple #6
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) {
	lu_mem size;
	white2gray(o);
	switch (gch(o)->tt) {
	case LUA_TSHRSTR:
	case LUA_TLNGSTR: {
		size = sizestring(gco2ts(o));
		break;  /* nothing else to mark; make it black */
	}
	case LUA_TUSERDATA: {
		Table *mt = gco2u(o)->metatable;
		markobject(g, mt);
		markobject(g, gco2u(o)->env);
		size = sizeudata(gco2u(o));
		break;
	}
	case LUA_TUPVAL: {
		UpVal *uv = gco2uv(o);
		markvalue(g, uv->v);
		if (uv->v != &uv->u.value)  /* open? */
		return;  /* open upvalues remain gray */
		size = sizeof(UpVal);
		break;
	}
	case LUA_TLCL: {
		gco2lcl(o)->gclist = g->gray;
		g->gray = o;
		return;
	}
	case LUA_TCCL: {
		gco2ccl(o)->gclist = g->gray;
		g->gray = o;
		return;
	}
	case LUA_TTABLE: {
		linktable(gco2t(o), &g->gray);
		return;
	}
	case LUA_TTHREAD: {
		gco2th(o)->gclist = g->gray;
		g->gray = o;
		return;
	}
	case LUA_TPROTO: {
		gco2p(o)->gclist = g->gray;
		g->gray = o;
		return;
	}
	default: lua_assert(0); return;
	}
	gray2black(o);
	g->GCmemtrav += size;
}
Exemple #7
0
void luaF_close (lua_State *L, StkId level) {
  UpVal *uv;
  while (L->openupval != NULL &&
        (uv = L->openupval, uplevel(uv) >= level)) {
    TValue *slot = &uv->u.value;  /* new position for value */
    luaF_unlinkupval(uv);
    setobj(L, slot, uv->v);  /* move value to upvalue slot */
    uv->v = slot;  /* now current value lives here */
    if (!iswhite(uv))
      gray2black(uv);  /* closed upvalues cannot be gray */
    luaC_barrier(L, uv, slot);
  }
}
Exemple #8
0
/*
** check color (and invariants) for an upvalue that was closed,
** i.e., moved into the 'allgc' list
*/
void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
	GCObject *o = obj2gco(uv);
	lua_assert(!isblack(o));  /* open upvalues are never black */
	if (isgray(o)) {
	if (keepinvariant(g)) {
		resetoldbit(o);  /* see MOVE OLD rule */
		gray2black(o);  /* it is being visited now */
		markvalue(g, uv->v);
	}
	else {
		lua_assert(issweepphase(g));
		makewhite(g, o);
	}
	}
}
Exemple #9
0
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);
        }
    }
}
Exemple #10
0
/*
** traverse one gray object, turning it to black.
** Returns `quantity' traversed.
*/
static l_mem propagatemark (global_State *g) {
  GCObject *o = g->gray;
  lua_assert(isgray(o));
  gray2black(o);
  switch (o->gch.tt) {
    case LUA_TTABLE: {
      Table *h = gco2h(o);
      g->gray = h->gclist;
      if (traversetable(g, h))  /* table is weak? */
        black2gray(o);  /* keep it gray */
      return sizeof(Table) + sizeof(TValue) * h->sizearray +
                             sizeof(Node) * sizenode(h);
    }
    case LUA_TFUNCTION: {
      Closure *cl = gco2cl(o);
      g->gray = cl->c.gclist;
      traverseclosure(g, cl);
      return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
                           sizeLclosure(cl->l.nupvalues);
    }
    case LUA_TTHREAD: {
      lua_State *th = gco2th(o);
      g->gray = th->gclist;
      th->gclist = g->grayagain;
      g->grayagain = o;
      black2gray(o);
      traversestack(g, th);
      return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
                                 sizeof(CallInfo) * th->size_ci;
    }
    case LUA_TPROTO: {
      Proto *p = gco2p(o);
      g->gray = p->gclist;
      traverseproto(g, p);
      return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
                             sizeof(Proto *) * p->sizep +
                             sizeof(TValue) * p->sizek + 
                             sizeof(int) * p->sizelineinfo +
                             sizeof(LocVar) * p->sizelocvars +
                             sizeof(TString *) * p->sizeupvalues;
    }
    default: lua_assert(0); return 0;
  }
}
Exemple #11
0
/*
** traverse one gray object, turning it to black (except for threads,
** which are always gray).
*/
static void propagatemark (global_State *g) {
    lu_mem size;
    GCObject *o = g->gray;
    lua_assert(isgray(o));
    gray2black(o);
    switch (o->tt) {
    case LUA_TTABLE: {
        Table *h = gco2t(o);
        g->gray = h->gclist;  /* remove from 'gray' list */
        size = traversetable(g, h);
        break;
    }
    case LUA_TLCL: {
        LClosure *cl = gco2lcl(o);
        g->gray = cl->gclist;  /* remove from 'gray' list */
        size = traverseLclosure(g, cl);
        break;
    }
    case LUA_TCCL: {
        CClosure *cl = gco2ccl(o);
        g->gray = cl->gclist;  /* remove from 'gray' list */
        size = traverseCclosure(g, cl);
        break;
    }
    case LUA_TTHREAD: {
        lua_State *th = gco2th(o);
        g->gray = th->gclist;  /* remove from 'gray' list */
        linkgclist(th, g->grayagain);  /* insert into 'grayagain' list */
        black2gray(o);
        size = traversethread(g, th);
        break;
    }
    case LUA_TPROTO: {
        Proto *p = gco2p(o);
        g->gray = p->gclist;  /* remove from 'gray' list */
        size = traverseproto(g, p);
        break;
    }
    default:
        lua_assert(0);
        return;
    }
    g->GCmemtrav += size;
}