mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
rewrite SSM and clonefunction
This commit is contained in:
@@ -193,6 +193,10 @@ void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
|
||||
|
||||
void luaC_fix (lua_State *L, GCObject *o) {
|
||||
global_State *g = G(L);
|
||||
if (o->tt == LUA_TSHRSTR) {
|
||||
luaS_fix(g, gco2ts(o));
|
||||
return;
|
||||
}
|
||||
if (g->allgc != o)
|
||||
return; /* if object is not 1st in 'allgc' list, it is in global short string table */
|
||||
white2gray(o); /* they will be gray forever */
|
||||
@@ -235,20 +239,22 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
|
||||
*/
|
||||
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);
|
||||
luaS_mark(g, gco2ts(o));
|
||||
break;
|
||||
}
|
||||
case LUA_TLNGSTR: {
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
|
||||
if (!isshared(o)) {
|
||||
white2gray(o);
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LUA_TUSERDATA: {
|
||||
TValue uvalue;
|
||||
white2gray(o);
|
||||
markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizeudata(gco2u(o));
|
||||
@@ -260,23 +266,31 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||
break;
|
||||
}
|
||||
case LUA_TLCL: {
|
||||
white2gray(o);
|
||||
linkgclist(gco2lcl(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TCCL: {
|
||||
white2gray(o);
|
||||
linkgclist(gco2ccl(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TTABLE: {
|
||||
linkgclist(gco2t(o), g->gray);
|
||||
if (!isshared(o))
|
||||
white2gray(o);
|
||||
linkgclist(gco2t(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TTHREAD: {
|
||||
white2gray(o);
|
||||
linkgclist(gco2th(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TPROTO: {
|
||||
linkgclist(gco2p(o), g->gray);
|
||||
if (!isshared(o)) {
|
||||
white2gray(o);
|
||||
linkgclist(gco2p(o), g->gray);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: lua_assert(0); break;
|
||||
@@ -471,20 +485,6 @@ static lu_mem traversetable (global_State *g, Table *h) {
|
||||
sizeof(Node) * cast(size_t, allocsizenode(h));
|
||||
}
|
||||
|
||||
static int marksharedproto (global_State *g, SharedProto *f) {
|
||||
int i;
|
||||
if (g != f->l_G)
|
||||
return 0;
|
||||
markobjectN(g, f->source);
|
||||
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
|
||||
markobjectN(g, f->upvalues[i].name);
|
||||
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
|
||||
markobjectN(g, f->locvars[i].varname);
|
||||
return sizeof(Instruction) * f->sizecode +
|
||||
sizeof(int) * f->sizelineinfo +
|
||||
sizeof(LocVar) * f->sizelocvars +
|
||||
sizeof(Upvaldesc) * f->sizeupvalues;
|
||||
}
|
||||
|
||||
/*
|
||||
** Traverse a prototype. (While a prototype is being build, its
|
||||
@@ -492,20 +492,24 @@ static int marksharedproto (global_State *g, SharedProto *f) {
|
||||
** NULL, so the use of 'markobjectN')
|
||||
*/
|
||||
static int traverseproto (global_State *g, Proto *f) {
|
||||
int i,nk,np;
|
||||
if (f->cache && iswhite(f->cache))
|
||||
f->cache = NULL; /* allow cache to be collected */
|
||||
if (f->sp == NULL)
|
||||
return sizeof(Proto);
|
||||
nk = (f->k == f->sp->k && g != f->sp->l_G) ? 0 : f->sp->sizek;
|
||||
np = (f->p == NULL) ? 0 : f->sp->sizep;
|
||||
for (i = 0; i < nk; i++) /* mark literals */
|
||||
int i;
|
||||
if (g != f->l_G)
|
||||
return 0;
|
||||
markobjectN(g, f->source);
|
||||
for (i = 0; i < f->sizek; i++) /* mark literals */
|
||||
markvalue(g, &f->k[i]);
|
||||
for (i = 0; i < np; i++) /* mark nested protos */
|
||||
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
|
||||
markobjectN(g, f->upvalues[i].name);
|
||||
for (i = 0; i < f->sizep; i++) /* mark nested protos */
|
||||
markobjectN(g, f->p[i]);
|
||||
return sizeof(Proto) + sizeof(Proto *) * np +
|
||||
sizeof(TValue) * nk +
|
||||
marksharedproto(g, f->sp);
|
||||
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
|
||||
markobjectN(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -719,10 +723,6 @@ static void freeobj (lua_State *L, GCObject *o) {
|
||||
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;
|
||||
@@ -745,7 +745,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
|
||||
*/
|
||||
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
||||
global_State *g = G(L);
|
||||
int ow = otherwhite(g);
|
||||
int ow = otherwhite(g) | bitmask(SHAREBIT); /* shared object never dead */
|
||||
int white = luaC_white(g); /* current white */
|
||||
while (*p != NULL && count-- > 0) {
|
||||
GCObject *curr = *p;
|
||||
@@ -783,19 +783,6 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
** If possible, shrink string table
|
||||
*/
|
||||
static void checkSizes (lua_State *L, global_State *g) {
|
||||
if (g->gckind != KGC_EMERGENCY) {
|
||||
l_mem olddebt = g->GCdebt;
|
||||
if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
|
||||
luaS_resize(L, g->strt.size / 2); /* shrink it a little */
|
||||
g->GCestimate += g->GCdebt - olddebt; /* update estimate */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GCObject *udata2finalize (global_State *g) {
|
||||
GCObject *o = g->tobefnz; /* get first element */
|
||||
lua_assert(tofinalize(o));
|
||||
@@ -986,7 +973,6 @@ void luaC_freeallobjects (lua_State *L) {
|
||||
sweepwholelist(L, &g->finobj);
|
||||
sweepwholelist(L, &g->allgc);
|
||||
sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
|
||||
lua_assert(g->strt.nuse == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1057,7 +1043,7 @@ static lu_mem singlestep (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
switch (g->gcstate) {
|
||||
case GCSpause: {
|
||||
g->GCmemtrav = g->strt.size * sizeof(GCObject*);
|
||||
g->GCmemtrav = 0;
|
||||
restartcollection(g);
|
||||
g->gcstate = GCSpropagate;
|
||||
return g->GCmemtrav;
|
||||
@@ -1089,7 +1075,6 @@ static lu_mem singlestep (lua_State *L) {
|
||||
}
|
||||
case GCSswpend: { /* finish sweeps */
|
||||
makewhite(g, g->mainthread); /* sweep main thread */
|
||||
checkSizes(L, g);
|
||||
g->gcstate = GCScallfin;
|
||||
return 0;
|
||||
}
|
||||
@@ -1099,6 +1084,7 @@ static lu_mem singlestep (lua_State *L) {
|
||||
return (n * GCFINALIZECOST);
|
||||
}
|
||||
else { /* emergency mode or no more finalizers */
|
||||
luaS_collect(g, 0); /* send short strings set to gc thread */
|
||||
g->gcstate = GCSpause; /* finish collection */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user