Skip to content

Commit

Permalink
long strings are created directly in final position when possible
Browse files Browse the repository at this point in the history
(instead of using an auxiliar buffer to first create the string
and then allocate the final string and copy result there)
  • Loading branch information
roberto-ieru committed Sep 8, 2015
1 parent 502214f commit 4196464
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 58 deletions.
4 changes: 2 additions & 2 deletions ldo.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp roberto $
** $Id: ldo.c,v 2.139 2015/06/18 14:19:52 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -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");
Expand Down
5 changes: 2 additions & 3 deletions lgc.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp roberto $
** $Id: lgc.c,v 2.206 2015/07/13 13:30:03 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -769,12 +769,11 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
*/

/*
** If possible, free concatenation buffer and shrink string table
** If possible, shrink string table
*/
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 */
Expand Down
4 changes: 1 addition & 3 deletions lstate.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp roberto $
** $Id: lstate.c,v 2.129 2015/07/13 13:30:03 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -241,7 +241,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 */
Expand Down Expand Up @@ -310,7 +309,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;
Expand Down
3 changes: 1 addition & 2 deletions lstate.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 2.122 2015/06/01 16:34:37 roberto Exp roberto $
** $Id: lstate.h,v 2.123 2015/07/04 16:33:17 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -131,7 +131,6 @@ 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 */
unsigned int gcfinnum; /* number of finalizers to call in each GC step */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC 'granularity' */
Expand Down
20 changes: 13 additions & 7 deletions lstring.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 2.49 2015/06/01 16:34:37 roberto Exp roberto $
** $Id: lstring.c,v 2.50 2015/06/18 14:20:32 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -119,8 +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,
int tag, unsigned int h) {
static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
TString *ts;
GCObject *o;
size_t totalsize; /* total size of TString object */
Expand All @@ -129,12 +128,18 @@ 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;
}


TString *luaS_createlngstrobj (lua_State *L, size_t l) {
TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
ts->u.lnglen = l;
return ts;
}


void luaS_remove (lua_State *L, TString *ts) {
stringtable *tb = &G(L)->strt;
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
Expand Down Expand Up @@ -166,7 +171,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;
Expand All @@ -185,8 +191,8 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
TString *ts;
if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char))
luaM_toobig(L);
ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
ts->u.lnglen = l;
ts = luaS_createlngstrobj(L, l);
memcpy(getaddrstr(ts), str, l * sizeof(char));
return ts;
}
}
Expand Down
3 changes: 2 additions & 1 deletion lstring.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lstring.h,v 1.58 2015/03/04 13:31:21 roberto Exp roberto $
** $Id: lstring.h,v 1.59 2015/03/25 13:42:19 roberto Exp roberto $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -42,6 +42,7 @@ 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);


#endif
20 changes: 11 additions & 9 deletions lundump.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 2.40 2014/06/19 18:27:20 roberto Exp roberto $
** $Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp roberto $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -32,7 +32,6 @@
typedef struct {
lua_State *L;
ZIO *Z;
Mbuffer *b;
const char *name;
} LoadState;

Expand Down Expand Up @@ -92,10 +91,15 @@ static TString *LoadString (LoadState *S) {
LoadVar(S, size);
if (size == 0)
return NULL;
else {
char *s = luaZ_openspace(S->L, S->b, --size);
LoadVector(S, s, size);
return luaS_newlstr(S->L, s, size);
else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
char buff[LUAI_MAXSHORTLEN];
LoadVector(S, buff, size);
return luaS_newlstr(S->L, buff, size);
}
else { /* long string */
TString *ts = luaS_createlngstrobj(S->L, size);
LoadVector(S, getaddrstr(ts), size); /* load directly in final place */
return ts;
}
}

Expand Down Expand Up @@ -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 == '=')
Expand All @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions lundump.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lundump.h,v 1.43 2014/04/15 14:28:20 roberto Exp roberto $
** $Id: lundump.h,v 1.44 2014/06/19 18:27:20 roberto Exp roberto $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
Expand All @@ -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,
Expand Down
41 changes: 26 additions & 15 deletions lvm.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.249 2015/08/03 19:50:49 roberto Exp roberto $
** $Id: lvm.c,v 2.250 2015/08/03 20:40:26 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -445,6 +445,17 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {

#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)

/* copy strings in stack from top - n up to top - 1 to buffer */
static void copy2buff (StkId top, int n, char *buff) {
size_t tl = 0; /* size already copied */
do {
size_t l = vslen(top - n); /* length of string being copied */
memcpy(buff + tl, svalue(top - n), l * sizeof(char));
tl += l;
} while (--n > 0);
}


/*
** Main operation for concatenation: concat 'total' values in the stack,
** from 'L->top - total' up to 'L->top - 1'.
Expand All @@ -464,24 +475,24 @@ 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;
int i;
/* collect total length */
for (i = 1; i < total && tostring(L, top-i-1); i++) {
size_t l = vslen(top - i - 1);
TString *ts;
/* collect total length and number of strings */
for (n = 1; n < total && tostring(L, top - n - 1); n++) {
size_t l = vslen(top - n - 1);
if (l >= (MAX_SIZE/sizeof(char)) - tl)
luaG_runerror(L, "string length overflow");
tl += l;
}
buffer = luaZ_openspace(L, &G(L)->buff, 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 (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
char buff[LUAI_MAXSHORTLEN];
copy2buff(top, n, buff); /* copy strings to buffer */
ts = luaS_newlstr(L, buff, tl);
}
else { /* long string; copy strings directly to final result */
ts = luaS_createlngstrobj(L, tl);
copy2buff(top, n, getaddrstr(ts));
}
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 */
Expand Down
12 changes: 1 addition & 11 deletions lzio.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lzio.c,v 1.35 2012/05/14 13:34:18 roberto Exp roberto $
** $Id: lzio.c,v 1.36 2014/11/02 19:19:04 roberto Exp roberto $
** Buffered streams
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -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;
}


3 changes: 1 addition & 2 deletions lzio.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
** $Id: lzio.h,v 1.29 2014/12/19 13:45:40 roberto Exp roberto $
** $Id: lzio.h,v 1.30 2014/12/19 17:26:14 roberto Exp roberto $
** Buffered streams
** See Copyright Notice in lua.h
*/
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 4196464

Please sign in to comment.