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