aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lgc.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/lgc.c b/lgc.c
index 02adfecf..ef8646c7 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.120 2012/05/08 13:53:33 roberto Exp roberto $ 2** $Id: lgc.c,v 2.121 2012/05/11 19:22:33 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -65,12 +65,6 @@
65#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) 65#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS)
66#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) 66#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)
67 67
68/*
69** dirty trick: we know that 'reallymarkobject' does not use 'g' when
70** object is a string
71*/
72#define stringmark(s) markobject(NULL, s)
73
74 68
75#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) 69#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT)
76 70
@@ -127,10 +121,10 @@ static void removeentry (Node *n) {
127** other objects: if really collected, cannot keep them; for objects 121** other objects: if really collected, cannot keep them; for objects
128** being finalized, keep them in keys, but not in values 122** being finalized, keep them in keys, but not in values
129*/ 123*/
130static int iscleared (const TValue *o) { 124static int iscleared (global_State *g, const TValue *o) {
131 if (!iscollectable(o)) return 0; 125 if (!iscollectable(o)) return 0;
132 else if (ttisstring(o)) { 126 else if (ttisstring(o)) {
133 stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ 127 markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */
134 return 0; 128 return 0;
135 } 129 }
136 else return iswhite(gcvalue(o)); 130 else return iswhite(gcvalue(o));
@@ -369,7 +363,7 @@ static void traverseweakvalue (global_State *g, Table *h) {
369 else { 363 else {
370 lua_assert(!ttisnil(gkey(n))); 364 lua_assert(!ttisnil(gkey(n)));
371 markvalue(g, gkey(n)); /* mark key */ 365 markvalue(g, gkey(n)); /* mark key */
372 if (!hasclears && iscleared(gval(n))) /* is there a white value? */ 366 if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */
373 hasclears = 1; /* table will have to be cleared */ 367 hasclears = 1; /* table will have to be cleared */
374 } 368 }
375 } 369 }
@@ -398,7 +392,7 @@ static int traverseephemeron (global_State *g, Table *h) {
398 checkdeadkey(n); 392 checkdeadkey(n);
399 if (ttisnil(gval(n))) /* entry is empty? */ 393 if (ttisnil(gval(n))) /* entry is empty? */
400 removeentry(n); /* remove it */ 394 removeentry(n); /* remove it */
401 else if (iscleared(gkey(n))) { /* key is not marked (yet)? */ 395 else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */
402 hasclears = 1; /* table must be cleared */ 396 hasclears = 1; /* table must be cleared */
403 if (valiswhite(gval(n))) /* value not marked yet? */ 397 if (valiswhite(gval(n))) /* value not marked yet? */
404 prop = 1; /* must propagate again */ 398 prop = 1; /* must propagate again */
@@ -467,15 +461,15 @@ static int traverseproto (global_State *g, Proto *f) {
467 int i; 461 int i;
468 if (f->cache && iswhite(obj2gco(f->cache))) 462 if (f->cache && iswhite(obj2gco(f->cache)))
469 f->cache = NULL; /* allow cache to be collected */ 463 f->cache = NULL; /* allow cache to be collected */
470 stringmark(f->source); 464 markobject(g, f->source);
471 for (i = 0; i < f->sizek; i++) /* mark literals */ 465 for (i = 0; i < f->sizek; i++) /* mark literals */
472 markvalue(g, &f->k[i]); 466 markvalue(g, &f->k[i]);
473 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ 467 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
474 stringmark(f->upvalues[i].name); 468 markobject(g, f->upvalues[i].name);
475 for (i = 0; i < f->sizep; i++) /* mark nested protos */ 469 for (i = 0; i < f->sizep; i++) /* mark nested protos */
476 markobject(g, f->p[i]); 470 markobject(g, f->p[i]);
477 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ 471 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
478 stringmark(f->locvars[i].varname); 472 markobject(g, f->locvars[i].varname);
479 return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; 473 return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars;
480} 474}
481 475
@@ -613,12 +607,12 @@ static void convergeephemerons (global_State *g) {
613** clear entries with unmarked keys from all weaktables in list 'l' up 607** clear entries with unmarked keys from all weaktables in list 'l' up
614** to element 'f' 608** to element 'f'
615*/ 609*/
616static void clearkeys (GCObject *l, GCObject *f) { 610static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
617 for (; l != f; l = gco2t(l)->gclist) { 611 for (; l != f; l = gco2t(l)->gclist) {
618 Table *h = gco2t(l); 612 Table *h = gco2t(l);
619 Node *n, *limit = gnodelast(h); 613 Node *n, *limit = gnodelast(h);
620 for (n = gnode(h, 0); n < limit; n++) { 614 for (n = gnode(h, 0); n < limit; n++) {
621 if (!ttisnil(gval(n)) && (iscleared(gkey(n)))) { 615 if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
622 setnilvalue(gval(n)); /* remove value ... */ 616 setnilvalue(gval(n)); /* remove value ... */
623 removeentry(n); /* and remove entry from table */ 617 removeentry(n); /* and remove entry from table */
624 } 618 }
@@ -631,18 +625,18 @@ static void clearkeys (GCObject *l, GCObject *f) {
631** clear entries with unmarked values from all weaktables in list 'l' up 625** clear entries with unmarked values from all weaktables in list 'l' up
632** to element 'f' 626** to element 'f'
633*/ 627*/
634static void clearvalues (GCObject *l, GCObject *f) { 628static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
635 for (; l != f; l = gco2t(l)->gclist) { 629 for (; l != f; l = gco2t(l)->gclist) {
636 Table *h = gco2t(l); 630 Table *h = gco2t(l);
637 Node *n, *limit = gnodelast(h); 631 Node *n, *limit = gnodelast(h);
638 int i; 632 int i;
639 for (i = 0; i < h->sizearray; i++) { 633 for (i = 0; i < h->sizearray; i++) {
640 TValue *o = &h->array[i]; 634 TValue *o = &h->array[i];
641 if (iscleared(o)) /* value was collected? */ 635 if (iscleared(g, o)) /* value was collected? */
642 setnilvalue(o); /* remove value */ 636 setnilvalue(o); /* remove value */
643 } 637 }
644 for (n = gnode(h, 0); n < limit; n++) { 638 for (n = gnode(h, 0); n < limit; n++) {
645 if (!ttisnil(gval(n)) && iscleared(gval(n))) { 639 if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
646 setnilvalue(gval(n)); /* remove value ... */ 640 setnilvalue(gval(n)); /* remove value ... */
647 removeentry(n); /* and remove entry from table */ 641 removeentry(n); /* and remove entry from table */
648 } 642 }
@@ -945,8 +939,8 @@ static void atomic (lua_State *L) {
945 convergeephemerons(g); 939 convergeephemerons(g);
946 /* at this point, all strongly accessible objects are marked. */ 940 /* at this point, all strongly accessible objects are marked. */
947 /* clear values from weak tables, before checking finalizers */ 941 /* clear values from weak tables, before checking finalizers */
948 clearvalues(g->weak, NULL); 942 clearvalues(g, g->weak, NULL);
949 clearvalues(g->allweak, NULL); 943 clearvalues(g, g->allweak, NULL);
950 origweak = g->weak; origall = g->allweak; 944 origweak = g->weak; origall = g->allweak;
951 separatetobefnz(L, 0); /* separate objects to be finalized */ 945 separatetobefnz(L, 0); /* separate objects to be finalized */
952 markbeingfnz(g); /* mark userdata that will be finalized */ 946 markbeingfnz(g); /* mark userdata that will be finalized */
@@ -954,11 +948,11 @@ static void atomic (lua_State *L) {
954 convergeephemerons(g); 948 convergeephemerons(g);
955 /* at this point, all resurrected objects are marked. */ 949 /* at this point, all resurrected objects are marked. */
956 /* remove dead objects from weak tables */ 950 /* remove dead objects from weak tables */
957 clearkeys(g->ephemeron, NULL); /* clear keys from all ephemeron tables */ 951 clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */
958 clearkeys(g->allweak, NULL); /* clear keys from all allweak tables */ 952 clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */
959 /* clear values from resurrected weak tables */ 953 /* clear values from resurrected weak tables */
960 clearvalues(g->weak, origweak); 954 clearvalues(g, g->weak, origweak);
961 clearvalues(g->allweak, origall); 955 clearvalues(g, g->allweak, origall);
962 g->sweepstrgc = 0; /* prepare to sweep strings */ 956 g->sweepstrgc = 0; /* prepare to sweep strings */
963 g->gcstate = GCSsweepstring; 957 g->gcstate = GCSsweepstring;
964 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 958 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */