diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-12 16:29:34 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-12 16:29:34 -0200 |
| commit | beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7 (patch) | |
| tree | 2ddcd1ac23b6a4275fc6d16b0316651b7cfb87f6 | |
| parent | 47fc57a2529c83376883f36954082cfe80ae588f (diff) | |
| download | lua-beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7.tar.gz lua-beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7.tar.bz2 lua-beb2aa5a46d0f0a8464f4045b1cfb790e97f08c7.zip | |
atomic operations are not GC "states"
| -rw-r--r-- | lgc.c | 122 | ||||
| -rw-r--r-- | lgc.h | 12 | ||||
| -rw-r--r-- | lstate.c | 4 |
3 files changed, 61 insertions, 77 deletions
| @@ -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 | ||
| 106 | static void reallymarkobject (global_State *g, GCObject *o) { | 106 | static 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 | ||
| 500 | static void GCTM (lua_State *L) { | 498 | static 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 */ |
| 544 | static void markroot (lua_State *L) { | 538 | static 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 | ||
| 556 | static void atomic (lua_State *L) { | 550 | static 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 | ||
| 580 | static 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 | |||
| 591 | static 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 | |||
| 602 | void luaC_step (lua_State *L) { | 572 | void 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 | ||
| 629 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 616 | void 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 */ |
| @@ -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 | /* |
| @@ -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); |
