summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lstring.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/lstring.c')
-rw-r--r--apps/plugins/lua/lstring.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/apps/plugins/lua/lstring.c b/apps/plugins/lua/lstring.c
index bf0536e311..6d73f1e9ea 100644
--- a/apps/plugins/lua/lstring.c
+++ b/apps/plugins/lua/lstring.c
@@ -22,30 +22,34 @@
22 22
23 23
24void luaS_resize (lua_State *L, int newsize) { 24void luaS_resize (lua_State *L, int newsize) {
25 GCObject **newhash;
26 stringtable *tb; 25 stringtable *tb;
27 int i; 26 int i;
28 if (G(L)->gcstate == GCSsweepstring)
29 return; /* cannot resize during GC traverse */
30 newhash = luaM_newvector(L, newsize, GCObject *);
31 tb = &G(L)->strt; 27 tb = &G(L)->strt;
32 for (i=0; i<newsize; i++) newhash[i] = NULL; 28 if (luaC_sweepstrgc(L) || newsize == tb->size || is_resizing_strings_gc(L))
29 return; /* cannot resize during GC traverse or doesn't need to be resized */
30 set_resizing_strings_gc(L);
31 if (newsize > tb->size) {
32 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
33 for (i=tb->size; i<newsize; i++) tb->hash[i] = NULL;
34 }
33 /* rehash */ 35 /* rehash */
34 for (i=0; i<tb->size; i++) { 36 for (i=0; i<tb->size; i++) {
35 GCObject *p = tb->hash[i]; 37 GCObject *p = tb->hash[i];
38 tb->hash[i] = NULL;
36 while (p) { /* for each node in the list */ 39 while (p) { /* for each node in the list */
37 GCObject *next = p->gch.next; /* save next */ 40 GCObject *next = p->gch.next; /* save next */
38 unsigned int h = gco2ts(p)->hash; 41 unsigned int h = gco2ts(p)->hash;
39 int h1 = lmod(h, newsize); /* new position */ 42 int h1 = lmod(h, newsize); /* new position */
40 lua_assert(cast_int(h%newsize) == lmod(h, newsize)); 43 lua_assert(cast_int(h%newsize) == lmod(h, newsize));
41 p->gch.next = newhash[h1]; /* chain it */ 44 p->gch.next = tb->hash[h1]; /* chain it */
42 newhash[h1] = p; 45 tb->hash[h1] = p;
43 p = next; 46 p = next;
44 } 47 }
45 } 48 }
46 luaM_freearray(L, tb->hash, tb->size, TString *); 49 if (newsize < tb->size)
50 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
47 tb->size = newsize; 51 tb->size = newsize;
48 tb->hash = newhash; 52 unset_resizing_strings_gc(L);
49} 53}
50 54
51 55
@@ -55,6 +59,9 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
55 stringtable *tb; 59 stringtable *tb;
56 if (l > ((MAX_SIZET - sizeof(TString))/sizeof(char)) - sizeof("")) 60 if (l > ((MAX_SIZET - sizeof(TString))/sizeof(char)) - sizeof(""))
57 luaM_toobig(L); 61 luaM_toobig(L);
62 tb = &G(L)->strt;
63 if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
64 luaS_resize(L, tb->size*2); /* too crowded */
58 ts = cast(TString *, luaM_malloc(L, sizetstring(type, l))); 65 ts = cast(TString *, luaM_malloc(L, sizetstring(type, l)));
59 ts->tsv.len = l; 66 ts->tsv.len = l;
60 ts->tsv.hash = h; 67 ts->tsv.hash = h;
@@ -70,13 +77,10 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
70 memcpy(ts+1, str, l*sizeof(char)); 77 memcpy(ts+1, str, l*sizeof(char));
71 ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 78 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
72 } 79 }
73 tb = &G(L)->strt;
74 h = lmod(h, tb->size); 80 h = lmod(h, tb->size);
75 ts->tsv.next = tb->hash[h]; /* chain new entry */ 81 ts->tsv.next = tb->hash[h]; /* chain new entry */
76 tb->hash[h] = obj2gco(ts); 82 tb->hash[h] = obj2gco(ts);
77 tb->nuse++; 83 tb->nuse++;
78 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
79 luaS_resize(L, tb->size*2); /* too crowded */
80 return ts; 84 return ts;
81} 85}
82 86