Skip to content
Permalink
Browse files
luaS_newlstr() with str == NULL
Since longs strings are not interned it's ok to initialize their
contents later. This can elliminate bounce buffers in many cases.
  • Loading branch information
zde committed Sep 4, 2015
1 parent 570b787 commit 7caf974
Show file tree
Hide file tree
Showing 10 changed files with 24 additions and 31 deletions.
@@ -684,7 +684,7 @@ static void f_parser (lua_State *L, void *ud) {
int c = zgetc(p->z); /* read first character */
if (c == LUA_SIGNATURE[0]) {
checkmode(L, p->mode, "binary");
cl = luaU_undump(L, p->z, &p->buff, p->name);
cl = luaU_undump(L, p->z, p->name);
}
else {
checkmode(L, p->mode, "text");
@@ -774,7 +774,6 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
static void checkSizes (lua_State *L, global_State *g) {
if (g->gckind != KGC_EMERGENCY) {
l_mem olddebt = g->GCdebt;
luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
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 */
@@ -237,7 +237,6 @@ static void close_state (lua_State *L) {
if (g->version) /* closing a fully built state? */
luai_userstateclose(L);
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
luaZ_freebuffer(L, &g->buff);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
@@ -306,7 +305,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->strt.size = g->strt.nuse = 0;
g->strt.hash = NULL;
setnilvalue(&g->l_registry);
luaZ_initbuffer(L, &g->buff);
g->panic = NULL;
g->version = NULL;
g->gcstate = GCSpause;
@@ -131,7 +131,7 @@ typedef struct global_State {
GCObject *tobefnz; /* list of userdata to be GC */
GCObject *fixedgc; /* list of objects not to be collected */
struct lua_State *twups; /* list of threads with open upvalues */
Mbuffer buff; /* temporary buffer for string concatenation */
char buff[LUAI_MAXSHORTLEN]; /* temporary buffer for string concatenation */
unsigned int gcfinnum; /* number of finalizers to call in each GC step */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC 'granularity' */
@@ -119,7 +119,7 @@ void luaS_init (lua_State *L) {
/*
** creates a new string object
*/
static TString *createstrobj (lua_State *L, const char *str, size_t l,
static TString *createstrobj (lua_State *L, size_t l,
int tag, unsigned int h) {
TString *ts;
GCObject *o;
@@ -129,7 +129,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
ts = gco2ts(o);
ts->hash = h;
ts->extra = 0;
memcpy(getaddrstr(ts), str, l * sizeof(char));
getaddrstr(ts)[l] = '\0'; /* ending 0 */
return ts;
}
@@ -166,7 +165,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
luaS_resize(L, g->strt.size * 2);
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
}
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
ts = createstrobj(L, l, LUA_TSHRSTR, h);
memcpy(getaddrstr(ts), str, l * sizeof(char));
ts->shrlen = cast_byte(l);
ts->u.hnext = *list;
*list = ts;
@@ -185,7 +185,9 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
TString *ts;
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
luaM_toobig(L);
ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
if (str != NULL)
memcpy(getaddrstr(ts), str, l * sizeof(char));
ts->u.lnglen = l;
return ts;
}
@@ -32,7 +32,6 @@
typedef struct {
lua_State *L;
ZIO *Z;
Mbuffer *b;
const char *name;
} LoadState;

@@ -93,9 +92,14 @@ static TString *LoadString (LoadState *S) {
if (size == 0)
return NULL;
else {
char *s = luaZ_openspace(S->L, S->b, --size);
TString *ts = NULL;
char *s = G(S->L)->buff;
if (--size > LUAI_MAXSHORTLEN)
s = getaddrstr(ts = luaS_newlstr(S->L, NULL, size));
LoadVector(S, s, size);
return luaS_newlstr(S->L, s, size);
if (ts == NULL)
ts = luaS_newlstr(S->L, s, size);
return ts;
}
}

@@ -251,8 +255,7 @@ static void checkHeader (LoadState *S) {
/*
** load precompiled chunk
*/
LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
const char *name) {
LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
LoadState S;
LClosure *cl;
if (*name == '@' || *name == '=')
@@ -263,7 +266,6 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
S.name = name;
S.L = L;
S.Z = Z;
S.b = buff;
checkHeader(&S);
cl = luaF_newLclosure(L, LoadByte(&S));
setclLvalue(L, L->top, cl);
@@ -23,8 +23,7 @@
#define LUAC_FORMAT 0 /* this is the official format */

/* load one chunk; from lundump.c */
LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff,
const char* name);
LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);

/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
@@ -462,7 +462,8 @@ void luaV_concat (lua_State *L, int total) {
else {
/* at least two non-empty string values; get as many as possible */
size_t tl = vslen(top - 1);
char *buffer;
TString *ts = NULL;
char *buffer = G(L)->buff;
int i;
/* collect total length */
for (i = 1; i < total && tostring(L, top-i-1); i++) {
@@ -471,15 +472,18 @@ void luaV_concat (lua_State *L, int total) {
luaG_runerror(L, "string length overflow");
tl += l;
}
buffer = luaZ_openspace(L, &G(L)->buff, tl);
if (tl > LUAI_MAXSHORTLEN)
buffer = getaddrstr(ts = luaS_newlstr(L, NULL, tl));
tl = 0;
n = i;
do { /* copy all strings to buffer */
size_t l = vslen(top - i);
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
tl += l;
} while (--i > 0);
setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); /* create result */
if (ts == NULL)
ts = luaS_newlstr(L, buffer, tl);
setsvalue2s(L, top-n, ts); /* create result */
}
total -= n-1; /* got 'n' strings to create 1 new */
L->top -= n-1; /* popped 'n' strings and pushed one */
@@ -66,13 +66,3 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) {
return 0;
}

/* ------------------------------------------------------------------------ */
char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
if (n > buff->buffsize) {
if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
luaZ_resizebuffer(L, buff, n);
}
return buff->buffer;
}


@@ -44,7 +44,6 @@ typedef struct Mbuffer {
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)


LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
void *data);
LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */

0 comments on commit 7caf974

Please sign in to comment.