From 6cdf0d8768afb16faaf6c020d6798a4588be2f74 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 28 Jan 1998 14:50:33 -0200 Subject: [PATCH] tables can become full of "emptys" slots, and keep growing without limits. --- bugs | 6 +++++- lstring.c | 33 +++++++++++++++++++++++++-------- ltable.c | 34 +++++++++++++++++----------------- 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 ** lstrlib.c Tue Jan 27 15:27:49 EDT 1998 ->> formats like "%020d" were considered too big (3 algarithms); moreover, +>> formats like "%020d" were considered too big (3 digits); moreover, >> some sistems limit printf to at most 500 chars, so we can limit sizes >> to 2 digits (99). @@ -29,3 +29,7 @@ Tue Jan 27 15:27:49 EDT 1998 Tue Jan 27 17:12:36 EDT 1998 >> "lua_getstring" may create a new string, so should check GC +** lstring.c / ltable.c +Wed Jan 28 14:48:12 EDT 1998 +>> tables can become full of "emptys" slots, and keep growing without limits. + diff --git a/lstring.c b/lstring.c index 070674c7..a6e0ca4e 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.9 1997/12/30 19:15:52 roberto Exp roberto $ +** $Id: lstring.c,v 1.10 1998/01/13 18:06:27 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -50,26 +50,43 @@ static unsigned long hash (char *s, int tag) } +static int newsize (stringtable *tb) +{ + int size = tb->size; + int realuse = 0; + int i; + /* count how many entries are really in use */ + for (i=0; ihash[i] != NULL && tb->hash[i] != &EMPTY) + realuse++; + if (2*(realuse+1) <= size) /* +1 is the new element */ + return size; /* don't need to grow, just rehash to clear EMPTYs */ + else + return luaO_redimension(size); +} + + static void grow (stringtable *tb) { - int newsize = luaO_redimension(tb->size); - TaggedString **newhash = luaM_newvector(newsize, TaggedString *); + + int ns = newsize(tb); + TaggedString **newhash = luaM_newvector(ns, TaggedString *); int i; - for (i=0; inuse = 0; for (i=0; isize; i++) { if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { - int h = tb->hash[i]->hash%newsize; + int h = tb->hash[i]->hash%ns; while (newhash[h]) - h = (h+1)%newsize; + h = (h+1)%ns; newhash[h] = tb->hash[i]; tb->nuse++; } } luaM_free(tb->hash); - tb->size = newsize; + tb->size = ns; tb->hash = newhash; } @@ -86,7 +103,7 @@ static TaggedString *newone (char *buff, int tag, unsigned long h) L->nblocks += gcsizestring(l); } else { - ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)); + ts = luaM_new(TaggedString); ts->u.d.v = buff; ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag; 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 @@ /* -** $Id: ltable.c,v 1.10 1998/01/09 14:44:55 roberto Exp roberto $ +** $Id: ltable.c,v 1.11 1998/01/13 18:06:27 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -121,36 +121,36 @@ Hash *luaH_new (int nhash) } -/* -** Rehash: -** Check if table has deleted slots. It it has, it does not need to -** grow, since rehash will reuse them. -*/ -static int emptyslots (Hash *t) +static int newsize (Hash *t) { + Node *v = t->node; + int size = nhash(t); + int realuse = 0; int i; - for (i=nhash(t)-1; i>=0; i--) { - Node *n = node(t, i); - if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) == LUA_T_NIL) - return 1; + for (i=0; inblocks += gcsize(t->nhash)-gcsize(nold); + L->nblocks += gcsize(nnew)-gcsize(nold); luaM_free(vold); }