diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-09-19 14:03:38 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-09-19 14:03:38 -0300 |
commit | 45c346645c84b0d4750b254a1547051343fb26a3 (patch) | |
tree | ea175f17797128bdf21872be1385a21b6914ac04 | |
parent | 68ce878292cf7c571b8bc20f567e462ae62d859d (diff) | |
download | lua-45c346645c84b0d4750b254a1547051343fb26a3.tar.gz lua-45c346645c84b0d4750b254a1547051343fb26a3.tar.bz2 lua-45c346645c84b0d4750b254a1547051343fb26a3.zip |
avoid clearing ephemeron tables that have nothing to be cleaned
(no white elements)
-rw-r--r-- | lgc.c | 30 |
1 files changed, 17 insertions, 13 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.108 2010/12/29 18:00:23 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.109 2011/05/05 19:42:25 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 | */ |
@@ -357,7 +357,8 @@ static void traverseweakvalue (global_State *g, Table *h) { | |||
357 | 357 | ||
358 | static int traverseephemeron (global_State *g, Table *h) { | 358 | static int traverseephemeron (global_State *g, Table *h) { |
359 | int marked = 0; /* true if an object is marked in this traversal */ | 359 | int marked = 0; /* true if an object is marked in this traversal */ |
360 | int hasclears = 0; /* true if table has unmarked pairs */ | 360 | int hasclears = 0; /* true if table has white keys */ |
361 | int prop = 0; /* true if table has entry "white-key -> white-value" */ | ||
361 | Node *n, *limit = gnode(h, sizenode(h)); | 362 | Node *n, *limit = gnode(h, sizenode(h)); |
362 | int i; | 363 | int i; |
363 | /* traverse array part (numeric keys are 'strong') */ | 364 | /* traverse array part (numeric keys are 'strong') */ |
@@ -372,19 +373,22 @@ static int traverseephemeron (global_State *g, Table *h) { | |||
372 | checkdeadkey(n); | 373 | checkdeadkey(n); |
373 | if (ttisnil(gval(n))) /* entry is empty? */ | 374 | if (ttisnil(gval(n))) /* entry is empty? */ |
374 | removeentry(n); /* remove it */ | 375 | removeentry(n); /* remove it */ |
376 | else if (iscleared(gkey(n), 1)) { /* key is not marked (yet)? */ | ||
377 | hasclears = 1; /* table still have white keys */ | ||
378 | if (valiswhite(gval(n))) /* value not marked yet? */ | ||
379 | prop = 1; | ||
380 | } | ||
375 | else if (valiswhite(gval(n))) { /* value not marked yet? */ | 381 | else if (valiswhite(gval(n))) { /* value not marked yet? */ |
376 | if (iscleared(gkey(n), 1)) /* key is not marked (yet)? */ | 382 | marked = 1; /* mark it now */ |
377 | hasclears = 1; /* may have to propagate mark from key to value */ | 383 | reallymarkobject(g, gcvalue(gval(n))); |
378 | else { /* key is marked, so mark value */ | ||
379 | marked = 1; /* value was not marked */ | ||
380 | reallymarkobject(g, gcvalue(gval(n))); | ||
381 | } | ||
382 | } | 384 | } |
383 | } | 385 | } |
384 | if (hasclears) /* does table have unmarked pairs? */ | 386 | if (prop) |
385 | linktable(h, &g->ephemeron); /* will have to propagate again */ | 387 | linktable(h, &g->ephemeron); /* have to propagate again */ |
386 | else /* nothing to propagate */ | 388 | else if (hasclears) /* does table have white keys? */ |
387 | linktable(h, &g->weak); /* avoid convergence phase */ | 389 | linktable(h, &g->allweak); /* may have to clean white keys */ |
390 | else /* no white keys */ | ||
391 | linktable(h, &g->grayagain); /* no need to clean */ | ||
388 | return marked; | 392 | return marked; |
389 | } | 393 | } |
390 | 394 | ||
@@ -868,8 +872,8 @@ static void atomic (lua_State *L) { | |||
868 | /* traverse objects caught by write barrier and by 'remarkupvals' */ | 872 | /* traverse objects caught by write barrier and by 'remarkupvals' */ |
869 | propagateall(g); | 873 | propagateall(g); |
870 | traverselistofgrays(g, &g->weak); /* remark weak tables */ | 874 | traverselistofgrays(g, &g->weak); /* remark weak tables */ |
871 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ | ||
872 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ | 875 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ |
876 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ | ||
873 | convergeephemerons(g); | 877 | convergeephemerons(g); |
874 | /* at this point, all strongly accessible objects are marked. */ | 878 | /* at this point, all strongly accessible objects are marked. */ |
875 | luaC_separateudata(L, 0); /* separate userdata to be finalized */ | 879 | luaC_separateudata(L, 0); /* separate userdata to be finalized */ |