aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/lgc.c b/lgc.c
index 94e0486e..b360eed0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1575,52 +1575,64 @@ static int sweepstep (lua_State *L, global_State *g,
1575 1575
1576static lu_mem singlestep (lua_State *L) { 1576static lu_mem singlestep (lua_State *L) {
1577 global_State *g = G(L); 1577 global_State *g = G(L);
1578 lu_mem work;
1579 lua_assert(!g->gcstopem); /* collector is not reentrant */
1580 g->gcstopem = 1; /* no emergency collections while collecting */
1578 switch (g->gcstate) { 1581 switch (g->gcstate) {
1579 case GCSpause: { 1582 case GCSpause: {
1580 restartcollection(g); 1583 restartcollection(g);
1581 g->gcstate = GCSpropagate; 1584 g->gcstate = GCSpropagate;
1582 return 1; 1585 work = 1;
1586 break;
1583 } 1587 }
1584 case GCSpropagate: { 1588 case GCSpropagate: {
1585 if (g->gray == NULL) { /* no more gray objects? */ 1589 if (g->gray == NULL) { /* no more gray objects? */
1586 g->gcstate = GCSenteratomic; /* finish propagate phase */ 1590 g->gcstate = GCSenteratomic; /* finish propagate phase */
1587 return 0; 1591 work = 0;
1588 } 1592 }
1589 else 1593 else
1590 return propagatemark(g); /* traverse one gray object */ 1594 work = propagatemark(g); /* traverse one gray object */
1595 break;
1591 } 1596 }
1592 case GCSenteratomic: { 1597 case GCSenteratomic: {
1593 lu_mem work = atomic(L); /* work is what was traversed by 'atomic' */ 1598 work = atomic(L); /* work is what was traversed by 'atomic' */
1594 entersweep(L); 1599 entersweep(L);
1595 g->GCestimate = gettotalbytes(g); /* first estimate */; 1600 g->GCestimate = gettotalbytes(g); /* first estimate */;
1596 return work; 1601 break;
1597 } 1602 }
1598 case GCSswpallgc: { /* sweep "regular" objects */ 1603 case GCSswpallgc: { /* sweep "regular" objects */
1599 return sweepstep(L, g, GCSswpfinobj, &g->finobj); 1604 work = sweepstep(L, g, GCSswpfinobj, &g->finobj);
1605 break;
1600 } 1606 }
1601 case GCSswpfinobj: { /* sweep objects with finalizers */ 1607 case GCSswpfinobj: { /* sweep objects with finalizers */
1602 return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); 1608 work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
1609 break;
1603 } 1610 }
1604 case GCSswptobefnz: { /* sweep objects to be finalized */ 1611 case GCSswptobefnz: { /* sweep objects to be finalized */
1605 return sweepstep(L, g, GCSswpend, NULL); 1612 work = sweepstep(L, g, GCSswpend, NULL);
1613 break;
1606 } 1614 }
1607 case GCSswpend: { /* finish sweeps */ 1615 case GCSswpend: { /* finish sweeps */
1608 checkSizes(L, g); 1616 checkSizes(L, g);
1609 g->gcstate = GCScallfin; 1617 g->gcstate = GCScallfin;
1610 return 0; 1618 work = 0;
1619 break;
1611 } 1620 }
1612 case GCScallfin: { /* call remaining finalizers */ 1621 case GCScallfin: { /* call remaining finalizers */
1613 if (g->tobefnz && !g->gcemergency) { 1622 if (g->tobefnz && !g->gcemergency) {
1614 int n = runafewfinalizers(L, GCFINMAX); 1623 g->gcstopem = 0; /* ok collections during finalizers */
1615 return n * GCFINALIZECOST; 1624 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST;
1616 } 1625 }
1617 else { /* emergency mode or no more finalizers */ 1626 else { /* emergency mode or no more finalizers */
1618 g->gcstate = GCSpause; /* finish collection */ 1627 g->gcstate = GCSpause; /* finish collection */
1619 return 0; 1628 work = 0;
1620 } 1629 }
1630 break;
1621 } 1631 }
1622 default: lua_assert(0); return 0; 1632 default: lua_assert(0); return 0;
1623 } 1633 }
1634 g->gcstopem = 0;
1635 return work;
1624} 1636}
1625 1637
1626 1638