aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-01-28 14:50:33 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-01-28 14:50:33 -0200
commit6cdf0d8768afb16faaf6c020d6798a4588be2f74 (patch)
tree44103165d9a04254c9970ad4ede4659c03e84c13
parent07ff251a176f341467f66a853221da81f573b5a1 (diff)
downloadlua-6cdf0d8768afb16faaf6c020d6798a4588be2f74.tar.gz
lua-6cdf0d8768afb16faaf6c020d6798a4588be2f74.tar.bz2
lua-6cdf0d8768afb16faaf6c020d6798a4588be2f74.zip
tables can become full of "emptys" slots, and keep growing without limits.
-rw-r--r--bugs6
-rw-r--r--lstring.c33
-rw-r--r--ltable.c34
3 files changed, 47 insertions, 26 deletions
diff --git a/bugs b/bugs
index ffa4cec1..df6a0ef9 100644
--- a/bugs
+++ b/bugs
@@ -21,7 +21,7 @@ Mon Jan 19 18:17:18 EDT 1998
21 21
22** lstrlib.c 22** lstrlib.c
23Tue Jan 27 15:27:49 EDT 1998 23Tue Jan 27 15:27:49 EDT 1998
24>> formats like "%020d" were considered too big (3 algarithms); moreover, 24>> formats like "%020d" were considered too big (3 digits); moreover,
25>> some sistems limit printf to at most 500 chars, so we can limit sizes 25>> some sistems limit printf to at most 500 chars, so we can limit sizes
26>> to 2 digits (99). 26>> to 2 digits (99).
27 27
@@ -29,3 +29,7 @@ Tue Jan 27 15:27:49 EDT 1998
29Tue Jan 27 17:12:36 EDT 1998 29Tue Jan 27 17:12:36 EDT 1998
30>> "lua_getstring" may create a new string, so should check GC 30>> "lua_getstring" may create a new string, so should check GC
31 31
32** lstring.c / ltable.c
33Wed Jan 28 14:48:12 EDT 1998
34>> tables can become full of "emptys" slots, and keep growing without limits.
35
diff --git a/lstring.c b/lstring.c
index 070674c7..a6e0ca4e 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 1.9 1997/12/30 19:15:52 roberto Exp roberto $ 2** $Id: lstring.c,v 1.10 1998/01/13 18:06:27 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*/
@@ -50,26 +50,43 @@ static unsigned long hash (char *s, int tag)
50} 50}
51 51
52 52
53static int newsize (stringtable *tb)
54{
55 int size = tb->size;
56 int realuse = 0;
57 int i;
58 /* count how many entries are really in use */
59 for (i=0; i<size; i++)
60 if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
61 realuse++;
62 if (2*(realuse+1) <= size) /* +1 is the new element */
63 return size; /* don't need to grow, just rehash to clear EMPTYs */
64 else
65 return luaO_redimension(size);
66}
67
68
53static void grow (stringtable *tb) 69static void grow (stringtable *tb)
54{ 70{
55 int newsize = luaO_redimension(tb->size); 71
56 TaggedString **newhash = luaM_newvector(newsize, TaggedString *); 72 int ns = newsize(tb);
73 TaggedString **newhash = luaM_newvector(ns, TaggedString *);
57 int i; 74 int i;
58 for (i=0; i<newsize; i++) 75 for (i=0; i<ns; i++)
59 newhash[i] = NULL; 76 newhash[i] = NULL;
60 /* rehash */ 77 /* rehash */
61 tb->nuse = 0; 78 tb->nuse = 0;
62 for (i=0; i<tb->size; i++) { 79 for (i=0; i<tb->size; i++) {
63 if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { 80 if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
64 int h = tb->hash[i]->hash%newsize; 81 int h = tb->hash[i]->hash%ns;
65 while (newhash[h]) 82 while (newhash[h])
66 h = (h+1)%newsize; 83 h = (h+1)%ns;
67 newhash[h] = tb->hash[i]; 84 newhash[h] = tb->hash[i];
68 tb->nuse++; 85 tb->nuse++;
69 } 86 }
70 } 87 }
71 luaM_free(tb->hash); 88 luaM_free(tb->hash);
72 tb->size = newsize; 89 tb->size = ns;
73 tb->hash = newhash; 90 tb->hash = newhash;
74} 91}
75 92
@@ -86,7 +103,7 @@ static TaggedString *newone (char *buff, int tag, unsigned long h)
86 L->nblocks += gcsizestring(l); 103 L->nblocks += gcsizestring(l);
87 } 104 }
88 else { 105 else {
89 ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)); 106 ts = luaM_new(TaggedString);
90 ts->u.d.v = buff; 107 ts->u.d.v = buff;
91 ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag; 108 ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
92 ts->constindex = -1; /* tag -> this is a userdata */ 109 ts->constindex = -1; /* tag -> this is a userdata */
diff --git a/ltable.c b/ltable.c
index df5b7a5a..aaf9f16e 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.10 1998/01/09 14:44:55 roberto Exp roberto $ 2** $Id: ltable.c,v 1.11 1998/01/13 18:06:27 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -121,36 +121,36 @@ Hash *luaH_new (int nhash)
121} 121}
122 122
123 123
124/* 124static int newsize (Hash *t)
125** Rehash:
126** Check if table has deleted slots. It it has, it does not need to
127** grow, since rehash will reuse them.
128*/
129static int emptyslots (Hash *t)
130{ 125{
126 Node *v = t->node;
127 int size = nhash(t);
128 int realuse = 0;
131 int i; 129 int i;
132 for (i=nhash(t)-1; i>=0; i--) { 130 for (i=0; i<size; i++) {
133 Node *n = node(t, i); 131 if (ttype(ref(v+i)) != LUA_T_NIL && ttype(val(v+i)) != LUA_T_NIL)
134 if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) == LUA_T_NIL) 132 realuse++;
135 return 1;
136 } 133 }
137 return 0; 134 if (2*(realuse+1) <= size) /* +1 is the new element */
135 return size; /* don't need to grow, just rehash */
136 else
137 return luaO_redimension(size);
138} 138}
139 139
140static void rehash (Hash *t) 140static void rehash (Hash *t)
141{ 141{
142 int nold = nhash(t); 142 int nold = nhash(t);
143 Node *vold = nodevector(t); 143 Node *vold = nodevector(t);
144 int nnew = newsize(t);
144 int i; 145 int i;
145 if (!emptyslots(t)) 146 nodevector(t) = hashnodecreate(nnew);
146 nhash(t) = luaO_redimension(nhash(t)); 147 nhash(t) = nnew;
147 nodevector(t) = hashnodecreate(nhash(t));
148 for (i=0; i<nold; i++) { 148 for (i=0; i<nold; i++) {
149 Node *n = vold+i; 149 Node *n = vold+i;
150 if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) 150 if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
151 *node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */ 151 *node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */
152 } 152 }
153 L->nblocks += gcsize(t->nhash)-gcsize(nold); 153 L->nblocks += gcsize(nnew)-gcsize(nold);
154 luaM_free(vold); 154 luaM_free(vold);
155} 155}
156 156