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 | |
| 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'
| -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}, |
