From 4343420d4d559a7d4cdacdbc1fd61552dcf59f04 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 4 Oct 1999 15:51:04 -0200 Subject: simplified version of `gc' tag method (only for userdata now). --- lstring.c | 142 ++++++++++++++------------------------------------------------ 1 file changed, 31 insertions(+), 111 deletions(-) (limited to 'lstring.c') diff --git a/lstring.c b/lstring.c index 13a123e3..633fbcd4 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.20 1999/08/16 20:52:00 roberto Exp roberto $ +** $Id: lstring.c,v 1.21 1999/09/28 12:27:06 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -14,17 +14,13 @@ #include "lua.h" -#define NUM_HASHSTR 31 -#define NUM_HASHUDATA 31 -#define NUM_HASHS (NUM_HASHSTR+NUM_HASHUDATA) - #define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */ -static TaggedString EMPTY = {{NULL, 2}, 0L, 0, - {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; +TaggedString luaS_EMPTY = {NULL, MAX_INT, 0L, 0, + {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; @@ -49,6 +45,16 @@ void luaS_init (void) { } +void luaS_freeall (void) { + int i; + for (i=0; istring_root[i].hash != init_hash) + luaM_free(L->string_root[i].hash); + } + luaM_free(L->string_root); +} + + static unsigned long hash_s (const char *s, long l) { unsigned long h = 0; /* seed */ while (l--) @@ -57,12 +63,12 @@ static unsigned long hash_s (const char *s, long l) { } -static int newsize (stringtable *tb) { +static int newsize (const stringtable *tb) { int realuse = 0; int i; /* count how many entries are really in use */ for (i=0; isize; i++) { - if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) + if (tb->hash[i] != NULL && tb->hash[i] != &luaS_EMPTY) realuse++; } return luaO_redimension(realuse*2); @@ -78,7 +84,7 @@ static void grow (stringtable *tb) { /* rehash */ tb->nuse = 0; for (i=0; isize; i++) { - if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { + if (tb->hash[i] != NULL && tb->hash[i] != &luaS_EMPTY) { unsigned long h = tb->hash[i]->hash; int h1 = h%ns; while (newhash[h1]) { @@ -103,8 +109,8 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) { ts->u.s.len = l; ts->constindex = 0; L->nblocks += gcsizestring(l); - ts->head.marked = 0; - ts->head.next = (GCnode *)ts; /* signal it is in no list */ + ts->marked = 0; + ts->next = ts; /* signal it is in no list */ ts->hash = h; return ts; } @@ -115,8 +121,8 @@ static TaggedString *newone_u (void *buff, int tag, unsigned long h) { ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; ts->constindex = -1; /* tag -> this is a userdata */ L->nblocks++; - ts->head.marked = 0; - ts->head.next = (GCnode *)ts; /* signal it is in no list */ + ts->marked = 0; + ts->next = ts; /* signal it is in no list */ ts->hash = h; return ts; } @@ -144,7 +150,7 @@ static TaggedString *insert_s (const char *str, long l, stringtable *tb) { int j = -1; /* last empty place found (or -1) */ int h1 = h%size; while ((ts = tb->hash[h1]) != NULL) { - if (ts == &EMPTY) + if (ts == &luaS_EMPTY) j = h1; else if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) return ts; @@ -168,7 +174,7 @@ static TaggedString *insert_u (void *buff, int tag, stringtable *tb) { int j = -1; int h1 = h%size; while ((ts = tb->hash[h1]) != NULL) { - if (ts == &EMPTY) + if (ts == &luaS_EMPTY) j = h1; else if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v) return ts; @@ -200,115 +206,29 @@ TaggedString *luaS_new (const char *str) { TaggedString *luaS_newfixedstring (const char *str) { TaggedString *ts = luaS_new(str); - if (ts->head.marked == 0) - ts->head.marked = 2; /* avoid GC */ + if (ts->marked == 0) ts->marked = 2; /* avoid GC */ return ts; } -void luaS_free (TaggedString *l) { - while (l) { - TaggedString *next = (TaggedString *)l->head.next; - L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); - luaM_free(l); - l = next; - } -} - - -/* -** Garbage collection functions. -*/ - -static void remove_from_list (GCnode *l) { - while (l) { - GCnode *next = l->next; - while (next && !next->marked) - next = l->next = next->next; - l = next; - } -} - - -TaggedString *luaS_collector (void) { - TaggedString *frees = NULL; - int i; - remove_from_list(&(L->rootglobal)); - for (i=0; istring_root[i]; - int j; - for (j=0; jsize; j++) { - TaggedString *t = tb->hash[j]; - if (t == NULL) continue; - if (t->head.marked == 1) - t->head.marked = 0; - else if (!t->head.marked) { - t->head.next = (GCnode *)frees; - frees = t; - tb->hash[j] = ∅ - } - } - } - return frees; -} - - -TaggedString *luaS_collectudata (void) { - TaggedString *frees = NULL; - int i; - L->rootglobal.next = NULL; /* empty list of globals */ - for (i=NUM_HASHSTR; istring_root[i]; - int j; - for (j=0; jsize; j++) { - TaggedString *t = tb->hash[j]; - if (t == NULL || t == &EMPTY) - continue; - LUA_ASSERT(t->constindex == -1, "must be userdata"); - t->head.next = (GCnode *)frees; - frees = t; - tb->hash[j] = ∅ - } - } - return frees; -} - - -void luaS_freeall (void) { - int i; - for (i=0; istring_root[i]; - int j; - for (j=0; jsize; j++) { - TaggedString *t = tb->hash[j]; - if (t != &EMPTY) luaM_free(t); - } - if (tb->hash != init_hash) luaM_free(tb->hash); - } - luaM_free(L->string_root); +void luaS_free (TaggedString *t) { + L->nblocks -= (t->constindex == -1) ? 1 : gcsizestring(t->u.s.len); + luaM_free(t); } -void luaS_rawsetglobal (TaggedString *ts, TObject *newval) { +void luaS_rawsetglobal (TaggedString *ts, const TObject *newval) { ts->u.s.globalval = *newval; - if (ts->head.next == (GCnode *)ts) { /* is not in list? */ - ts->head.next = L->rootglobal.next; - L->rootglobal.next = (GCnode *)ts; + if (ts->next == ts) { /* is not in list? */ + ts->next = L->rootglobal; + L->rootglobal = ts; } } -const char *luaS_travsymbol (int (*fn)(TObject *)) { - TaggedString *g; - for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) - if (fn(&g->u.s.globalval)) - return g->str; - return NULL; -} - - int luaS_globaldefined (const char *name) { TaggedString *ts = luaS_new(name); return ts->u.s.globalval.ttype != LUA_T_NIL; } + -- cgit v1.2.3-55-g6feb