diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-06 15:16:57 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-06 15:16:57 -0300 |
| commit | 8c583c61a366d90a7c6971c46568bb92522a77e9 (patch) | |
| tree | 8490e1215ceec38ba09edbd1b7740148b72c0000 | |
| parent | d2ea5b00b7c1832d2889fe0cb6bbf4b82e7a9f98 (diff) | |
| download | lua-8c583c61a366d90a7c6971c46568bb92522a77e9.tar.gz lua-8c583c61a366d90a7c6971c46568bb92522a77e9.tar.bz2 lua-8c583c61a366d90a7c6971c46568bb92522a77e9.zip | |
more tests in 'lua_checkmemory'
| -rw-r--r-- | ltests.c | 61 |
1 files changed, 48 insertions, 13 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.100 2010/05/03 11:55:40 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.101 2010/05/03 17:33:39 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 | */ |
| @@ -361,13 +361,13 @@ static void checkobject (global_State *g, GCObject *o) { | |||
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | 363 | ||
| 364 | #define GRAYBIT 7 | 364 | #define TESTGRAYBIT 7 |
| 365 | 365 | ||
| 366 | static void checkgraylist (GCObject *l) { | 366 | static void checkgraylist (GCObject *l) { |
| 367 | while (l) { | 367 | while (l) { |
| 368 | lua_assert(isgray(l)); | 368 | lua_assert(isgray(l)); |
| 369 | lua_assert(!testbit(l->gch.marked, GRAYBIT)); | 369 | lua_assert(!testbit(l->gch.marked, TESTGRAYBIT)); |
| 370 | l->gch.marked = l_setbit(l->gch.marked, GRAYBIT); | 370 | l->gch.marked = l_setbit(l->gch.marked, TESTGRAYBIT); |
| 371 | switch (gch(l)->tt) { | 371 | switch (gch(l)->tt) { |
| 372 | case LUA_TTABLE: l = gco2t(l)->gclist; break; | 372 | case LUA_TTABLE: l = gco2t(l)->gclist; break; |
| 373 | case LUA_TFUNCTION: l = gco2cl(l)->c.gclist; break; | 373 | case LUA_TFUNCTION: l = gco2cl(l)->c.gclist; break; |
| @@ -379,6 +379,10 @@ static void checkgraylist (GCObject *l) { | |||
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | 381 | ||
| 382 | /* | ||
| 383 | ** mark all objects in gray lists with the TESTGRAYBIT, so that | ||
| 384 | ** 'checkmemory' can check that all gray objects are in a gray list | ||
| 385 | */ | ||
| 382 | static void markgrays (global_State *g) { | 386 | static void markgrays (global_State *g) { |
| 383 | if (!keepinvariant(g)) return; | 387 | if (!keepinvariant(g)) return; |
| 384 | checkgraylist(g->gray); | 388 | checkgraylist(g->gray); |
| @@ -389,37 +393,63 @@ static void markgrays (global_State *g) { | |||
| 389 | } | 393 | } |
| 390 | 394 | ||
| 391 | 395 | ||
| 396 | static void checkold (global_State *g, GCObject *o) { | ||
| 397 | int isold = 0; | ||
| 398 | for (; o != NULL; o = gch(o)->next) { | ||
| 399 | if (testbit(o->gch.marked, OLDBIT)) { /* old generation? */ | ||
| 400 | lua_assert(g->gckind == KGC_GEN); | ||
| 401 | if (!issweepphase(g)) | ||
| 402 | isold = 1; | ||
| 403 | } | ||
| 404 | else lua_assert(!isold); /* non-old object cannot be after an old one */ | ||
| 405 | if (isgray(o)) { | ||
| 406 | lua_assert(!keepinvariant(g) || testbit(o->gch.marked, TESTGRAYBIT)); | ||
| 407 | o->gch.marked = resetbit(o->gch.marked, TESTGRAYBIT); | ||
| 408 | } | ||
| 409 | lua_assert(!testbit(o->gch.marked, TESTGRAYBIT)); | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | |||
| 392 | int lua_checkmemory (lua_State *L) { | 414 | int lua_checkmemory (lua_State *L) { |
| 393 | global_State *g = G(L); | 415 | global_State *g = G(L); |
| 394 | GCObject *o; | 416 | GCObject *o; |
| 395 | UpVal *uv; | 417 | UpVal *uv; |
| 396 | checkliveness(g, &g->l_registry); | 418 | checkliveness(g, &g->l_registry); |
| 397 | checkstack(g, g->mainthread); | 419 | checkstack(g, g->mainthread); |
| 398 | g->mainthread->marked = resetbit(g->mainthread->marked, GRAYBIT); | 420 | g->mainthread->marked = resetbit(g->mainthread->marked, TESTGRAYBIT); |
| 421 | /* check 'allgc' list */ | ||
| 399 | markgrays(g); | 422 | markgrays(g); |
| 423 | checkold(g, g->allgc); | ||
| 400 | for (o = g->allgc; o != NULL; o = gch(o)->next) { | 424 | for (o = g->allgc; o != NULL; o = gch(o)->next) { |
| 401 | checkobject(g, o); | 425 | checkobject(g, o); |
| 402 | if (isgray(o)) { | ||
| 403 | lua_assert(!keepinvariant(g) || testbit(o->gch.marked, GRAYBIT)); | ||
| 404 | o->gch.marked = resetbit(o->gch.marked, GRAYBIT); | ||
| 405 | } | ||
| 406 | lua_assert(!testbit(o->gch.marked, SEPARATED)); | 426 | lua_assert(!testbit(o->gch.marked, SEPARATED)); |
| 407 | lua_assert(!testbit(o->gch.marked, GRAYBIT)); | ||
| 408 | } | 427 | } |
| 428 | /* check 'udgc' list */ | ||
| 429 | checkold(g, g->tobefnz); | ||
| 409 | for (o = g->udgc; o != NULL; o = gch(o)->next) { | 430 | for (o = g->udgc; o != NULL; o = gch(o)->next) { |
| 410 | lua_assert(gch(o)->tt == LUA_TUSERDATA && | 431 | lua_assert(gch(o)->tt == LUA_TUSERDATA && |
| 411 | !isdead(g, o) && | 432 | !isdead(g, o) && |
| 412 | testbit(o->gch.marked, SEPARATED)); | 433 | testbit(o->gch.marked, SEPARATED)); |
| 413 | checkobject(g, o); | 434 | checkobject(g, o); |
| 414 | } | 435 | } |
| 436 | /* check 'tobefnz' list */ | ||
| 437 | checkold(g, g->tobefnz); | ||
| 415 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { | 438 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { |
| 416 | lua_assert(gch(o)->tt == LUA_TUSERDATA && isblack(o)); | 439 | lua_assert(gch(o)->tt == LUA_TUSERDATA); |
| 440 | lua_assert(isblack(o)); | ||
| 441 | lua_assert(!testbit(o->gch.marked, OLDBIT)); | ||
| 442 | lua_assert(testbit(o->gch.marked, SEPARATED)); | ||
| 417 | } | 443 | } |
| 444 | /* check 'uvhead' list */ | ||
| 418 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { | 445 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { |
| 419 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | 446 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); |
| 420 | lua_assert(uv->v != &uv->u.value); /* must be open */ | 447 | lua_assert(uv->v != &uv->u.value); /* must be open */ |
| 421 | lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never black */ | 448 | lua_assert(!isblack(obj2gco(uv))); /* open upvalues are never black */ |
| 422 | checkvalref(g, obj2gco(uv), uv->v); | 449 | if (isdead(g, obj2gco(uv))) |
| 450 | lua_assert(issweepphase(g)); | ||
| 451 | else | ||
| 452 | checkvalref(g, obj2gco(uv), uv->v); | ||
| 423 | } | 453 | } |
| 424 | return 0; | 454 | return 0; |
| 425 | } | 455 | } |
| @@ -571,9 +601,14 @@ static int get_gccolor (lua_State *L) { | |||
| 571 | o = obj_at(L, 1); | 601 | o = obj_at(L, 1); |
| 572 | if (!iscollectable(o)) | 602 | if (!iscollectable(o)) |
| 573 | lua_pushstring(L, "no collectable"); | 603 | lua_pushstring(L, "no collectable"); |
| 574 | else | 604 | else { |
| 575 | lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : | 605 | lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : |
| 576 | isblack(gcvalue(o)) ? "black" : "grey"); | 606 | isblack(gcvalue(o)) ? "black" : "grey"); |
| 607 | if (testbit(gcvalue(o)->gch.marked, OLDBIT)) { | ||
| 608 | lua_pushliteral(L, "/old"); | ||
| 609 | lua_concat(L, 2); | ||
| 610 | } | ||
| 611 | } | ||
| 577 | return 1; | 612 | return 1; |
| 578 | } | 613 | } |
| 579 | 614 | ||
