浏览代码

collect dead indices in tables

Roberto Ierusalimschy 25 年之前
父节点
当前提交
c542aac0b9
共有 3 个文件被更改,包括 28 次插入3 次删除
  1. 3 1
      lgc.c
  2. 23 1
      ltable.c
  3. 2 1
      ltable.h

+ 3 - 1
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.53 2000/05/30 19:00:31 roberto Exp roberto $
+** $Id: lgc.c,v 1.54 2000/06/05 14:56:18 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -64,6 +64,8 @@ static void tablemark (lua_State *L, Hash *h) {
     for (i=h->size-1; i>=0; i--) {
       Node *n = node(h,i);
       if (ttype(key(n)) != TAG_NIL) {
+        if (ttype(val(n)) == TAG_NIL)
+          luaH_remove(h, key(n));  /* dead element; try to remove it */
         markobject(L, &n->key);
         markobject(L, &n->val);
       }

+ 23 - 1
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.42 2000/05/11 18:57:19 roberto Exp roberto $
+** $Id: ltable.c,v 1.43 2000/05/24 13:54:49 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -121,6 +121,28 @@ int luaH_pos (lua_State *L, const Hash *t, const TObject *key) {
       (int)(((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node));
 }
 
+/*
+** try to remove a key without value from a table. To avoid problems with
+** hash, change `key' for a number with the same hash.
+*/
+void luaH_remove (Hash *t, TObject *key) {
+  /* do not remove numbers */
+  if (ttype(key) != TAG_NUMBER) {
+    /* try to find a number `n' with the same hash as `key' */
+    Node *mp = luaH_mainposition(t, key);
+    int n = mp - &t->node[0];
+    /* make sure `n' is not in `t' */
+    while (luaH_getnum(t, n) != &luaO_nilobject) {
+      if (t->size >= MAX_INT-n)
+        return;  /* give up; (to avoid overflow) */
+      n += t->size;
+    }
+    ttype(key) = TAG_NUMBER;
+    nvalue(key) = n;
+    LUA_ASSERT(L, luaH_mainposition(t, key) == mp, "cannot change hash");
+  }
+}
+
 
 static void setnodevector (lua_State *L, Hash *t, lint32 size) {
   int i;

+ 2 - 1
ltable.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.h,v 1.19 2000/04/25 16:55:09 roberto Exp roberto $
+** $Id: ltable.h,v 1.20 2000/05/08 19:32:53 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -21,6 +21,7 @@ void luaH_free (lua_State *L, Hash *t);
 const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
 const TObject *luaH_getnum (const Hash *t, Number key);
 const TObject *luaH_getstr (const Hash *t, TString *key);
+void luaH_remove (Hash *t, TObject *key);
 void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val);
 int luaH_pos (lua_State *L, const Hash *t, const TObject *r);
 void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val);