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 */ |
