remove ssm and add string id

This commit is contained in:
Cloud Wu
2019-06-18 14:09:36 +08:00
committed by 云风
parent 7032f21d18
commit 5d26fb3f18
20 changed files with 183 additions and 1172 deletions

View File

@@ -1050,10 +1050,19 @@ LUA_API void lua_sharestring (lua_State *L, int index) {
luaG_runerror(L, "need a string to share");
TString *ts = (TString *)(str - sizeof(UTString));
if(ts->tt == LUA_TLNGSTR)
makeshared(ts);
else
luaS_fix(G(L), ts);
luaS_share(ts);
}
LUA_API void lua_clonetable(lua_State *L, const void * tp) {
Table *t = cast(Table *, tp);
if (!isshared(t))
luaG_runerror(L, "Not a shared table");
lua_lock(L);
sethvalue(L, L->top, t);
api_incr_top(L);
lua_unlock(L);
}
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {

View File

@@ -1103,7 +1103,7 @@ save(const char *key, const void * proto) {
} else {
lua_pop(L,2);
}
SPIN_UNLOCK(&CC)
return result;
}

View File

@@ -19,6 +19,7 @@
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
@@ -148,22 +149,20 @@ const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
return NULL; /* not found */
}
#define MAKESHARED(x) if ((x) && (x)->tt == LUA_TLNGSTR) makeshared(x)
void luaF_shareproto (Proto *f) {
int i;
if (f == NULL)
return;
makeshared(f);
MAKESHARED(f->source);
luaS_share(f->source);
for (i = 0; i < f->sizek; i++) {
if (ttnov(&f->k[i]) == LUA_TSTRING)
MAKESHARED(tsvalue(&f->k[i]));
luaS_share(tsvalue(&f->k[i]));
}
for (i = 0; i < f->sizeupvalues; i++)
MAKESHARED(f->upvalues[i].name);
luaS_share(f->upvalues[i].name);
for (i = 0; i < f->sizelocvars; i++)
MAKESHARED(f->locvars[i].varname);
luaS_share(f->locvars[i].varname);
for (i = 0; i < f->sizep; i++)
luaF_shareproto(f->p[i]);
}

View File

@@ -193,12 +193,7 @@ 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 */
lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
white2gray(o); /* they will be gray forever */
g->allgc = o->next; /* remove object from 'allgc' list */
o->next = g->fixedgc; /* link it to 'fixedgc' list */
@@ -239,22 +234,22 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
*/
static void reallymarkobject (global_State *g, GCObject *o) {
reentry:
if (isshared(o))
return;
white2gray(o);
switch (o->tt) {
case LUA_TSHRSTR: {
luaS_mark(g, gco2ts(o));
gray2black(o);
g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
break;
}
case LUA_TLNGSTR: {
if (!isshared(o)) {
white2gray(o);
gray2black(o);
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
}
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));
@@ -266,34 +261,23 @@ static void reallymarkobject (global_State *g, GCObject *o) {
break;
}
case LUA_TLCL: {
if (!isshared(o)) {
white2gray(o);
linkgclist(gco2lcl(o), g->gray);
}
linkgclist(gco2lcl(o), g->gray);
break;
}
case LUA_TCCL: {
white2gray(o);
linkgclist(gco2ccl(o), g->gray);
break;
}
case LUA_TTABLE: {
if (!isshared(o)) {
white2gray(o);
linkgclist(gco2t(o), g->gray);
}
linkgclist(gco2t(o), g->gray);
break;
}
case LUA_TTHREAD: {
white2gray(o);
linkgclist(gco2th(o), g->gray);
break;
}
case LUA_TPROTO: {
if (!isshared(o)) {
white2gray(o);
linkgclist(gco2p(o), g->gray);
}
linkgclist(gco2p(o), g->gray);
break;
}
default: lua_assert(0); break;
@@ -724,6 +708,10 @@ 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;
@@ -789,6 +777,19 @@ 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));
@@ -979,6 +980,7 @@ 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);
}
@@ -1024,7 +1026,6 @@ static l_mem atomic (lua_State *L) {
clearvalues(g, g->allweak, origall);
luaS_clearcache(g);
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
luaS_collect(g, 0); /* send short strings set to gc thread */
work += g->GCmemtrav; /* complete counting */
return work; /* estimate of memory marked by 'atomic' */
}
@@ -1050,7 +1051,7 @@ static lu_mem singlestep (lua_State *L) {
global_State *g = G(L);
switch (g->gcstate) {
case GCSpause: {
g->GCmemtrav = 0;
g->GCmemtrav = g->strt.size * sizeof(GCObject*);
restartcollection(g);
g->gcstate = GCSpropagate;
return g->GCmemtrav;
@@ -1082,6 +1083,7 @@ 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;
}

View File

@@ -85,7 +85,6 @@
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
/* short string is always white */
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
@@ -120,15 +119,15 @@
#define luaC_barrier(L,p,v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v)) && !isshared(gcvalue(v))) ? \
luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
#define luaC_barrierback(L,p,v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v)) && !isshared(gcvalue(v))) ? \
luaC_barrierback_(L,p) : cast_void(0))
#define luaC_objbarrier(L,p,o) ( \
(isblack(p) && iswhite(o)) ? \
(isblack(p) && iswhite(o) && !isshared(o)) ? \
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
#define luaC_upvalbarrier(L,uv) ( \

View File

@@ -189,7 +189,7 @@ typedef struct lua_TValue {
#define checkliveness(L,obj) \
lua_longassert(!iscollectable(obj) || \
(righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))
(righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)) || isshared(gcvalue(obj)))))
/* Macros to set values */
@@ -305,9 +305,10 @@ typedef struct TString {
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
lu_byte shrlen; /* length for short strings */
unsigned int hash;
size_t id; /* id for short strings */
union {
size_t lnglen; /* length for long strings */
size_t ref; /* reference count for short strings */
struct TString *hnext; /* linked list for hash table */
} u;
} TString;

View File

@@ -224,7 +224,7 @@ static void close_state (lua_State *L) {
luaC_freeallobjects(L); /* collect all objects */
if (g->version) /* closing a fully built state? */
luai_userstateclose(L);
luaS_collect(g, 1); /* clear short strings */
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
@@ -289,6 +289,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->mainthread = L;
g->gcrunning = 0; /* no GC while building state */
g->GCestimate = 0;
g->strt.size = g->strt.nuse = 0;
g->strt.hash = NULL;
setnilvalue(&g->l_registry);
g->panic = NULL;
g->version = NULL;
@@ -304,9 +306,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->gcfinnum = 0;
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
g->strsave = NULL;
g->strmark = NULL;
g->strfix = NULL;
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */

View File

@@ -130,8 +130,6 @@ typedef struct CallInfo {
#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
#define getoah(st) ((st) & CIST_OAH)
/* SSM (short string map) See lstring.c */
struct ssm_ref;
/*
** 'global state', shared by all threads of this state
@@ -143,6 +141,7 @@ typedef struct global_State {
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
lu_mem GCmemtrav; /* memory traversed by the GC */
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
stringtable strt; /* hash table for strings */
TValue l_registry;
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
@@ -169,9 +168,6 @@ typedef struct global_State {
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
struct ssm_ref *strsave;
struct ssm_ref *strmark;
struct ssm_ref *strfix;
} global_State;

File diff suppressed because it is too large Load Diff

View File

@@ -28,46 +28,24 @@
/*
** equality for short strings, which are always internalized
** equality for short strings, compare id first
*/
#define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
#define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b) || \
( ((a)->id == (b)->id) ? ((a)->id != 0) : ((a)->hash == (b)->hash && luaS_eqshrstr(a,b)) ) )
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts);
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
LUAI_FUNC int luaS_eqshrstr (TString *a, TString *b);
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC void luaS_clearcache (global_State *g);
LUAI_FUNC void luaS_init (lua_State *L);
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
LUAI_FUNC void luaS_share(TString *ts);
#define ENABLE_SHORT_STRING_TABLE
struct ssm_info {
int total;
int longest;
int slots;
int garbage;
size_t size;
size_t garbage_size;
double variance;
};
struct ssm_collect {
void *key;
int n;
int sweep;
};
LUA_API void luaS_initssm();
LUA_API void luaS_exitssm();
LUA_API void luaS_infossm(struct ssm_info *info);
LUA_API int luaS_collectssm(struct ssm_collect *info);
LUAI_FUNC void luaS_mark(global_State *g, TString *s);
LUAI_FUNC void luaS_fix(global_State *g, TString *s);
LUAI_FUNC void luaS_collect(global_State *g, int closed);
#endif

View File

@@ -18,7 +18,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lstring.h"
@@ -596,9 +595,7 @@ static int pmain (lua_State *L) {
int main (int argc, char **argv) {
int status, result;
lua_State *L;
luaS_initssm();
L = luaL_newstate(); /* create state */
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
@@ -610,7 +607,6 @@ int main (int argc, char **argv) {
result = lua_toboolean(L, -1); /* get result */
report(L, status);
lua_close(L);
luaS_exitssm();
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -233,9 +233,11 @@ LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);
LUA_API void (lua_clonefunction) (lua_State *L, const void * fp);
LUA_API void (lua_sharefunction) (lua_State *L, int index);
LUA_API void (lua_sharestring) (lua_State *L, int index);
LUA_API void (lua_clonetable) (lua_State *L, const void * t);
/*
** get functions (Lua -> stack)

View File

@@ -21,7 +21,6 @@
#include "lobject.h"
#include "lstate.h"
#include "lundump.h"
#include "lstring.h"
static void PrintFunction(const Proto* f, int full);
#define luaU_print PrintFunction
@@ -193,7 +192,6 @@ static int pmain(lua_State* L)
int main(int argc, char* argv[])
{
lua_State* L;
luaS_initssm();
int i=doargs(argc,argv);
argc-=i; argv+=i;
if (argc<=0) usage("no input files given");
@@ -204,7 +202,6 @@ int main(int argc, char* argv[])
lua_pushlightuserdata(L,argv);
if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
lua_close(L);
luaS_exitssm();
return EXIT_SUCCESS;
}

View File

@@ -69,7 +69,6 @@ LUA_CLIB_SKYNET = \
lua-stm.c \
lua-debugchannel.c \
lua-datasheet.c \
lua-ssm.c \
lua-sharetable.c \
\

View File

@@ -4,12 +4,9 @@
#include <lauxlib.h>
#include <lualib.h>
#include "lstring.h"
#include "lobject.h"
#include "lapi.h"
#include "lgc.h"
#ifdef ENABLE_SHORT_STRING_TABLE
#ifdef makeshared
static void
mark_shared(lua_State *L) {
@@ -81,12 +78,7 @@ make_matrix(lua_State *L) {
static int
clone_table(lua_State *L) {
Table * t = (Table *)lua_touserdata(L, 1);
if (!isshared(t))
return luaL_error(L, "Not a shared table");
sethvalue(L, L->top, t);
api_incr_top(L);
lua_clonetable(L, lua_touserdata(L, 1));
return 1;
}

View File

@@ -1,78 +0,0 @@
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
#include "lstring.h"
static int
linfo(lua_State *L) {
struct ssm_info info;
memset(&info, 0, sizeof(info));
luaS_infossm(&info);
lua_createtable(L, 0, 5);
lua_pushinteger(L, info.total);
lua_setfield(L, -2, "n");
lua_pushinteger(L, info.longest);
lua_setfield(L, -2, "longest");
lua_pushinteger(L, info.slots);
lua_setfield(L, -2, "slots");
lua_pushinteger(L, info.size);
lua_setfield(L, -2, "size");
lua_pushinteger(L, info.garbage);
lua_setfield(L, -2, "garbage");
lua_pushinteger(L, info.garbage_size);
lua_setfield(L, -2, "garbage_size");
lua_pushnumber(L, info.variance);
lua_setfield(L, -2, "variance");
return 1;
}
static int
lcollect(lua_State *L) {
int loop = lua_toboolean(L, 1);
if (loop) {
int n = 0;
struct ssm_collect info;
while (luaS_collectssm(&info)) {
n+=info.n;
}
lua_pushinteger(L, n);
return 1;
} else {
struct ssm_collect info;
int again = luaS_collectssm(&info);
if (again && lua_istable(L, 2)) {
lua_pushinteger(L, info.n);
lua_setfield(L, 2, "n");
lua_pushinteger(L, info.sweep);
lua_setfield(L, 2, "sweep");
lua_pushlightuserdata(L, info.key);
lua_setfield(L, 2, "key");
}
lua_pushboolean(L, again);
return 1;
}
}
LUAMOD_API int
luaopen_skynet_ssm(lua_State *L) {
luaL_checkversion(L);
luaL_Reg l[] = {
{ "info", linfo },
{ "collect", lcollect },
{ NULL, NULL },
};
luaL_newlib(L,l);
#ifndef ENABLE_SHORT_STRING_TABLE
lua_pushboolean(L, 1);
lua_setfield(L, -2, "disable");
#endif
return 1;
}

View File

@@ -8,8 +8,6 @@ skynet.start(function()
local launcher = assert(skynet.launch("snlua","launcher"))
skynet.name(".launcher", launcher)
skynet.newservice "garbagecollect"
local harbor_id = tonumber(skynet.getenv "harbor" or 0)
if harbor_id == 0 then
assert(standalone == nil)

View File

@@ -1,26 +0,0 @@
local skynet = require "skynet"
local ssm = require "skynet.ssm"
local function ssm_info()
return ssm.info()
end
local function collect()
local info = {}
while true do
-- while ssm.collect(false, info) do
-- skynet.error(string.format("Collect %d strings from %s, sweep %d", info.n, info.key, info.sweep))
-- end
ssm.collect(true)
skynet.sleep(50)
end
end
skynet.start(function()
if ssm.disable then
skynet.error "Short String Map (SSM) Disabled"
skynet.exit()
end
skynet.info_func(ssm_info)
skynet.fork(collect)
end)

View File

@@ -1,29 +0,0 @@
#ifndef LUA_SHORT_STRING_TABLE_H
#define LUA_SHORT_STRING_TABLE_H
#include "lstring.h"
// If you use modified lua, this macro would be defined in lstring.h
#ifndef ENABLE_SHORT_STRING_TABLE
struct ssm_info {
int total;
int longest;
int slots;
size_t size;
double variance;
};
struct ssm_collect {
void *key;
int n;
};
static inline void luaS_initssm();
static inline void luaS_exitssm();
static inline void luaS_infossm(struct ssm_info *info) {}
static inline int luaS_collectssm(struct ssm_collect *info) { return 0; }
#endif
#endif

View File

@@ -3,7 +3,6 @@
#include "skynet_imp.h"
#include "skynet_env.h"
#include "skynet_server.h"
#include "luashrtbl.h"
#include <stdio.h>
#include <stdlib.h>
@@ -126,7 +125,6 @@ main(int argc, char *argv[]) {
return 1;
}
luaS_initssm();
skynet_globalinit();
skynet_env_init();
@@ -162,7 +160,6 @@ main(int argc, char *argv[]) {
skynet_start(&config);
skynet_globalexit();
luaS_exitssm();
return 0;
}