diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-19 15:46:47 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-19 15:46:47 -0300 |
commit | 7ae180f8e8c987c1992ad95b3f5f31c69e5650e0 (patch) | |
tree | e897591d3950342f1b75b74cedd9337ce11fe9bf /ltests.c | |
parent | c7bdc0e0e8ab03820b472a87b87c04475def5997 (diff) | |
download | lua-7ae180f8e8c987c1992ad95b3f5f31c69e5650e0.tar.gz lua-7ae180f8e8c987c1992ad95b3f5f31c69e5650e0.tar.bz2 lua-7ae180f8e8c987c1992ad95b3f5f31c69e5650e0.zip |
corrected some checks about colors of old objects + new test function
'gcage'
Diffstat (limited to 'ltests.c')
-rw-r--r-- | ltests.c | 61 |
1 files changed, 46 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.212 2017/02/23 21:07:34 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.213 2017/04/18 19:42:12 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -189,10 +189,11 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) { | |||
189 | /* | 189 | /* |
190 | ** Check GC invariants. For incremental mode, a black object cannot | 190 | ** Check GC invariants. For incremental mode, a black object cannot |
191 | ** point to a white one. For generational mode, really old objects | 191 | ** point to a white one. For generational mode, really old objects |
192 | ** cannot point to young objects. (Threads and open upvalues, despite | 192 | ** cannot point to young objects. Both old1 and touched2 objects |
193 | ** being marked "really old", continue to be visited in all collections, | 193 | ** cannot point to new objects (but can point to survivals). |
194 | ** and therefore can point to new objects. They, and only they, are | 194 | ** (Threads and open upvalues, despite being marked "really old", |
195 | ** old but gray.) | 195 | ** continue to be visited in all collections, and therefore can point to |
196 | ** new objects. They, and only they, are old but gray.) | ||
196 | */ | 197 | */ |
197 | static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { | 198 | static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { |
198 | if (isdead(g,t)) return 0; | 199 | if (isdead(g,t)) return 0; |
@@ -200,8 +201,14 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { | |||
200 | return 1; /* no invariants */ | 201 | return 1; /* no invariants */ |
201 | else if (g->gckind == KGC_NORMAL) | 202 | else if (g->gckind == KGC_NORMAL) |
202 | return !(isblack(f) && iswhite(t)); /* basic incremental invariant */ | 203 | return !(isblack(f) && iswhite(t)); /* basic incremental invariant */ |
203 | else | 204 | else { /* generational mode */ |
204 | return !((getage(f) == G_OLD && isblack(f)) && !isold(t)); | 205 | if ((getage(f) == G_OLD && isblack(f)) && !isold(t)) |
206 | return 0; | ||
207 | if (((getage(f) == G_OLD1 || getage(f) == G_TOUCHED2) && isblack(f)) && | ||
208 | getage(t) == G_NEW) | ||
209 | return 0; | ||
210 | return 1; | ||
211 | } | ||
205 | } | 212 | } |
206 | 213 | ||
207 | 214 | ||
@@ -377,6 +384,17 @@ static void checkrefs (global_State *g, GCObject *o) { | |||
377 | } | 384 | } |
378 | 385 | ||
379 | 386 | ||
387 | /* | ||
388 | ** Check consistency of an object: | ||
389 | ** - Dead objects can only happen in the 'allgc' list during a sweep | ||
390 | ** phase (controled by the caller through 'maybedead'). | ||
391 | ** - During pause, all objects must be white. | ||
392 | ** - In generational mode: | ||
393 | ** * objects must be old enough for their lists ('listage'). | ||
394 | ** * old objects cannot be white. | ||
395 | ** * old objects must be black, except for 'touched1', 'old0', | ||
396 | ** threads, and open upvalues. | ||
397 | */ | ||
380 | static void checkobject (global_State *g, GCObject *o, int maybedead, | 398 | static void checkobject (global_State *g, GCObject *o, int maybedead, |
381 | int listage) { | 399 | int listage) { |
382 | if (isdead(g, o)) | 400 | if (isdead(g, o)) |
@@ -389,6 +407,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead, | |||
389 | if (isold(o)) { | 407 | if (isold(o)) { |
390 | lua_assert(isblack(o) || | 408 | lua_assert(isblack(o) || |
391 | getage(o) == G_TOUCHED1 || | 409 | getage(o) == G_TOUCHED1 || |
410 | getage(o) == G_OLD0 || | ||
392 | o->tt == LUA_TTHREAD || | 411 | o->tt == LUA_TTHREAD || |
393 | (o->tt == LUA_TUPVAL && upisopen(gco2upv(o)))); | 412 | (o->tt == LUA_TUPVAL && upisopen(gco2upv(o)))); |
394 | } | 413 | } |
@@ -442,9 +461,9 @@ static void checkgray (global_State *g, GCObject *o) { | |||
442 | 461 | ||
443 | 462 | ||
444 | static void checklist (global_State *g, int maybedead, int tof, | 463 | static void checklist (global_State *g, int maybedead, int tof, |
445 | GCObject *new, GCObject *survival, GCObject *old, GCObject *reallyold) { | 464 | GCObject *newl, GCObject *survival, GCObject *old, GCObject *reallyold) { |
446 | GCObject *o; | 465 | GCObject *o; |
447 | for (o = new; o != survival; o = o->next) { | 466 | for (o = newl; o != survival; o = o->next) { |
448 | checkobject(g, o, maybedead, G_NEW); | 467 | checkobject(g, o, maybedead, G_NEW); |
449 | lua_assert(!tof == !tofinalize(o)); | 468 | lua_assert(!tof == !tofinalize(o)); |
450 | } | 469 | } |
@@ -668,20 +687,31 @@ static int gc_color (lua_State *L) { | |||
668 | TValue *o; | 687 | TValue *o; |
669 | luaL_checkany(L, 1); | 688 | luaL_checkany(L, 1); |
670 | o = obj_at(L, 1); | 689 | o = obj_at(L, 1); |
671 | if (!iscollectable(o)) { | 690 | if (!iscollectable(o)) |
672 | lua_pushstring(L, "no collectable"); | 691 | lua_pushstring(L, "no collectable"); |
673 | return 1; | ||
674 | } | ||
675 | else { | 692 | else { |
676 | static const char *gennames[] = {"new", "survival", "old0", "old1", | ||
677 | "old", "touched1", "touched2"}; | ||
678 | GCObject *obj = gcvalue(o); | 693 | GCObject *obj = gcvalue(o); |
679 | lua_pushstring(L, isdead(G(L), obj) ? "dead" : | 694 | lua_pushstring(L, isdead(G(L), obj) ? "dead" : |
680 | iswhite(obj) ? "white" : | 695 | iswhite(obj) ? "white" : |
681 | isblack(obj) ? "black" : "grey"); | 696 | isblack(obj) ? "black" : "grey"); |
697 | } | ||
698 | return 1; | ||
699 | } | ||
700 | |||
701 | |||
702 | static int gc_age (lua_State *L) { | ||
703 | TValue *o; | ||
704 | luaL_checkany(L, 1); | ||
705 | o = obj_at(L, 1); | ||
706 | if (!iscollectable(o)) | ||
707 | lua_pushstring(L, "no collectable"); | ||
708 | else { | ||
709 | static const char *gennames[] = {"new", "survival", "old0", "old1", | ||
710 | "old", "touched1", "touched2"}; | ||
711 | GCObject *obj = gcvalue(o); | ||
682 | lua_pushstring(L, gennames[getage(obj)]); | 712 | lua_pushstring(L, gennames[getage(obj)]); |
683 | return 2; | ||
684 | } | 713 | } |
714 | return 1; | ||
685 | } | 715 | } |
686 | 716 | ||
687 | 717 | ||
@@ -1587,6 +1617,7 @@ static const struct luaL_Reg tests_funcs[] = { | |||
1587 | {"doonnewstack", doonnewstack}, | 1617 | {"doonnewstack", doonnewstack}, |
1588 | {"doremote", doremote}, | 1618 | {"doremote", doremote}, |
1589 | {"gccolor", gc_color}, | 1619 | {"gccolor", gc_color}, |
1620 | {"gcage", gc_age}, | ||
1590 | {"gcstate", gc_state}, | 1621 | {"gcstate", gc_state}, |
1591 | {"pobj", gc_printobj}, | 1622 | {"pobj", gc_printobj}, |
1592 | {"getref", getref}, | 1623 | {"getref", getref}, |