diff options
author | Mike Pall <mike> | 2010-04-21 01:45:58 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-04-21 01:45:58 +0200 |
commit | ab45481199e9c9dd3efec922647bcec122504bcb (patch) | |
tree | 0484341edff50a0afe98133ad66fb6a59915996a /src/lj_gc.c | |
parent | d8cb69ed076c3444258f63314662451c9d117cae (diff) | |
download | luajit-ab45481199e9c9dd3efec922647bcec122504bcb.tar.gz luajit-ab45481199e9c9dd3efec922647bcec122504bcb.tar.bz2 luajit-ab45481199e9c9dd3efec922647bcec122504bcb.zip |
No longer let the GC replace dead keys with the LJ_TDEADKEY tag.
Important: this changes the semantics of the write barrier!
Carefully read the big comment block in lj_obj.h
This helps HREFK key slot specialization and allows safely hoisting
HREF/HREFK across GC steps, too (fix for a barely reproducible bug).
Dead keys are only removed during a table resize (as before).
Diffstat (limited to 'src/lj_gc.c')
-rw-r--r-- | src/lj_gc.c | 8 |
1 files changed, 1 insertions, 7 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c index b97fb955..b457c424 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c | |||
@@ -186,13 +186,10 @@ static int gc_traverse_tab(global_State *g, GCtab *t) | |||
186 | MSize i, hmask = t->hmask; | 186 | MSize i, hmask = t->hmask; |
187 | for (i = 0; i <= hmask; i++) { | 187 | for (i = 0; i <= hmask; i++) { |
188 | Node *n = &node[i]; | 188 | Node *n = &node[i]; |
189 | lua_assert(itype(&n->key) != LJ_TDEADKEY || tvisnil(&n->val)); | ||
190 | if (!tvisnil(&n->val)) { /* Mark non-empty slot. */ | 189 | if (!tvisnil(&n->val)) { /* Mark non-empty slot. */ |
191 | lua_assert(!tvisnil(&n->key)); | 190 | lua_assert(!tvisnil(&n->key)); |
192 | if (!(weak & LJ_GC_WEAKKEY)) gc_marktv(g, &n->key); | 191 | if (!(weak & LJ_GC_WEAKKEY)) gc_marktv(g, &n->key); |
193 | if (!(weak & LJ_GC_WEAKVAL)) gc_marktv(g, &n->val); | 192 | if (!(weak & LJ_GC_WEAKVAL)) gc_marktv(g, &n->val); |
194 | } else if (tvisgcv(&n->key)) { /* Leave GC key in, but mark as dead. */ | ||
195 | setitype(&n->key, LJ_TDEADKEY); | ||
196 | } | 193 | } |
197 | } | 194 | } |
198 | } | 195 | } |
@@ -424,11 +421,8 @@ static void gc_clearweak(GCobj *o) | |||
424 | Node *n = &node[i]; | 421 | Node *n = &node[i]; |
425 | /* Clear hash slot when key or value is about to be collected. */ | 422 | /* Clear hash slot when key or value is about to be collected. */ |
426 | if (!tvisnil(&n->val) && (gc_mayclear(&n->key, 0) || | 423 | if (!tvisnil(&n->val) && (gc_mayclear(&n->key, 0) || |
427 | gc_mayclear(&n->val, 1))) { | 424 | gc_mayclear(&n->val, 1))) |
428 | setnilV(&n->val); | 425 | setnilV(&n->val); |
429 | if (tvisgcv(&n->key)) /* Leave GC key in, but mark as dead. */ | ||
430 | setitype(&n->key, LJ_TDEADKEY); | ||
431 | } | ||
432 | } | 426 | } |
433 | } | 427 | } |
434 | o = gcref(t->gclist); | 428 | o = gcref(t->gclist); |