From 7ae180f8e8c987c1992ad95b3f5f31c69e5650e0 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 19 Apr 2017 15:46:47 -0300 Subject: corrected some checks about colors of old objects + new test function 'gcage' --- ltests.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'ltests.c') diff --git a/ltests.c b/ltests.c index 4022809c..9679bee2 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.212 2017/02/23 21:07:34 roberto Exp roberto $ +** $Id: ltests.c,v 2.213 2017/04/18 19:42:12 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -189,10 +189,11 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) { /* ** Check GC invariants. For incremental mode, a black object cannot ** point to a white one. For generational mode, really old objects -** cannot point to young objects. (Threads and open upvalues, despite -** being marked "really old", continue to be visited in all collections, -** and therefore can point to new objects. They, and only they, are -** old but gray.) +** cannot point to young objects. Both old1 and touched2 objects +** cannot point to new objects (but can point to survivals). +** (Threads and open upvalues, despite being marked "really old", +** continue to be visited in all collections, and therefore can point to +** new objects. They, and only they, are old but gray.) */ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { if (isdead(g,t)) return 0; @@ -200,8 +201,14 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { return 1; /* no invariants */ else if (g->gckind == KGC_NORMAL) return !(isblack(f) && iswhite(t)); /* basic incremental invariant */ - else - return !((getage(f) == G_OLD && isblack(f)) && !isold(t)); + else { /* generational mode */ + if ((getage(f) == G_OLD && isblack(f)) && !isold(t)) + return 0; + if (((getage(f) == G_OLD1 || getage(f) == G_TOUCHED2) && isblack(f)) && + getage(t) == G_NEW) + return 0; + return 1; + } } @@ -377,6 +384,17 @@ static void checkrefs (global_State *g, GCObject *o) { } +/* +** Check consistency of an object: +** - Dead objects can only happen in the 'allgc' list during a sweep +** phase (controled by the caller through 'maybedead'). +** - During pause, all objects must be white. +** - In generational mode: +** * objects must be old enough for their lists ('listage'). +** * old objects cannot be white. +** * old objects must be black, except for 'touched1', 'old0', +** threads, and open upvalues. +*/ static void checkobject (global_State *g, GCObject *o, int maybedead, int listage) { if (isdead(g, o)) @@ -389,6 +407,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead, if (isold(o)) { lua_assert(isblack(o) || getage(o) == G_TOUCHED1 || + getage(o) == G_OLD0 || o->tt == LUA_TTHREAD || (o->tt == LUA_TUPVAL && upisopen(gco2upv(o)))); } @@ -442,9 +461,9 @@ static void checkgray (global_State *g, GCObject *o) { static void checklist (global_State *g, int maybedead, int tof, - GCObject *new, GCObject *survival, GCObject *old, GCObject *reallyold) { + GCObject *newl, GCObject *survival, GCObject *old, GCObject *reallyold) { GCObject *o; - for (o = new; o != survival; o = o->next) { + for (o = newl; o != survival; o = o->next) { checkobject(g, o, maybedead, G_NEW); lua_assert(!tof == !tofinalize(o)); } @@ -668,20 +687,31 @@ static int gc_color (lua_State *L) { TValue *o; luaL_checkany(L, 1); o = obj_at(L, 1); - if (!iscollectable(o)) { + if (!iscollectable(o)) lua_pushstring(L, "no collectable"); - return 1; - } else { - static const char *gennames[] = {"new", "survival", "old0", "old1", - "old", "touched1", "touched2"}; GCObject *obj = gcvalue(o); lua_pushstring(L, isdead(G(L), obj) ? "dead" : iswhite(obj) ? "white" : isblack(obj) ? "black" : "grey"); + } + return 1; +} + + +static int gc_age (lua_State *L) { + TValue *o; + luaL_checkany(L, 1); + o = obj_at(L, 1); + if (!iscollectable(o)) + lua_pushstring(L, "no collectable"); + else { + static const char *gennames[] = {"new", "survival", "old0", "old1", + "old", "touched1", "touched2"}; + GCObject *obj = gcvalue(o); lua_pushstring(L, gennames[getage(obj)]); - return 2; } + return 1; } @@ -1587,6 +1617,7 @@ static const struct luaL_Reg tests_funcs[] = { {"doonnewstack", doonnewstack}, {"doremote", doremote}, {"gccolor", gc_color}, + {"gcage", gc_age}, {"gcstate", gc_state}, {"pobj", gc_printobj}, {"getref", getref}, -- cgit v1.2.3-55-g6feb