예제 #1
0
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 */
  }
}
예제 #2
0
파일: lgc.c 프로젝트: zapline/zlib
void GCTM (lua_State *L) {
#else
static void GCTM (lua_State *L) {
#endif /* LUA_REFCOUNT */
  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;
#if LUA_REFCOUNT
  udata->uv.prev = (GCObject*)&G(L)->mainthread->next;
#endif /* LUA_REFCOUNT */
  udata->uv.next = g->mainthread->next;  /* return it to `root' list */
#if LUA_REFCOUNT
  if (udata->uv.next)
    udata->uv.next->uv.prev = obj2gco(udata);
#endif /* LUA_REFCOUNT */
  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 */
#if LUA_REFCOUNT
    /* We could be in the middle of a stack set, so call the __gc metamethod on
       one stack level past the current one. */
    L->top++;

	/* we're freeing this object, but fake ref count it, because GCTM actually uses it */
    udata->uv.ref++;

    L->top += 2;
    setobj2s(L, L->top - 2, tm);
    setuvalue(L, L->top - 1, udata);
    luaD_call(L, L->top - 2, 0);
    udata->uv.ref--;
    L->top--;
    setnilvalue2n(L, L->top - 1);
#else
    setobj2s(L, L->top, tm);
    setuvalue(L, L->top+1, udata);
    L->top += 2;
    luaD_call(L, L->top - 2, 0);
#endif /* LUA_REFCOUNT */
    L->allowhook = oldah;  /* restore hooks */
    g->GCthreshold = oldt;  /* restore threshold */
  }
}
예제 #3
0
파일: lgc.c 프로젝트: NicoleRobin/TDR
/*
** 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;
  }
}
예제 #4
0
파일: lregion.c 프로젝트: hogelog/ostacklua
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);
    }
}
예제 #5
0
파일: lregion.c 프로젝트: hogelog/ostacklua
void rstack_reject (lua_State *L, GCObject *src) {
    RStack *rs = rstack(L);
    RObject *robj = rstack_getrobj(rs, src);
    lua_assert(robj && src == robj->body);
    luaC_link(L, src, src->gch.tt);
    switch(src->gch.tt) {
    case LUA_TTABLE:
        luaH_reject(L, gco2h(src));
        break;
    case LUA_TUSERDATA:
        luaS_rejectu(L, rawgco2u(src));
        break;
    // TODO: implement
    default:
        lua_assert(0);
    }
    robj->body = NULL;
}