diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-07 17:21:34 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-07 17:21:34 -0300 |
| commit | d9e61e8ceafe8c3f6ad936979719ca7c446ce228 (patch) | |
| tree | 0808ada3d7b7219022b9002503894c76c7253df6 | |
| parent | 397905ef8694ec716a51acebc993bb625340d388 (diff) | |
| download | lua-d9e61e8ceafe8c3f6ad936979719ca7c446ce228.tar.gz lua-d9e61e8ceafe8c3f6ad936979719ca7c446ce228.tar.bz2 lua-d9e61e8ceafe8c3f6ad936979719ca7c446ce228.zip | |
new algorithm for traversing in GC to avoid deep recursion calls
| -rw-r--r-- | ldebug.c | 37 | ||||
| -rw-r--r-- | lfunc.c | 4 | ||||
| -rw-r--r-- | lgc.c | 148 | ||||
| -rw-r--r-- | lobject.h | 24 | ||||
| -rw-r--r-- | lref.c | 12 | ||||
| -rw-r--r-- | ltable.c | 12 | ||||
| -rw-r--r-- | ltm.c | 15 | ||||
| -rw-r--r-- | ltm.h | 3 |
8 files changed, 143 insertions, 112 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.26 2000/06/30 14:29:35 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.27 2000/06/30 14:35:17 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -172,25 +172,38 @@ static void lua_funcinfo (lua_Debug *ar, StkId func) { | |||
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | 174 | ||
| 175 | static int checkfunc (lua_State *L, TObject *o) { | 175 | static const char *travtagmethods (lua_State *L, const TObject *o) { |
| 176 | return luaO_equalObj(o, L->top); | 176 | int e; |
| 177 | for (e=0; e<IM_N; e++) { | ||
| 178 | int t; | ||
| 179 | for (t=0; t<=L->last_tag; t++) | ||
| 180 | if (luaO_equalObj(o, luaT_getim(L, t,e))) | ||
| 181 | return luaT_eventname[e]; | ||
| 182 | } | ||
| 183 | return NULL; | ||
| 177 | } | 184 | } |
| 178 | 185 | ||
| 179 | 186 | ||
| 180 | static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) { | 187 | static const char *travglobals (lua_State *L, const TObject *o) { |
| 181 | Hash *g = L->gt; | 188 | Hash *g = L->gt; |
| 182 | int i; | 189 | int i; |
| 183 | /* try to find a name for given function */ | ||
| 184 | setnormalized(L->top, f); /* to be used by `checkfunc' */ | ||
| 185 | for (i=0; i<=g->size; i++) { | 190 | for (i=0; i<=g->size; i++) { |
| 186 | if (ttype(key(node(g,i))) == TAG_STRING && checkfunc(L, val(node(g,i)))) { | 191 | if (luaO_equalObj(o, val(node(g, i))) && |
| 187 | ar->name = tsvalue(key(node(g,i)))->str; | 192 | ttype(key(node(g, i))) == TAG_STRING) |
| 188 | ar->namewhat = "global"; | 193 | return tsvalue(key(node(g, i)))->str; |
| 189 | return; | ||
| 190 | } | ||
| 191 | } | 194 | } |
| 195 | return NULL; | ||
| 196 | } | ||
| 197 | |||
| 198 | |||
| 199 | static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) { | ||
| 200 | TObject o; | ||
| 201 | setnormalized(&o, f); | ||
| 202 | /* try to find a name for given function */ | ||
| 203 | if ((ar->name = travglobals(L, &o)) != NULL) | ||
| 204 | ar->namewhat = "global"; | ||
| 192 | /* not found: try tag methods */ | 205 | /* not found: try tag methods */ |
| 193 | if ((ar->name = luaT_travtagmethods(L, checkfunc)) != NULL) | 206 | else if ((ar->name = travtagmethods(L, &o)) != NULL) |
| 194 | ar->namewhat = "tag-method"; | 207 | ar->namewhat = "tag-method"; |
| 195 | else ar->namewhat = ""; /* not found at all */ | 208 | else ar->namewhat = ""; /* not found at all */ |
| 196 | } | 209 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 1.24 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.25 2000/06/26 19:28:31 roberto Exp roberto $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -25,7 +25,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { | |||
| 25 | (lint32)sizeof(TObject)*(nelems-1)); | 25 | (lint32)sizeof(TObject)*(nelems-1)); |
| 26 | c->next = L->rootcl; | 26 | c->next = L->rootcl; |
| 27 | L->rootcl = c; | 27 | L->rootcl = c; |
| 28 | c->marked = 0; | 28 | c->mark = c; |
| 29 | c->nupvalues = nelems; | 29 | c->nupvalues = nelems; |
| 30 | L->nblocks += gcsizeclosure(L, c); | 30 | L->nblocks += gcsizeclosure(L, c); |
| 31 | return c; | 31 | return c; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.58 2000/06/26 19:28:31 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.59 2000/06/30 14:35:17 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -20,97 +20,94 @@ | |||
| 20 | #include "ltm.h" | 20 | #include "ltm.h" |
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | typedef struct GCState { | ||
| 24 | Hash *tmark; /* list of marked tables to be visited */ | ||
| 25 | Closure *cmark; /* list of marked closures to be visited */ | ||
| 26 | } GCState; | ||
| 23 | 27 | ||
| 24 | 28 | ||
| 25 | static int markobject (lua_State *L, TObject *o); | 29 | |
| 30 | static int markobject (GCState *st, TObject *o); | ||
| 26 | 31 | ||
| 27 | 32 | ||
| 28 | /* mark a string; marks larger than 1 cannot be changed */ | 33 | /* mark a string; marks larger than 1 cannot be changed */ |
| 29 | #define strmark(L, s) {if ((s)->marked == 0) (s)->marked = 1;} | 34 | #define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;} |
| 30 | 35 | ||
| 31 | 36 | ||
| 32 | 37 | ||
| 33 | static void protomark (lua_State *L, Proto *f) { | 38 | static void protomark (Proto *f) { |
| 34 | if (!f->marked) { | 39 | if (!f->marked) { |
| 35 | int i; | 40 | int i; |
| 36 | f->marked = 1; | 41 | f->marked = 1; |
| 37 | strmark(L, f->source); | 42 | strmark(f->source); |
| 38 | for (i=0; i<f->nkstr; i++) | 43 | for (i=0; i<f->nkstr; i++) |
| 39 | strmark(L, f->kstr[i]); | 44 | strmark(f->kstr[i]); |
| 40 | for (i=0; i<f->nkproto; i++) | 45 | for (i=0; i<f->nkproto; i++) |
| 41 | protomark(L, f->kproto[i]); | 46 | protomark(f->kproto[i]); |
| 42 | if (f->locvars) { /* is there debug information? */ | 47 | if (f->locvars) { /* is there debug information? */ |
| 43 | LocVar *lv; | 48 | LocVar *lv; |
| 44 | for (lv=f->locvars; lv->pc != -1; lv++) /* mark local-variable names */ | 49 | for (lv=f->locvars; lv->pc != -1; lv++) /* mark local-variable names */ |
| 45 | if (lv->varname) strmark(L, lv->varname); | 50 | if (lv->varname) strmark(lv->varname); |
| 46 | } | 51 | } |
| 47 | } | 52 | } |
| 48 | } | 53 | } |
| 49 | 54 | ||
| 50 | 55 | ||
| 51 | static void closuremark (lua_State *L, Closure *f) { | 56 | static void markstack (lua_State *L, GCState *st) { |
| 52 | if (!f->marked) { | ||
| 53 | int i = f->nupvalues; | ||
| 54 | f->marked = 1; | ||
| 55 | while (i--) | ||
| 56 | markobject(L, &f->upvalue[i]); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | |||
| 61 | static void tablemark (lua_State *L, Hash *h) { | ||
| 62 | if (!h->marked) { | ||
| 63 | int i; | ||
| 64 | h->marked = 1; | ||
| 65 | for (i=h->size-1; i>=0; i--) { | ||
| 66 | Node *n = node(h,i); | ||
| 67 | if (ttype(key(n)) != TAG_NIL) { | ||
| 68 | if (ttype(val(n)) == TAG_NIL) | ||
| 69 | luaH_remove(h, key(n)); /* dead element; try to remove it */ | ||
| 70 | markobject(L, &n->key); | ||
| 71 | markobject(L, &n->val); | ||
| 72 | } | ||
| 73 | } | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | |||
| 78 | static void travstack (lua_State *L) { | ||
| 79 | StkId o; | 57 | StkId o; |
| 80 | for (o=L->stack; o<L->top; o++) | 58 | for (o=L->stack; o<L->top; o++) |
| 81 | markobject(L, o); | 59 | markobject(st, o); |
| 82 | } | 60 | } |
| 83 | 61 | ||
| 84 | 62 | ||
| 85 | static void travlock (lua_State *L) { | 63 | static void marklock (lua_State *L, GCState *st) { |
| 86 | int i; | 64 | int i; |
| 87 | for (i=0; i<L->refSize; i++) { | 65 | for (i=0; i<L->refSize; i++) { |
| 88 | if (L->refArray[i].st == LOCK) | 66 | if (L->refArray[i].st == LOCK) |
| 89 | markobject(L, &L->refArray[i].o); | 67 | markobject(st, &L->refArray[i].o); |
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | |||
| 72 | static void marktagmethods (lua_State *L, GCState *st) { | ||
| 73 | int e; | ||
| 74 | for (e=0; e<IM_N; e++) { | ||
| 75 | int t; | ||
| 76 | for (t=0; t<=L->last_tag; t++) | ||
| 77 | markobject(st, luaT_getim(L, t,e)); | ||
| 90 | } | 78 | } |
| 91 | } | 79 | } |
| 92 | 80 | ||
| 93 | 81 | ||
| 94 | static int markobject (lua_State *L, TObject *o) { | 82 | static int markobject (GCState *st, TObject *o) { |
| 95 | switch (ttype(o)) { | 83 | switch (ttype(o)) { |
| 96 | case TAG_USERDATA: case TAG_STRING: | 84 | case TAG_USERDATA: case TAG_STRING: |
| 97 | strmark(L, tsvalue(o)); | 85 | strmark(tsvalue(o)); |
| 98 | break; | ||
| 99 | case TAG_TABLE: | ||
| 100 | tablemark(L, hvalue(o)); | ||
| 101 | break; | 86 | break; |
| 102 | case TAG_LCLOSURE: | 87 | case TAG_TABLE: { |
| 103 | protomark(L, clvalue(o)->f.l); | 88 | if (!ismarked(hvalue(o))) { |
| 104 | closuremark(L, clvalue(o)); | 89 | hvalue(o)->mark = st->tmark; /* chain it in list of marked */ |
| 90 | st->tmark = hvalue(o); | ||
| 91 | } | ||
| 105 | break; | 92 | break; |
| 93 | } | ||
| 106 | case TAG_LMARK: { | 94 | case TAG_LMARK: { |
| 107 | Closure *cl = infovalue(o)->func; | 95 | Closure *cl = infovalue(o)->func; |
| 108 | protomark(L, cl->f.l); | 96 | if (!ismarked(cl)) { |
| 109 | closuremark(L, cl); | 97 | protomark(cl->f.l); |
| 98 | cl->mark = st->cmark; /* chain it for later traversal */ | ||
| 99 | st->cmark = cl; | ||
| 100 | } | ||
| 110 | break; | 101 | break; |
| 111 | } | 102 | } |
| 103 | case TAG_LCLOSURE: | ||
| 104 | protomark(clvalue(o)->f.l); | ||
| 105 | /* go through */ | ||
| 112 | case TAG_CCLOSURE: case TAG_CMARK: | 106 | case TAG_CCLOSURE: case TAG_CMARK: |
| 113 | closuremark(L, clvalue(o)); | 107 | if (!ismarked(clvalue(o))) { |
| 108 | clvalue(o)->mark = st->cmark; /* chain it for later traversal */ | ||
| 109 | st->cmark = clvalue(o); | ||
| 110 | } | ||
| 114 | break; | 111 | break; |
| 115 | default: break; /* numbers, etc */ | 112 | default: break; /* numbers, etc */ |
| 116 | } | 113 | } |
| @@ -118,6 +115,41 @@ static int markobject (lua_State *L, TObject *o) { | |||
| 118 | } | 115 | } |
| 119 | 116 | ||
| 120 | 117 | ||
| 118 | static void markall (lua_State *L) { | ||
| 119 | GCState st; | ||
| 120 | st.cmark = NULL; | ||
| 121 | st.tmark = L->gt; /* put table of globals in mark list */ | ||
| 122 | L->gt->mark = NULL; | ||
| 123 | marktagmethods(L, &st); /* mark tag methods */ | ||
| 124 | markstack(L, &st); /* mark stack objects */ | ||
| 125 | marklock(L, &st); /* mark locked objects */ | ||
| 126 | for (;;) { /* mark tables and closures */ | ||
| 127 | if (st.cmark) { | ||
| 128 | int i; | ||
| 129 | Closure *f = st.cmark; /* get first closure from list */ | ||
| 130 | st.cmark = f->mark; /* remove it from list */ | ||
| 131 | for (i=0; i<f->nupvalues; i++) /* mark its upvalues */ | ||
| 132 | markobject(&st, &f->upvalue[i]); | ||
| 133 | } | ||
| 134 | else if (st.tmark) { | ||
| 135 | int i; | ||
| 136 | Hash *h = st.tmark; /* get first table from list */ | ||
| 137 | st.tmark = h->mark; /* remove it from list */ | ||
| 138 | for (i=0; i<h->size; i++) { | ||
| 139 | Node *n = node(h, i); | ||
| 140 | if (ttype(key(n)) != TAG_NIL) { | ||
| 141 | if (ttype(val(n)) == TAG_NIL) | ||
| 142 | luaH_remove(h, key(n)); /* dead element; try to remove it */ | ||
| 143 | markobject(&st, &n->key); | ||
| 144 | markobject(&st, &n->val); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | } | ||
| 148 | else break; /* nothing else to mark */ | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | |||
| 121 | static void collectproto (lua_State *L) { | 153 | static void collectproto (lua_State *L) { |
| 122 | Proto **p = &L->rootproto; | 154 | Proto **p = &L->rootproto; |
| 123 | Proto *next; | 155 | Proto *next; |
| @@ -138,8 +170,8 @@ static void collectclosure (lua_State *L) { | |||
| 138 | Closure **p = &L->rootcl; | 170 | Closure **p = &L->rootcl; |
| 139 | Closure *next; | 171 | Closure *next; |
| 140 | while ((next = *p) != NULL) { | 172 | while ((next = *p) != NULL) { |
| 141 | if (next->marked) { | 173 | if (ismarked(next)) { |
| 142 | next->marked = 0; | 174 | next->mark = next; /* unmark */ |
| 143 | p = &next->next; | 175 | p = &next->next; |
| 144 | } | 176 | } |
| 145 | else { | 177 | else { |
| @@ -154,8 +186,8 @@ static void collecttable (lua_State *L) { | |||
| 154 | Hash **p = &L->roottable; | 186 | Hash **p = &L->roottable; |
| 155 | Hash *next; | 187 | Hash *next; |
| 156 | while ((next = *p) != NULL) { | 188 | while ((next = *p) != NULL) { |
| 157 | if (next->marked) { | 189 | if (ismarked(next)) { |
| 158 | next->marked = 0; | 190 | next->mark = next; /* unmark */ |
| 159 | p = &next->next; | 191 | p = &next->next; |
| 160 | } | 192 | } |
| 161 | else { | 193 | else { |
| @@ -256,14 +288,6 @@ static void callgcTMudata (lua_State *L) { | |||
| 256 | } | 288 | } |
| 257 | 289 | ||
| 258 | 290 | ||
| 259 | static void markall (lua_State *L) { | ||
| 260 | luaT_travtagmethods(L, markobject); /* mark tag methods */ | ||
| 261 | travstack(L); /* mark stack objects */ | ||
| 262 | tablemark(L, L->gt); /* mark global variables */ | ||
| 263 | travlock(L); /* mark locked objects */ | ||
| 264 | } | ||
| 265 | |||
| 266 | |||
| 267 | void luaC_collect (lua_State *L, int all) { | 291 | void luaC_collect (lua_State *L, int all) { |
| 268 | int oldah = L->allowhooks; | 292 | int oldah = L->allowhooks; |
| 269 | L->allowhooks = 0; /* stop debug hooks during GC */ | 293 | L->allowhooks = 0; /* stop debug hooks during GC */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 1.69 2000/06/28 20:20:36 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.70 2000/06/30 14:35:17 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -110,15 +110,15 @@ typedef struct TString { | |||
| 110 | ** Function Prototypes | 110 | ** Function Prototypes |
| 111 | */ | 111 | */ |
| 112 | typedef struct Proto { | 112 | typedef struct Proto { |
| 113 | struct Proto *next; | ||
| 114 | int marked; | ||
| 115 | struct TString **kstr; /* strings used by the function */ | ||
| 116 | int nkstr; /* size of `kstr' */ | ||
| 117 | Number *knum; /* Number numbers used by the function */ | 113 | Number *knum; /* Number numbers used by the function */ |
| 118 | int nknum; /* size of `knum' */ | 114 | int nknum; /* size of `knum' */ |
| 115 | struct TString **kstr; /* strings used by the function */ | ||
| 116 | int nkstr; /* size of `kstr' */ | ||
| 119 | struct Proto **kproto; /* functions defined inside the function */ | 117 | struct Proto **kproto; /* functions defined inside the function */ |
| 120 | int nkproto; /* size of `kproto' */ | 118 | int nkproto; /* size of `kproto' */ |
| 121 | Instruction *code; /* ends with opcode ENDCODE */ | 119 | Instruction *code; /* ends with opcode ENDCODE */ |
| 120 | struct Proto *next; | ||
| 121 | int marked; | ||
| 122 | int *lines; /* source line that generated each opcode */ | 122 | int *lines; /* source line that generated each opcode */ |
| 123 | int lineDefined; | 123 | int lineDefined; |
| 124 | TString *source; | 124 | TString *source; |
| @@ -139,12 +139,12 @@ typedef struct LocVar { | |||
| 139 | ** Closures | 139 | ** Closures |
| 140 | */ | 140 | */ |
| 141 | typedef struct Closure { | 141 | typedef struct Closure { |
| 142 | struct Closure *next; | ||
| 143 | int marked; | ||
| 144 | union { | 142 | union { |
| 145 | lua_CFunction c; /* C functions */ | 143 | lua_CFunction c; /* C functions */ |
| 146 | struct Proto *l; /* Lua functions */ | 144 | struct Proto *l; /* Lua functions */ |
| 147 | } f; | 145 | } f; |
| 146 | struct Closure *next; | ||
| 147 | struct Closure *mark; /* marked closures (point to itself when not marked) */ | ||
| 148 | int nupvalues; | 148 | int nupvalues; |
| 149 | TObject upvalue[1]; | 149 | TObject upvalue[1]; |
| 150 | } Closure; | 150 | } Closure; |
| @@ -157,15 +157,21 @@ typedef struct Node { | |||
| 157 | } Node; | 157 | } Node; |
| 158 | 158 | ||
| 159 | typedef struct Hash { | 159 | typedef struct Hash { |
| 160 | int htag; | ||
| 161 | Node *node; | 160 | Node *node; |
| 161 | int htag; | ||
| 162 | int size; | 162 | int size; |
| 163 | Node *firstfree; /* this position is free; all positions after it are full */ | 163 | Node *firstfree; /* this position is free; all positions after it are full */ |
| 164 | struct Hash *next; | 164 | struct Hash *next; |
| 165 | int marked; | 165 | struct Hash *mark; /* marked tables (point to itself when not marked) */ |
| 166 | } Hash; | 166 | } Hash; |
| 167 | 167 | ||
| 168 | 168 | ||
| 169 | /* unmarked tables and closures are represented by pointing `mark' to | ||
| 170 | ** themselves | ||
| 171 | */ | ||
| 172 | #define ismarked(x) ((x)->mark != (x)) | ||
| 173 | |||
| 174 | |||
| 169 | /* | 175 | /* |
| 170 | ** informations about a call (for debugging) | 176 | ** informations about a call (for debugging) |
| 171 | */ | 177 | */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lref.c,v 1.14 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: lref.c,v 1.15 2000/06/30 14:35:17 roberto Exp roberto $ |
| 3 | ** reference mechanism | 3 | ** reference mechanism |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -81,15 +81,15 @@ void lua_endblock (lua_State *L) { | |||
| 81 | 81 | ||
| 82 | 82 | ||
| 83 | 83 | ||
| 84 | static int ismarked (const TObject *o) { | 84 | static int hasmark (const TObject *o) { |
| 85 | /* valid only for locked objects */ | 85 | /* valid only for locked objects */ |
| 86 | switch (o->ttype) { | 86 | switch (o->ttype) { |
| 87 | case TAG_STRING: case TAG_USERDATA: | 87 | case TAG_STRING: case TAG_USERDATA: |
| 88 | return tsvalue(o)->marked; | 88 | return tsvalue(o)->marked; |
| 89 | case TAG_TABLE: | 89 | case TAG_TABLE: |
| 90 | return hvalue(o)->marked; | 90 | return ismarked(hvalue(o)); |
| 91 | case TAG_LCLOSURE: case TAG_CCLOSURE: | 91 | case TAG_LCLOSURE: case TAG_CCLOSURE: |
| 92 | return clvalue(o)->marked; | 92 | return ismarked(clvalue(o)->mark); |
| 93 | default: /* number */ | 93 | default: /* number */ |
| 94 | return 1; | 94 | return 1; |
| 95 | } | 95 | } |
| @@ -104,9 +104,9 @@ void luaR_invalidaterefs (lua_State *L) { | |||
| 104 | int i; | 104 | int i; |
| 105 | for (i=0; i<n; i++) { | 105 | for (i=0; i<n; i++) { |
| 106 | struct Ref *r = &L->refArray[i]; | 106 | struct Ref *r = &L->refArray[i]; |
| 107 | if (r->st == HOLD && !ismarked(&r->o)) | 107 | if (r->st == HOLD && !hasmark(&r->o)) |
| 108 | r->st = COLLECTED; | 108 | r->st = COLLECTED; |
| 109 | LUA_ASSERT((r->st == LOCK && ismarked(&r->o)) || | 109 | LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) || |
| 110 | r->st == COLLECTED || | 110 | r->st == COLLECTED || |
| 111 | r->st == NONEXT || | 111 | r->st == NONEXT || |
| 112 | (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), | 112 | (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.50 2000/06/30 14:35:17 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.51 2000/08/04 19:38:35 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 | */ |
| @@ -127,14 +127,16 @@ int luaH_pos (lua_State *L, const Hash *t, const TObject *key) { | |||
| 127 | ** hash, change `key' for a number with the same hash. | 127 | ** hash, change `key' for a number with the same hash. |
| 128 | */ | 128 | */ |
| 129 | void luaH_remove (Hash *t, TObject *key) { | 129 | void luaH_remove (Hash *t, TObject *key) { |
| 130 | /* do not remove numbers */ | 130 | if (ttype(key) == TAG_NUMBER || |
| 131 | if (ttype(key) != TAG_NUMBER) { | 131 | (ttype(key) == TAG_STRING && tsvalue(key)->u.s.len <= 30)) |
| 132 | return; /* do not remove numbers nor small strings */ | ||
| 133 | else { | ||
| 132 | /* try to find a number `n' with the same hash as `key' */ | 134 | /* try to find a number `n' with the same hash as `key' */ |
| 133 | Node *mp = luaH_mainposition(t, key); | 135 | Node *mp = luaH_mainposition(t, key); |
| 134 | int n = mp - &t->node[0]; | 136 | int n = mp - &t->node[0]; |
| 135 | /* make sure `n' is not in `t' */ | 137 | /* make sure `n' is not in `t' */ |
| 136 | while (luaH_getnum(t, n) != &luaO_nilobject) { | 138 | while (luaH_getnum(t, n) != &luaO_nilobject) { |
| 137 | if (t->size >= MAX_INT-n) | 139 | if (n >= MAX_INT - t->size) |
| 138 | return; /* give up; (to avoid overflow) */ | 140 | return; /* give up; (to avoid overflow) */ |
| 139 | n += t->size; | 141 | n += t->size; |
| 140 | } | 142 | } |
| @@ -165,7 +167,7 @@ Hash *luaH_new (lua_State *L, int size) { | |||
| 165 | t->htag = TagDefault; | 167 | t->htag = TagDefault; |
| 166 | t->next = L->roottable; | 168 | t->next = L->roottable; |
| 167 | L->roottable = t; | 169 | L->roottable = t; |
| 168 | t->marked = 0; | 170 | t->mark = t; |
| 169 | t->size = 0; | 171 | t->size = 0; |
| 170 | L->nblocks += gcsize(L, 0); | 172 | L->nblocks += gcsize(L, 0); |
| 171 | t->node = NULL; | 173 | t->node = NULL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 1.43 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 1.44 2000/08/04 19:38:35 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -147,16 +147,3 @@ void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func) { | |||
| 147 | *luaT_getim(L, t, e) = temp; | 147 | *luaT_getim(L, t, e) = temp; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | |||
| 151 | const char *luaT_travtagmethods (lua_State *L, | ||
| 152 | int (*fn)(lua_State *, TObject *)) { /* ORDER IM */ | ||
| 153 | int e; | ||
| 154 | for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { | ||
| 155 | int t; | ||
| 156 | for (t=0; t<=L->last_tag; t++) | ||
| 157 | if (fn(L, luaT_getim(L, t,e))) | ||
| 158 | return luaT_eventname[e]; | ||
| 159 | } | ||
| 160 | return NULL; | ||
| 161 | } | ||
| 162 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.h,v 1.12 2000/03/30 16:41:51 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 1.13 2000/05/30 18:54:49 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -52,7 +52,6 @@ void luaT_realtag (lua_State *L, int tag); | |||
| 52 | int luaT_effectivetag (lua_State *L, const TObject *o); | 52 | int luaT_effectivetag (lua_State *L, const TObject *o); |
| 53 | void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func); | 53 | void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func); |
| 54 | const TObject *luaT_gettagmethod (lua_State *L, int t, const char *event); | 54 | const TObject *luaT_gettagmethod (lua_State *L, int t, const char *event); |
| 55 | const char *luaT_travtagmethods (lua_State *L, int (*fn)(lua_State *, TObject *)); | ||
| 56 | int luaT_validevent (int t, int e); /* used by compatibility module */ | 55 | int luaT_validevent (int t, int e); /* used by compatibility module */ |
| 57 | 56 | ||
| 58 | 57 | ||
