diff options
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 25 |
1 files changed, 18 insertions, 7 deletions
@@ -91,6 +91,13 @@ | |||
91 | #define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) | 91 | #define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) |
92 | 92 | ||
93 | 93 | ||
94 | /* | ||
95 | ** Access to collectable objects in array part of tables | ||
96 | */ | ||
97 | #define gcvalarr(t,i) \ | ||
98 | ((*getArrTag(t,i) & BIT_ISCOLLECTABLE) ? getArrVal(t,i)->gc : NULL) | ||
99 | |||
100 | |||
94 | #define markvalue(g,o) { checkliveness(g->mainthread,o); \ | 101 | #define markvalue(g,o) { checkliveness(g->mainthread,o); \ |
95 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } | 102 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } |
96 | 103 | ||
@@ -486,9 +493,10 @@ static int traverseephemeron (global_State *g, Table *h, int inv) { | |||
486 | unsigned int nsize = sizenode(h); | 493 | unsigned int nsize = sizenode(h); |
487 | /* traverse array part */ | 494 | /* traverse array part */ |
488 | for (i = 0; i < asize; i++) { | 495 | for (i = 0; i < asize; i++) { |
489 | if (valiswhite(&h->array[i])) { | 496 | GCObject *o = gcvalarr(h, i + 1); |
497 | if (o != NULL && iswhite(o)) { | ||
490 | marked = 1; | 498 | marked = 1; |
491 | reallymarkobject(g, gcvalue(&h->array[i])); | 499 | reallymarkobject(g, o); |
492 | } | 500 | } |
493 | } | 501 | } |
494 | /* traverse hash part; if 'inv', traverse descending | 502 | /* traverse hash part; if 'inv', traverse descending |
@@ -524,8 +532,11 @@ static void traversestrongtable (global_State *g, Table *h) { | |||
524 | Node *n, *limit = gnodelast(h); | 532 | Node *n, *limit = gnodelast(h); |
525 | unsigned int i; | 533 | unsigned int i; |
526 | unsigned int asize = luaH_realasize(h); | 534 | unsigned int asize = luaH_realasize(h); |
527 | for (i = 0; i < asize; i++) /* traverse array part */ | 535 | for (i = 0; i < asize; i++) { /* traverse array part */ |
528 | markvalue(g, &h->array[i]); | 536 | GCObject *o = gcvalarr(h, i + 1); |
537 | if (o != NULL && iswhite(o)) | ||
538 | reallymarkobject(g, o); | ||
539 | } | ||
529 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ | 540 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ |
530 | if (isempty(gval(n))) /* entry is empty? */ | 541 | if (isempty(gval(n))) /* entry is empty? */ |
531 | clearkey(n); /* clear its key */ | 542 | clearkey(n); /* clear its key */ |
@@ -746,9 +757,9 @@ static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { | |||
746 | unsigned int i; | 757 | unsigned int i; |
747 | unsigned int asize = luaH_realasize(h); | 758 | unsigned int asize = luaH_realasize(h); |
748 | for (i = 0; i < asize; i++) { | 759 | for (i = 0; i < asize; i++) { |
749 | TValue *o = &h->array[i]; | 760 | GCObject *o = gcvalarr(h, i + 1); |
750 | if (iscleared(g, gcvalueN(o))) /* value was collected? */ | 761 | if (iscleared(g, o)) /* value was collected? */ |
751 | setempty(o); /* remove entry */ | 762 | *getArrTag(h, i + 1) = LUA_VEMPTY; /* remove entry */ |
752 | } | 763 | } |
753 | for (n = gnode(h, 0); n < limit; n++) { | 764 | for (n = gnode(h, 0); n < limit; n++) { |
754 | if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ | 765 | if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ |