diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-08-07 14:45:20 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-08-07 14:45:20 -0300 |
| commit | f13dc59416afa8fc93bb3d784d1a73e49e1b5b09 (patch) | |
| tree | 4719b653c8cbb3e0651e97ebb7acb96ac3a7a13d /ltests.c | |
| parent | 7c3cb71fa48fbe84d9d9c664eb646446fb80898b (diff) | |
| download | lua-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.c | 40 |
1 files changed, 31 insertions, 9 deletions
| @@ -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 | */ | ||
| 568 | static 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 | ||
| 563 | static lu_mem checklist (global_State *g, int maybedead, int tof, | 585 | static 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 | } |
