aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-12 16:29:34 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-12 16:29:34 -0200
commitbeb2aa5a46d0f0a8464f4045b1cfb790e97f08c7 (patch)
tree2ddcd1ac23b6a4275fc6d16b0316651b7cfb87f6
parent47fc57a2529c83376883f36954082cfe80ae588f (diff)
downloadlua-beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7.tar.gz
lua-beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7.tar.bz2
lua-beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7.zip
atomic operations are not GC "states"
-rw-r--r--lgc.c122
-rw-r--r--lgc.h12
-rw-r--r--lstate.c4
3 files changed, 61 insertions, 77 deletions
diff --git a/lgc.c b/lgc.c
index 147593b0..fe6461c0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.187 2003/12/09 16:56:11 roberto Exp roberto $ 2** $Id: lgc.c,v 2.1 2003/12/10 12:13:36 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*/
@@ -22,7 +22,7 @@
22#include "ltm.h" 22#include "ltm.h"
23 23
24 24
25#define GCSTEPSIZE (20*sizeof(TValue)) 25#define GCSTEPSIZE (40*sizeof(TValue))
26 26
27 27
28#define gray2black(x) setbit((x)->gch.marked, BLACKBIT) 28#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
@@ -104,8 +104,7 @@ static size_t objsize (GCObject *o) {
104 104
105 105
106static void reallymarkobject (global_State *g, GCObject *o) { 106static void reallymarkobject (global_State *g, GCObject *o) {
107 lua_assert(iswhite(o)); 107 lua_assert(iswhite(o) && !isdead(g, o));
108 lua_assert(!isdead(g, o));
109 white2gray(o); 108 white2gray(o);
110 switch (o->gch.tt) { 109 switch (o->gch.tt) {
111 case LUA_TSTRING: { 110 case LUA_TSTRING: {
@@ -348,7 +347,6 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
348 lim -= objsize(o); 347 lim -= objsize(o);
349 if (lim <= 0) return lim; 348 if (lim <= 0) return lim;
350 } 349 }
351 g->gcstate = GCSatomic;
352 return lim; 350 return lim;
353} 351}
354 352
@@ -499,26 +497,22 @@ static void checkSizes (lua_State *L) {
499 497
500static void GCTM (lua_State *L) { 498static void GCTM (lua_State *L) {
501 global_State *g = G(L); 499 global_State *g = G(L);
502 if (g->tmudata == NULL) 500 GCObject *o = g->tmudata;
503 g->gcstate = GCSroot; /* will restart GC */ 501 Udata *udata = rawgco2u(o);
504 else { 502 const TValue *tm;
505 GCObject *o = g->tmudata; 503 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
506 Udata *udata = rawgco2u(o); 504 udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */
507 const TValue *tm; 505 g->firstudata->uv.next = o;
508 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ 506 makewhite(g, o);
509 udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ 507 tm = fasttm(L, udata->uv.metatable, TM_GC);
510 g->firstudata->uv.next = o; 508 if (tm != NULL) {
511 makewhite(g, o); 509 lu_byte oldah = L->allowhook;
512 tm = fasttm(L, udata->uv.metatable, TM_GC); 510 L->allowhook = 0; /* stop debug hooks during GC tag method */
513 if (tm != NULL) { 511 setobj2s(L, L->top, tm);
514 lu_byte oldah = L->allowhook; 512 setuvalue(L, L->top+1, udata);
515 L->allowhook = 0; /* stop debug hooks during GC tag method */ 513 L->top += 2;
516 setobj2s(L, L->top, tm); 514 luaD_call(L, L->top - 2, 0);
517 setuvalue(L, L->top+1, udata); 515 L->allowhook = oldah; /* restore hooks */
518 L->top += 2;
519 luaD_call(L, L->top - 2, 0);
520 L->allowhook = oldah; /* restore hooks */
521 }
522 } 516 }
523} 517}
524 518
@@ -543,7 +537,7 @@ void luaC_sweepall (lua_State *L) {
543/* mark root set */ 537/* mark root set */
544static void markroot (lua_State *L) { 538static void markroot (lua_State *L) {
545 global_State *g = G(L); 539 global_State *g = G(L);
546 lua_assert(g->gray == NULL); 540 lua_assert(g->gray == NULL && g->grayagain == NULL);
547 g->weak = NULL; 541 g->weak = NULL;
548 makewhite(g, obj2gco(g->mainthread)); 542 makewhite(g, obj2gco(g->mainthread));
549 markobject(g, g->mainthread); 543 markobject(g, g->mainthread);
@@ -555,8 +549,6 @@ static void markroot (lua_State *L) {
555 549
556static void atomic (lua_State *L) { 550static void atomic (lua_State *L) {
557 global_State *g = G(L); 551 global_State *g = G(L);
558 /* there may be some gray elements due to the write barrier */
559 propagatemarks(g, MAXLMEM); /* traverse them */
560 lua_assert(g->gray == NULL); 552 lua_assert(g->gray == NULL);
561 g->gray = g->grayagain; 553 g->gray = g->grayagain;
562 g->grayagain = NULL; 554 g->grayagain = NULL;
@@ -577,60 +569,54 @@ static void atomic (lua_State *L) {
577} 569}
578 570
579 571
580static void sweepstringstep (lua_State *L) {
581 global_State *g = G(L);
582 l_mem lim = sweepstrings(L, 0, GCSTEPSIZE);
583 if (lim == GCSTEPSIZE) { /* nothing more to sweep? */
584 lua_assert(g->sweepstrgc > g->strt.size);
585 g->sweepstrgc = 0;
586 g->gcstate = GCSsweep; /* end sweep-string phase */
587 }
588}
589
590
591static void sweepstep (lua_State *L) {
592 global_State *g = G(L);
593 l_mem lim = GCSTEPSIZE;
594 g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
595 if (lim == GCSTEPSIZE) { /* nothing more to sweep? */
596 g->gcstate = GCSfinalize; /* end sweep phase */
597 checkSizes(L);
598 }
599}
600
601
602void luaC_step (lua_State *L) { 572void luaC_step (lua_State *L) {
603 global_State *g = G(L); 573 global_State *g = G(L);
574 l_mem lim = (g->nblocks - (g->GCthreshold - GCSTEPSIZE)) * 2;
604 switch (g->gcstate) { 575 switch (g->gcstate) {
605 case GCSroot: 576 case GCSpropagate: {
606 markroot(L); 577 if (g->gray)
607 break; 578 lim = propagatemarks(g, lim);
608 case GCSpropagate: 579 else { /* no more `gray' objects */
609 propagatemarks(g, GCSTEPSIZE); 580 atomic(L); /* finish mark phase */
610 break; 581 lim = 0;
611 case GCSatomic: 582 }
612 atomic(L);
613 break; 583 break;
614 case GCSsweepstring: 584 }
615 sweepstringstep(L); 585 case GCSsweepstring: {
586 lim = sweepstrings(L, 0, lim);
587 if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */
588 g->sweepstrgc = 0;
589 g->gcstate = GCSsweep; /* end sweep-string phase */
590 }
616 break; 591 break;
617 case GCSsweep: 592 }
618 sweepstep(L); 593 case GCSsweep: {
594 g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
595 if (*g->sweepgc == NULL) { /* nothing more to sweep? */
596 g->gcstate = GCSfinalize; /* end sweep phase */
597 checkSizes(L);
598 }
619 break; 599 break;
620 case GCSfinalize: 600 }
621 GCTM(L); 601 case GCSfinalize: {
602 if (g->tmudata) {
603 GCTM(L);
604 lim = 0;
605 }
606 else /* no more `udata' to finalize */
607 markroot(L); /* may restart collection */
622 break; 608 break;
609 }
623 default: lua_assert(0); 610 default: lua_assert(0);
624 } 611 }
625 g->GCthreshold = g->nblocks + GCSTEPSIZE; 612 g->GCthreshold = g->nblocks + GCSTEPSIZE - lim/2;
626} 613}
627 614
628 615
629void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 616void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
630 global_State *g = G(L); 617 global_State *g = G(L);
631 lua_assert(isblack(o) && iswhite(v)); 618 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
632 lua_assert(!isdead(g, v) && !isdead(g, o)); 619 if (g->gcstate >= GCSsweepstring) /* sweeping phases? */
633 if (g->gcstate > GCSatomic) /* sweeping phases? */
634 black2gray(o); /* just mark as gray to avoid other barriers */ 620 black2gray(o); /* just mark as gray to avoid other barriers */
635 else /* breaking invariant! */ 621 else /* breaking invariant! */
636 reallymarkobject(g, v); /* restore it */ 622 reallymarkobject(g, v); /* restore it */
diff --git a/lgc.h b/lgc.h
index e20f2afb..bd8bdadc 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 1.28 2003/12/09 16:56:11 roberto Exp roberto $ 2** $Id: lgc.h,v 2.1 2003/12/10 12:13:36 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*/
@@ -14,12 +14,10 @@
14/* 14/*
15** Possible states of the Garbage Collector 15** Possible states of the Garbage Collector
16*/ 16*/
17#define GCSroot 0 17#define GCSpropagate 0
18#define GCSpropagate 1 18#define GCSsweepstring 1
19#define GCSatomic 2 19#define GCSsweep 2
20#define GCSsweepstring 3 20#define GCSfinalize 3
21#define GCSsweep 4
22#define GCSfinalize 5
23 21
24 22
25/* 23/*
diff --git a/lstate.c b/lstate.c
index 913b42d4..13b15f6f 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.134 2003/12/04 18:52:23 roberto Exp roberto $ 2** $Id: lstate.c,v 2.1 2003/12/10 12:13:36 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -167,7 +167,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
167 setnilvalue(registry(L)); 167 setnilvalue(registry(L));
168 luaZ_initbuffer(L, &g->buff); 168 luaZ_initbuffer(L, &g->buff);
169 g->panic = NULL; 169 g->panic = NULL;
170 g->gcstate = 0; 170 g->gcstate = GCSfinalize;
171 g->rootgc = NULL; 171 g->rootgc = NULL;
172 g->sweepstrgc = 0; 172 g->sweepstrgc = 0;
173 g->currentwhite = bitmask(WHITE0BIT); 173 g->currentwhite = bitmask(WHITE0BIT);