mirror of
https://github.com/lua/lua
synced 2024-12-24 03:16:50 +03:00
long strings are created directly in final position when possible
(instead of using an auxiliar buffer to first create the string and then allocate the final string and copy result there)
This commit is contained in:
parent
502214f8a5
commit
41964648ee
4
ldo.c
4
ldo.c
@ -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
|
||||
*/
|
||||
@ -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");
|
||||
|
5
lgc.c
5
lgc.c
@ -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
|
||||
*/
|
||||
@ -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 */
|
||||
|
4
lstate.c
4
lstate.c
@ -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
|
||||
*/
|
||||
@ -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 */
|
||||
@ -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;
|
||||
|
3
lstate.h
3
lstate.h
@ -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
|
||||
*/
|
||||
@ -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' */
|
||||
|
20
lstring.c
20
lstring.c
@ -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
|
||||
*/
|
||||
@ -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 */
|
||||
@ -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)];
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
@ -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
lundump.c
20
lundump.c
@ -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
|
||||
*/
|
||||
@ -32,7 +32,6 @@
|
||||
typedef struct {
|
||||
lua_State *L;
|
||||
ZIO *Z;
|
||||
Mbuffer *b;
|
||||
const char *name;
|
||||
} LoadState;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
@ -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,
|
||||
|
41
lvm.c
41
lvm.c
@ -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
|
||||
*/
|
||||
@ -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'.
|
||||
@ -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 */
|
||||
|
12
lzio.c
12
lzio.c
@ -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
|
||||
*/
|
||||
@ -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
lzio.h
3
lzio.h
@ -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
|
||||
*/
|
||||
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user