Пример #1
0
static void freeobj (lua_State *L, GCObject *o) {
	switch (gch(o)->tt) {
	case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
	case LUA_TLCL: {
		luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));
		break;
	}
	case LUA_TCCL: {
		luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
		break;
	}
	case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
	case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
	case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
	case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
	case LUA_TSHRSTR:
		G(L)->strt.nuse--;
		/* go through */
	case LUA_TLNGSTR: {
		luaM_freemem(L, o, sizestring(gco2ts(o)));
		break;
	}
	default: lua_assert(0);
	}
}
Пример #2
0
static void freeobj (lua_State *L, GCObject *o) {
  switch (o->tt) {
    case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
    case LUA_TLCL: {
      freeLclosure(L, gco2lcl(o));
      break;
    }
    case LUA_TCCL: {
      luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
      break;
    }
    case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
    case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
    case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
    case LUA_TSHRSTR:
      luaS_remove(L, gco2ts(o));  /* remove it from hash table */
      luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
      break;
    case LUA_TLNGSTR: {
      luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
      break;
    }
    default: lua_assert(0);
  }
}
Пример #3
0
Proto *luaF_newproto (lua_State *L) {
  GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
  Proto *f = gco2p(o);
  f->k = NULL;
  f->sizek = 0;
  f->p = NULL;
  f->sizep = 0;
  f->code = NULL;
  f->cache = NULL;
  f->cachemiss = 0;
  f->sizecode = 0;
  f->lineinfo = NULL;
  f->sizelineinfo = 0;
  f->abslineinfo = NULL;
  f->sizeabslineinfo = 0;
  f->upvalues = NULL;
  f->sizeupvalues = 0;
  f->numparams = 0;
  f->is_vararg = 0;
  f->maxstacksize = 0;
  f->locvars = NULL;
  f->sizelocvars = 0;
  f->linedefined = 0;
  f->lastlinedefined = 0;
  f->source = NULL;
  return f;
}
Пример #4
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;
  }
}
Пример #5
0
Proto *luaF_newproto (lua_State *L, SharedProto *sp) {
  GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
  Proto *f = gco2p(o);
  f->sp = NULL;
  f->k = NULL;
  f->p = NULL;
  f->cache = NULL;
  if (sp == NULL) {
    sp = luaM_new(L, SharedProto);
    sp->l_G = G(L);
    sp->sizek = 0;
    sp->sizep = 0;
    sp->code = NULL;
    sp->sizecode = 0;
    sp->lineinfo = NULL;
    sp->sizelineinfo = 0;
    sp->upvalues = NULL;
    sp->sizeupvalues = 0;
    sp->numparams = 0;
    sp->is_vararg = 0;
    sp->maxstacksize = 0;
    sp->locvars = NULL;
    sp->sizelocvars = 0;
    sp->linedefined = 0;
    sp->lastlinedefined = 0;
    sp->source = NULL;
  }
  f->sp = sp;
  return f;
}
Пример #6
0
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);
    }
}
Пример #7
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;
}
Пример #8
0
Файл: lgc.c Проект: zapline/zlib
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);
  }
}
Пример #9
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;
    }
}
Пример #10
0
static void freeobj (lua_State *L, GCObject *o) {
    global_State *g = G(L);
    lua_assert(is_robj(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: {
        const Udata *udata = rawgco2u(o);
        const TValue *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 */
        }
        luaM_freemem(L, o, sizeudata(gco2u(o)));
        break;
    }
    default:
        lua_assert(0);
    }
}
Пример #11
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;
  }
}
Пример #12
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;
}
Пример #13
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);
  }
}
Пример #14
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);
  }
}
Пример #15
0
static Proto *toproto(lua_State *L, int stackpos)
{
	return gco2p(getobject(L, stackpos)->value.gc);
}
Пример #16
0
Файл: lgc.c Проект: zapline/zlib
static void cleartable (lua_State *L, GCObject *l) {
#else
static void cleartable (GCObject *l) {
#endif /* LUA_REFCOUNT */
  while (l) {
    Table *h = gco2h(l);
    int i = h->sizearray;
    lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
               testbit(h->marked, KEYWEAKBIT));
    if (testbit(h->marked, VALUEWEAKBIT)) {
      while (i--) {
        TValue *o = &h->array[i];
#if LUA_REFCOUNT
        if (iscleared(o, 0)) { /* value was collected? */
          if (iscollectable(o))
            o->value.gc->gch.ref--;
          setnilvalue2n(l, o);  /* remove value */
        }
#else
        if (iscleared(o, 0))  /* value was collected? */
          setnilvalue(o);  /* remove value */
#endif /* LUA_REFCOUNT */
      }
    }
    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))) {
#if LUA_REFCOUNT
        if (iscollectable(gval(n)))
          gval(n)->value.gc->gch.ref--;
        setnilvalue2n(L, gval(n));  /* remove value ... */
#else
        setnilvalue(gval(n));  /* remove value ... */
#endif /* LUA_REFCOUNT */
        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;
    }
#if LUA_WIDESTRING
    case LUA_TWSTRING: {
      G(L)->strt.nuse--;
      luaM_freemem(L, o, sizestring(gco2ts(o)));
      break;
    }
#endif /* LUA_WIDESTRING */
    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));
#if LUA_REFCOUNT
      if (curr->gch.prev)
        curr->gch.prev->gch.next = curr->gch.next;
      if (curr->gch.next)
        curr->gch.next->gch.prev = (GCObject*)p;
#endif /* LUA_REFCOUNT */
      *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;
}