aboutsummaryrefslogtreecommitdiff
path: root/ltests.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-08-07 14:45:20 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-08-07 14:45:20 -0300
commitf13dc59416afa8fc93bb3d784d1a73e49e1b5b09 (patch)
tree4719b653c8cbb3e0651e97ebb7acb96ac3a7a13d /ltests.c
parent7c3cb71fa48fbe84d9d9c664eb646446fb80898b (diff)
downloadlua-f13dc59416afa8fc93bb3d784d1a73e49e1b5b09.tar.gz
lua-f13dc59416afa8fc93bb3d784d1a73e49e1b5b09.tar.bz2
lua-f13dc59416afa8fc93bb3d784d1a73e49e1b5b09.zip
Better tests for gray lists
Test uses an extra bit in 'marked' to mark all elements in gray lists and then check against elements colored gray.
Diffstat (limited to 'ltests.c')
-rw-r--r--ltests.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/ltests.c b/ltests.c
index c0421781..04e8a00a 100644
--- a/ltests.c
+++ b/ltests.c
@@ -522,7 +522,11 @@ static lu_mem checkgraylist (global_State *g, GCObject *o) {
522 int total = 0; /* count number of elements in the list */ 522 int total = 0; /* count number of elements in the list */
523 ((void)g); /* better to keep it available if we need to print an object */ 523 ((void)g); /* better to keep it available if we need to print an object */
524 while (o) { 524 while (o) {
525 lua_assert(isgray(o) || getage(o) == G_TOUCHED2); 525 lua_assert(!!isgray(o) ^ (getage(o) == G_TOUCHED2));
526 //lua_assert(isgray(o) || getage(o) == G_TOUCHED2);
527 lua_assert(!testbit(o->marked, TESTBIT));
528 if (keepinvariant(g))
529 l_setbit(o->marked, TESTBIT); /* mark that object is in a gray list */
526 total++; 530 total++;
527 switch (o->tt) { 531 switch (o->tt) {
528 case LUA_VTABLE: o = gco2t(o)->gclist; break; 532 case LUA_VTABLE: o = gco2t(o)->gclist; break;
@@ -556,9 +560,27 @@ static lu_mem checkgrays (global_State *g) {
556} 560}
557 561
558 562
559/* Increment 't' if 'o' should be in a gray list */ 563/*
560#define incifingray(o,t) \ 564** Check whether 'o' should be in a gray list. If so, increment
561 if (isgray(o) || getage(o) == G_TOUCHED2) (t)++ 565** 'count' and check its TESTBIT. (It must have been previously set by
566** 'checkgraylist'.)
567*/
568static void incifingray (global_State *g, GCObject *o, lu_mem *count) {
569 if (!keepinvariant(g))
570 return; /* gray lists not being kept in these phases */
571 if (o->tt == LUA_VUPVAL) {
572 /* only open upvalues can be gray */
573 lua_assert(!isgray(o) || upisopen(gco2upv(o)));
574 return; /* upvalues are never in gray lists */
575 }
576 /* these are the ones that must be in gray lists */
577 if (isgray(o) || getage(o) == G_TOUCHED2) {
578 (*count)++;
579 lua_assert(testbit(o->marked, TESTBIT));
580 resetbit(o->marked, TESTBIT); /* prepare for next cycle */
581 }
582}
583
562 584
563static lu_mem checklist (global_State *g, int maybedead, int tof, 585static lu_mem checklist (global_State *g, int maybedead, int tof,
564 GCObject *newl, GCObject *survival, GCObject *old, GCObject *reallyold) { 586 GCObject *newl, GCObject *survival, GCObject *old, GCObject *reallyold) {
@@ -566,22 +588,22 @@ static lu_mem checklist (global_State *g, int maybedead, int tof,
566 lu_mem total = 0; /* number of object that should be in gray lists */ 588 lu_mem total = 0; /* number of object that should be in gray lists */
567 for (o = newl; o != survival; o = o->next) { 589 for (o = newl; o != survival; o = o->next) {
568 checkobject(g, o, maybedead, G_NEW); 590 checkobject(g, o, maybedead, G_NEW);
569 incifingray(o, total); 591 incifingray(g, o, &total);
570 lua_assert(!tof == !tofinalize(o)); 592 lua_assert(!tof == !tofinalize(o));
571 } 593 }
572 for (o = survival; o != old; o = o->next) { 594 for (o = survival; o != old; o = o->next) {
573 checkobject(g, o, 0, G_SURVIVAL); 595 checkobject(g, o, 0, G_SURVIVAL);
574 incifingray(o, total); 596 incifingray(g, o, &total);
575 lua_assert(!tof == !tofinalize(o)); 597 lua_assert(!tof == !tofinalize(o));
576 } 598 }
577 for (o = old; o != reallyold; o = o->next) { 599 for (o = old; o != reallyold; o = o->next) {
578 checkobject(g, o, 0, G_OLD1); 600 checkobject(g, o, 0, G_OLD1);
579 incifingray(o, total); 601 incifingray(g, o, &total);
580 lua_assert(!tof == !tofinalize(o)); 602 lua_assert(!tof == !tofinalize(o));
581 } 603 }
582 for (o = reallyold; o != NULL; o = o->next) { 604 for (o = reallyold; o != NULL; o = o->next) {
583 checkobject(g, o, 0, G_OLD); 605 checkobject(g, o, 0, G_OLD);
584 incifingray(o, total); 606 incifingray(g, o, &total);
585 lua_assert(!tof == !tofinalize(o)); 607 lua_assert(!tof == !tofinalize(o));
586 } 608 }
587 return total; 609 return total;
@@ -619,7 +641,7 @@ int lua_checkmemory (lua_State *L) {
619 /* check 'tobefnz' list */ 641 /* check 'tobefnz' list */
620 for (o = g->tobefnz; o != NULL; o = o->next) { 642 for (o = g->tobefnz; o != NULL; o = o->next) {
621 checkobject(g, o, 0, G_NEW); 643 checkobject(g, o, 0, G_NEW);
622 incifingray(o, totalshould); 644 incifingray(g, o, &totalshould);
623 lua_assert(tofinalize(o)); 645 lua_assert(tofinalize(o));
624 lua_assert(o->tt == LUA_VUSERDATA || o->tt == LUA_VTABLE); 646 lua_assert(o->tt == LUA_VUSERDATA || o->tt == LUA_VTABLE);
625 } 647 }