aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--lgc.h5
-rw-r--r--ltests.c40
-rw-r--r--testes/nextvar.lua2
3 files changed, 37 insertions, 10 deletions
diff --git a/lgc.h b/lgc.h
index f571fd2b..0508cd1d 100644
--- a/lgc.h
+++ b/lgc.h
@@ -69,13 +69,16 @@
69 69
70/* 70/*
71** Layout for bit use in 'marked' field. First three bits are 71** Layout for bit use in 'marked' field. First three bits are
72** used for object "age" in generational mode. 72** used for object "age" in generational mode. Last bit is used
73** by tests.
73*/ 74*/
74#define WHITE0BIT 3 /* object is white (type 0) */ 75#define WHITE0BIT 3 /* object is white (type 0) */
75#define WHITE1BIT 4 /* object is white (type 1) */ 76#define WHITE1BIT 4 /* object is white (type 1) */
76#define BLACKBIT 5 /* object is black */ 77#define BLACKBIT 5 /* object is black */
77#define FINALIZEDBIT 6 /* object has been marked for finalization */ 78#define FINALIZEDBIT 6 /* object has been marked for finalization */
78 79
80#define TESTBIT 7
81
79 82
80 83
81#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 84#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
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 }
diff --git a/testes/nextvar.lua b/testes/nextvar.lua
index 73af77dd..a16d557b 100644
--- a/testes/nextvar.lua
+++ b/testes/nextvar.lua
@@ -88,6 +88,7 @@ for _, sa in ipairs(sizes) do -- 'sa' is size of the array part
88 arr[1 + sa + sh + 1] = "}" 88 arr[1 + sa + sh + 1] = "}"
89 local prog = table.concat(arr) 89 local prog = table.concat(arr)
90 local f = assert(load(prog)) 90 local f = assert(load(prog))
91 collectgarbage("stop")
91 f() -- call once to ensure stack space 92 f() -- call once to ensure stack space
92 -- make sure table is not resized after being created 93 -- make sure table is not resized after being created
93 if sa == 0 or sh == 0 then 94 if sa == 0 or sh == 0 then
@@ -97,6 +98,7 @@ for _, sa in ipairs(sizes) do -- 'sa' is size of the array part
97 end 98 end
98 local t = f() 99 local t = f()
99 T.alloccount(); 100 T.alloccount();
101 collectgarbage("restart")
100 assert(#t == sa) 102 assert(#t == sa)
101 check(t, sa, mp2(sh)) 103 check(t, sa, mp2(sh))
102 end 104 end