summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-09-08 12:41:05 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-09-08 12:41:05 -0300
commit41964648eea1427d53934b886abb68cc8457b019 (patch)
treeb0388dfebe6614d5d49306193faf78f8b9e1a6a1
parent502214f8a551cd01d94677f98a40aa51531ef71d (diff)
downloadlua-41964648eea1427d53934b886abb68cc8457b019.tar.gz
lua-41964648eea1427d53934b886abb68cc8457b019.tar.bz2
lua-41964648eea1427d53934b886abb68cc8457b019.zip
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)
-rw-r--r--ldo.c4
-rw-r--r--lgc.c5
-rw-r--r--lstate.c4
-rw-r--r--lstate.h3
-rw-r--r--lstring.c20
-rw-r--r--lstring.h3
-rw-r--r--lundump.c20
-rw-r--r--lundump.h5
-rw-r--r--lvm.c41
-rw-r--r--lzio.c12
-rw-r--r--lzio.h3
11 files changed, 62 insertions, 58 deletions
diff --git a/ldo.c b/ldo.c
index 155ecf76..0606b59d 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp roberto $ 2** $Id: ldo.c,v 2.139 2015/06/18 14:19:52 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -684,7 +684,7 @@ static void f_parser (lua_State *L, void *ud) {
684 int c = zgetc(p->z); /* read first character */ 684 int c = zgetc(p->z); /* read first character */
685 if (c == LUA_SIGNATURE[0]) { 685 if (c == LUA_SIGNATURE[0]) {
686 checkmode(L, p->mode, "binary"); 686 checkmode(L, p->mode, "binary");
687 cl = luaU_undump(L, p->z, &p->buff, p->name); 687 cl = luaU_undump(L, p->z, p->name);
688 } 688 }
689 else { 689 else {
690 checkmode(L, p->mode, "text"); 690 checkmode(L, p->mode, "text");
diff --git a/lgc.c b/lgc.c
index 22d36aed..924445fa 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp roberto $ 2** $Id: lgc.c,v 2.206 2015/07/13 13:30:03 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -769,12 +769,11 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
769*/ 769*/
770 770
771/* 771/*
772** If possible, free concatenation buffer and shrink string table 772** If possible, shrink string table
773*/ 773*/
774static void checkSizes (lua_State *L, global_State *g) { 774static void checkSizes (lua_State *L, global_State *g) {
775 if (g->gckind != KGC_EMERGENCY) { 775 if (g->gckind != KGC_EMERGENCY) {
776 l_mem olddebt = g->GCdebt; 776 l_mem olddebt = g->GCdebt;
777 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
778 if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ 777 if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
779 luaS_resize(L, g->strt.size / 2); /* shrink it a little */ 778 luaS_resize(L, g->strt.size / 2); /* shrink it a little */
780 g->GCestimate += g->GCdebt - olddebt; /* update estimate */ 779 g->GCestimate += g->GCdebt - olddebt; /* update estimate */
diff --git a/lstate.c b/lstate.c
index d1679aaf..576485dc 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.128 2015/03/04 13:31:21 roberto Exp roberto $ 2** $Id: lstate.c,v 2.129 2015/07/13 13:30:03 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -241,7 +241,6 @@ static void close_state (lua_State *L) {
241 if (g->version) /* closing a fully built state? */ 241 if (g->version) /* closing a fully built state? */
242 luai_userstateclose(L); 242 luai_userstateclose(L);
243 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 243 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
244 luaZ_freebuffer(L, &g->buff);
245 freestack(L); 244 freestack(L);
246 lua_assert(gettotalbytes(g) == sizeof(LG)); 245 lua_assert(gettotalbytes(g) == sizeof(LG));
247 (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 246 (*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) {
310 g->strt.size = g->strt.nuse = 0; 309 g->strt.size = g->strt.nuse = 0;
311 g->strt.hash = NULL; 310 g->strt.hash = NULL;
312 setnilvalue(&g->l_registry); 311 setnilvalue(&g->l_registry);
313 luaZ_initbuffer(L, &g->buff);
314 g->panic = NULL; 312 g->panic = NULL;
315 g->version = NULL; 313 g->version = NULL;
316 g->gcstate = GCSpause; 314 g->gcstate = GCSpause;
diff --git a/lstate.h b/lstate.h
index aad379fd..61dd99f9 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.122 2015/06/01 16:34:37 roberto Exp roberto $ 2** $Id: lstate.h,v 2.123 2015/07/04 16:33:17 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -131,7 +131,6 @@ typedef struct global_State {
131 GCObject *tobefnz; /* list of userdata to be GC */ 131 GCObject *tobefnz; /* list of userdata to be GC */
132 GCObject *fixedgc; /* list of objects not to be collected */ 132 GCObject *fixedgc; /* list of objects not to be collected */
133 struct lua_State *twups; /* list of threads with open upvalues */ 133 struct lua_State *twups; /* list of threads with open upvalues */
134 Mbuffer buff; /* temporary buffer for string concatenation */
135 unsigned int gcfinnum; /* number of finalizers to call in each GC step */ 134 unsigned int gcfinnum; /* number of finalizers to call in each GC step */
136 int gcpause; /* size of pause between successive GCs */ 135 int gcpause; /* size of pause between successive GCs */
137 int gcstepmul; /* GC 'granularity' */ 136 int gcstepmul; /* GC 'granularity' */
diff --git a/lstring.c b/lstring.c
index c53325d0..588ee546 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.49 2015/06/01 16:34:37 roberto Exp roberto $ 2** $Id: lstring.c,v 2.50 2015/06/18 14:20:32 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -119,8 +119,7 @@ void luaS_init (lua_State *L) {
119/* 119/*
120** creates a new string object 120** creates a new string object
121*/ 121*/
122static TString *createstrobj (lua_State *L, const char *str, size_t l, 122static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
123 int tag, unsigned int h) {
124 TString *ts; 123 TString *ts;
125 GCObject *o; 124 GCObject *o;
126 size_t totalsize; /* total size of TString object */ 125 size_t totalsize; /* total size of TString object */
@@ -129,12 +128,18 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
129 ts = gco2ts(o); 128 ts = gco2ts(o);
130 ts->hash = h; 129 ts->hash = h;
131 ts->extra = 0; 130 ts->extra = 0;
132 memcpy(getaddrstr(ts), str, l * sizeof(char));
133 getaddrstr(ts)[l] = '\0'; /* ending 0 */ 131 getaddrstr(ts)[l] = '\0'; /* ending 0 */
134 return ts; 132 return ts;
135} 133}
136 134
137 135
136TString *luaS_createlngstrobj (lua_State *L, size_t l) {
137 TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
138 ts->u.lnglen = l;
139 return ts;
140}
141
142
138void luaS_remove (lua_State *L, TString *ts) { 143void luaS_remove (lua_State *L, TString *ts) {
139 stringtable *tb = &G(L)->strt; 144 stringtable *tb = &G(L)->strt;
140 TString **p = &tb->hash[lmod(ts->hash, tb->size)]; 145 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) {
166 luaS_resize(L, g->strt.size * 2); 171 luaS_resize(L, g->strt.size * 2);
167 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ 172 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
168 } 173 }
169 ts = createstrobj(L, str, l, LUA_TSHRSTR, h); 174 ts = createstrobj(L, l, LUA_TSHRSTR, h);
175 memcpy(getaddrstr(ts), str, l * sizeof(char));
170 ts->shrlen = cast_byte(l); 176 ts->shrlen = cast_byte(l);
171 ts->u.hnext = *list; 177 ts->u.hnext = *list;
172 *list = ts; 178 *list = ts;
@@ -185,8 +191,8 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
185 TString *ts; 191 TString *ts;
186 if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char)) 192 if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char))
187 luaM_toobig(L); 193 luaM_toobig(L);
188 ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); 194 ts = luaS_createlngstrobj(L, l);
189 ts->u.lnglen = l; 195 memcpy(getaddrstr(ts), str, l * sizeof(char));
190 return ts; 196 return ts;
191 } 197 }
192} 198}
diff --git a/lstring.h b/lstring.h
index cba3cb28..0d8e089c 100644
--- a/lstring.h
+++ b/lstring.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.h,v 1.58 2015/03/04 13:31:21 roberto Exp roberto $ 2** $Id: lstring.h,v 1.59 2015/03/25 13:42:19 roberto Exp roberto $
3** String table (keep all strings handled by Lua) 3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -42,6 +42,7 @@ LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
42LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 42LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
43LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 43LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
44LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 44LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
45LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
45 46
46 47
47#endif 48#endif
diff --git a/lundump.c b/lundump.c
index 039e4a0f..50c9f0fe 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 2.40 2014/06/19 18:27:20 roberto Exp roberto $ 2** $Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp roberto $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -32,7 +32,6 @@
32typedef struct { 32typedef struct {
33 lua_State *L; 33 lua_State *L;
34 ZIO *Z; 34 ZIO *Z;
35 Mbuffer *b;
36 const char *name; 35 const char *name;
37} LoadState; 36} LoadState;
38 37
@@ -92,10 +91,15 @@ static TString *LoadString (LoadState *S) {
92 LoadVar(S, size); 91 LoadVar(S, size);
93 if (size == 0) 92 if (size == 0)
94 return NULL; 93 return NULL;
95 else { 94 else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */
96 char *s = luaZ_openspace(S->L, S->b, --size); 95 char buff[LUAI_MAXSHORTLEN];
97 LoadVector(S, s, size); 96 LoadVector(S, buff, size);
98 return luaS_newlstr(S->L, s, size); 97 return luaS_newlstr(S->L, buff, size);
98 }
99 else { /* long string */
100 TString *ts = luaS_createlngstrobj(S->L, size);
101 LoadVector(S, getaddrstr(ts), size); /* load directly in final place */
102 return ts;
99 } 103 }
100} 104}
101 105
@@ -251,8 +255,7 @@ static void checkHeader (LoadState *S) {
251/* 255/*
252** load precompiled chunk 256** load precompiled chunk
253*/ 257*/
254LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, 258LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
255 const char *name) {
256 LoadState S; 259 LoadState S;
257 LClosure *cl; 260 LClosure *cl;
258 if (*name == '@' || *name == '=') 261 if (*name == '@' || *name == '=')
@@ -263,7 +266,6 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
263 S.name = name; 266 S.name = name;
264 S.L = L; 267 S.L = L;
265 S.Z = Z; 268 S.Z = Z;
266 S.b = buff;
267 checkHeader(&S); 269 checkHeader(&S);
268 cl = luaF_newLclosure(L, LoadByte(&S)); 270 cl = luaF_newLclosure(L, LoadByte(&S));
269 setclLvalue(L, L->top, cl); 271 setclLvalue(L, L->top, cl);
diff --git a/lundump.h b/lundump.h
index 45194532..bc9f99a2 100644
--- a/lundump.h
+++ b/lundump.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.h,v 1.43 2014/04/15 14:28:20 roberto Exp roberto $ 2** $Id: lundump.h,v 1.44 2014/06/19 18:27:20 roberto Exp roberto $
3** load precompiled Lua chunks 3** load precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,8 +23,7 @@
23#define LUAC_FORMAT 0 /* this is the official format */ 23#define LUAC_FORMAT 0 /* this is the official format */
24 24
25/* load one chunk; from lundump.c */ 25/* load one chunk; from lundump.c */
26LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, 26LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
27 const char* name);
28 27
29/* dump one chunk; from ldump.c */ 28/* dump one chunk; from ldump.c */
30LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 29LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
diff --git a/lvm.c b/lvm.c
index 6a6710b3..59f36e3a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.249 2015/08/03 19:50:49 roberto Exp roberto $ 2** $Id: lvm.c,v 2.250 2015/08/03 20:40:26 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -445,6 +445,17 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
445 445
446#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) 446#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
447 447
448/* copy strings in stack from top - n up to top - 1 to buffer */
449static void copy2buff (StkId top, int n, char *buff) {
450 size_t tl = 0; /* size already copied */
451 do {
452 size_t l = vslen(top - n); /* length of string being copied */
453 memcpy(buff + tl, svalue(top - n), l * sizeof(char));
454 tl += l;
455 } while (--n > 0);
456}
457
458
448/* 459/*
449** Main operation for concatenation: concat 'total' values in the stack, 460** Main operation for concatenation: concat 'total' values in the stack,
450** from 'L->top - total' up to 'L->top - 1'. 461** from 'L->top - total' up to 'L->top - 1'.
@@ -464,24 +475,24 @@ void luaV_concat (lua_State *L, int total) {
464 else { 475 else {
465 /* at least two non-empty string values; get as many as possible */ 476 /* at least two non-empty string values; get as many as possible */
466 size_t tl = vslen(top - 1); 477 size_t tl = vslen(top - 1);
467 char *buffer; 478 TString *ts;
468 int i; 479 /* collect total length and number of strings */
469 /* collect total length */ 480 for (n = 1; n < total && tostring(L, top - n - 1); n++) {
470 for (i = 1; i < total && tostring(L, top-i-1); i++) { 481 size_t l = vslen(top - n - 1);
471 size_t l = vslen(top - i - 1);
472 if (l >= (MAX_SIZE/sizeof(char)) - tl) 482 if (l >= (MAX_SIZE/sizeof(char)) - tl)
473 luaG_runerror(L, "string length overflow"); 483 luaG_runerror(L, "string length overflow");
474 tl += l; 484 tl += l;
475 } 485 }
476 buffer = luaZ_openspace(L, &G(L)->buff, tl); 486 if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
477 tl = 0; 487 char buff[LUAI_MAXSHORTLEN];
478 n = i; 488 copy2buff(top, n, buff); /* copy strings to buffer */
479 do { /* copy all strings to buffer */ 489 ts = luaS_newlstr(L, buff, tl);
480 size_t l = vslen(top - i); 490 }
481 memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); 491 else { /* long string; copy strings directly to final result */
482 tl += l; 492 ts = luaS_createlngstrobj(L, tl);
483 } while (--i > 0); 493 copy2buff(top, n, getaddrstr(ts));
484 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); /* create result */ 494 }
495 setsvalue2s(L, top - n, ts); /* create result */
485 } 496 }
486 total -= n-1; /* got 'n' strings to create 1 new */ 497 total -= n-1; /* got 'n' strings to create 1 new */
487 L->top -= n-1; /* popped 'n' strings and pushed one */ 498 L->top -= n-1; /* popped 'n' strings and pushed one */
diff --git a/lzio.c b/lzio.c
index 63ade652..eb6151a0 100644
--- a/lzio.c
+++ b/lzio.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lzio.c,v 1.35 2012/05/14 13:34:18 roberto Exp roberto $ 2** $Id: lzio.c,v 1.36 2014/11/02 19:19:04 roberto Exp roberto $
3** Buffered streams 3** Buffered streams
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -66,13 +66,3 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) {
66 return 0; 66 return 0;
67} 67}
68 68
69/* ------------------------------------------------------------------------ */
70char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
71 if (n > buff->buffsize) {
72 if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
73 luaZ_resizebuffer(L, buff, n);
74 }
75 return buff->buffer;
76}
77
78
diff --git a/lzio.h b/lzio.h
index 8a0c8171..fb310b99 100644
--- a/lzio.h
+++ b/lzio.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lzio.h,v 1.29 2014/12/19 13:45:40 roberto Exp roberto $ 2** $Id: lzio.h,v 1.30 2014/12/19 17:26:14 roberto Exp roberto $
3** Buffered streams 3** Buffered streams
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -44,7 +44,6 @@ typedef struct Mbuffer {
44#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 44#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
45 45
46 46
47LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
48LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 47LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
49 void *data); 48 void *data);
50LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 49LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */