NAMESPACE_LUA_BEGIN #define GCSTEPSIZE 1024u #define GCSWEEPMAX 40 #define GCSWEEPCOST 10 #define GCFINALIZECOST 100 #define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) #define makewhite(g,x) \ ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) #define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) #define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) #define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) #define KEYWEAK bitmask(KEYWEAKBIT) #define VALUEWEAK bitmask(VALUEWEAKBIT) #define markvalue(g,o) { checkconsistency(o); \ if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } #define markobject(g,t) { if (iswhite(obj2gco(t))) \ reallymarkobject(g, obj2gco(t)); } #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) static void removeentry (Node *n) { lua_assert(ttisnil(gval(n))); if (iscollectable(gkey(n))) setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ }
static void removeentry (Node *n) { lua_assert(ttisnil(gval(n))); if (iscollectable(gkey(n))) setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ }
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 */ }
static void removekey (Node *n) { setnilvalue(gval(n)); /* remove corresponding value ... */ if (iscollectable(gkey(n))) setttype(gkey(n), LUA_TNONE); /* dead key; remove it */ }