diff options
| -rw-r--r-- | lfunc.c | 6 | ||||
| -rw-r--r-- | lgc.c | 54 | ||||
| -rw-r--r-- | lgc.h | 14 | ||||
| -rw-r--r-- | lstate.c | 9 |
4 files changed, 40 insertions, 43 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $ | 2 | ** $Id: lfunc.c,v 2.7 2005/01/19 15:54:26 roberto Exp roberto $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -57,7 +57,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
| 57 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { | 57 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { |
| 58 | lua_assert(p->v != &p->u.value); | 58 | lua_assert(p->v != &p->u.value); |
| 59 | if (p->v == level) { /* found a corresponding upvalue? */ | 59 | if (p->v == level) { /* found a corresponding upvalue? */ |
| 60 | if (isdead(G(L), obj2gco(p))) /* is it dead? */ | 60 | if (isdead(g, obj2gco(p))) /* is it dead? */ |
| 61 | changewhite(obj2gco(p)); /* ressurect it */ | 61 | changewhite(obj2gco(p)); /* ressurect it */ |
| 62 | return p; | 62 | return p; |
| 63 | } | 63 | } |
| @@ -106,7 +106,7 @@ void luaF_close (lua_State *L, StkId level) { | |||
| 106 | setobj(L, &uv->u.value, uv->v); | 106 | setobj(L, &uv->u.value, uv->v); |
| 107 | if (isgray(o)) { | 107 | if (isgray(o)) { |
| 108 | gray2black(o); /* closed upvalues are never gray */ | 108 | gray2black(o); /* closed upvalues are never gray */ |
| 109 | luaC_barrier(L, uv, uv->v); | 109 | luaC_barrier(L, uv, &uv->u.value); |
| 110 | } | 110 | } |
| 111 | uv->v = &uv->u.value; /* now current value lives here */ | 111 | uv->v = &uv->u.value; /* now current value lives here */ |
| 112 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ | 112 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.21 2005/01/14 14:19:42 roberto Exp $ | 2 | ** $Id: lgc.c,v 2.22 2005/01/18 17:18:09 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 | */ |
| @@ -29,13 +29,11 @@ | |||
| 29 | #define GCFINALIZECOST 100 | 29 | #define GCFINALIZECOST 100 |
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | #define FIXEDMASK bitmask(FIXEDBIT) | ||
| 33 | |||
| 34 | #define maskmarks \ | 32 | #define maskmarks \ |
| 35 | cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT))) | 33 | cast(lu_byte, ~(bitmask(BLACKBIT)|WHITEBITS)) |
| 36 | 34 | ||
| 37 | #define makewhite(g,x) \ | 35 | #define makewhite(g,x) \ |
| 38 | ((x)->gch.marked = ((x)->gch.marked & maskmarks) | g->currentwhite) | 36 | ((x)->gch.marked = ((x)->gch.marked & maskmarks) | luaC_white(g)) |
| 39 | 37 | ||
| 40 | #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | 38 | #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) |
| 41 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) | 39 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) |
| @@ -60,6 +58,8 @@ | |||
| 60 | reallymarkobject(g, obj2gco(t)); } | 58 | reallymarkobject(g, obj2gco(t)); } |
| 61 | 59 | ||
| 62 | 60 | ||
| 61 | #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpace) | ||
| 62 | |||
| 63 | 63 | ||
| 64 | static void removeentry (Node *n) { | 64 | static void removeentry (Node *n) { |
| 65 | lua_assert(ttisnil(gval(n))); | 65 | lua_assert(ttisnil(gval(n))); |
| @@ -400,24 +400,23 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
| 400 | 400 | ||
| 401 | 401 | ||
| 402 | 402 | ||
| 403 | #define sweepwholelist(L,p) sweeplist(L,p,LUA_MAXINT32) | 403 | #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) |
| 404 | 404 | ||
| 405 | 405 | ||
| 406 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) { | 406 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { |
| 407 | GCObject *curr; | 407 | GCObject *curr; |
| 408 | global_State *g = G(L); | 408 | global_State *g = G(L); |
| 409 | int whitebit = otherwhite(g); | 409 | int deadmask = otherwhite(g); |
| 410 | int deadmask = whitebit | FIXEDMASK; | ||
| 411 | while ((curr = *p) != NULL && count-- > 0) { | 410 | while ((curr = *p) != NULL && count-- > 0) { |
| 412 | if ((curr->gch.marked ^ whitebit) & deadmask) { | 411 | if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ |
| 412 | sweepwholelist(L, &gco2th(curr)->openupval); | ||
| 413 | if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ | ||
| 413 | lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); | 414 | lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); |
| 414 | makewhite(g, curr); | 415 | makewhite(g, curr); /* make it white (for next cycle) */ |
| 415 | if (curr->gch.tt == LUA_TTHREAD) | ||
| 416 | sweepwholelist(L, &gco2th(curr)->openupval); | ||
| 417 | p = &curr->gch.next; | 416 | p = &curr->gch.next; |
| 418 | } | 417 | } |
| 419 | else { | 418 | else { /* must erase `curr' */ |
| 420 | lua_assert(isdead(g, curr)); | 419 | lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); |
| 421 | *p = curr->gch.next; | 420 | *p = curr->gch.next; |
| 422 | if (curr == g->rootgc) /* is the first element of the list? */ | 421 | if (curr == g->rootgc) /* is the first element of the list? */ |
| 423 | g->rootgc = curr->gch.next; /* adjust first */ | 422 | g->rootgc = curr->gch.next; /* adjust first */ |
| @@ -428,21 +427,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) { | |||
| 428 | } | 427 | } |
| 429 | 428 | ||
| 430 | 429 | ||
| 431 | |||
| 432 | static void freelist (lua_State *L, GCObject **p) { | ||
| 433 | while (*p) { | ||
| 434 | GCObject *curr = *p; | ||
| 435 | *p = (*p)->gch.next; | ||
| 436 | if (curr != obj2gco(L)) | ||
| 437 | freeobj(L, curr); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | |||
| 442 | static void checkSizes (lua_State *L) { | 430 | static void checkSizes (lua_State *L) { |
| 443 | global_State *g = G(L); | 431 | global_State *g = G(L); |
| 444 | /* check size of string hash */ | 432 | /* check size of string hash */ |
| 445 | if (g->strt.nuse < cast(lu_int32, G(L)->strt.size/4) && | 433 | if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && |
| 446 | g->strt.size > MINSTRTABSIZE*2) | 434 | g->strt.size > MINSTRTABSIZE*2) |
| 447 | luaS_resize(L, g->strt.size/2); /* table is too big */ | 435 | luaS_resize(L, g->strt.size/2); /* table is too big */ |
| 448 | /* check size of buffer */ | 436 | /* check size of buffer */ |
| @@ -487,9 +475,10 @@ void luaC_callGCTM (lua_State *L) { | |||
| 487 | void luaC_freeall (lua_State *L) { | 475 | void luaC_freeall (lua_State *L) { |
| 488 | global_State *g = G(L); | 476 | global_State *g = G(L); |
| 489 | int i; | 477 | int i; |
| 490 | freelist(L, &g->rootgc); | 478 | g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ |
| 479 | sweepwholelist(L, &g->rootgc); | ||
| 491 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | 480 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ |
| 492 | freelist(L, &G(L)->strt.hash[i]); | 481 | sweepwholelist(L, &g->strt.hash[i]); |
| 493 | } | 482 | } |
| 494 | 483 | ||
| 495 | 484 | ||
| @@ -604,6 +593,8 @@ static l_mem singlestep (lua_State *L) { | |||
| 604 | void luaC_step (lua_State *L) { | 593 | void luaC_step (lua_State *L) { |
| 605 | global_State *g = G(L); | 594 | global_State *g = G(L); |
| 606 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; | 595 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; |
| 596 | if (lim == 0) | ||
| 597 | lim = (MAX_LUMEM-1)/2; /* no limit */ | ||
| 607 | g->gcdept += g->totalbytes - g->GCthreshold; | 598 | g->gcdept += g->totalbytes - g->GCthreshold; |
| 608 | do { | 599 | do { |
| 609 | lim -= singlestep(L); | 600 | lim -= singlestep(L); |
| @@ -620,7 +611,7 @@ void luaC_step (lua_State *L) { | |||
| 620 | } | 611 | } |
| 621 | else { | 612 | else { |
| 622 | lua_assert(g->totalbytes >= g->estimate); | 613 | lua_assert(g->totalbytes >= g->estimate); |
| 623 | g->GCthreshold = (g->estimate/100) * g->gcpace; | 614 | setthreshold(g); |
| 624 | } | 615 | } |
| 625 | } | 616 | } |
| 626 | 617 | ||
| @@ -637,6 +628,7 @@ void luaC_fullgc (lua_State *L) { | |||
| 637 | g->weak = NULL; | 628 | g->weak = NULL; |
| 638 | g->gcstate = GCSsweepstring; | 629 | g->gcstate = GCSsweepstring; |
| 639 | } | 630 | } |
| 631 | lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); | ||
| 640 | /* finish any pending sweep phase */ | 632 | /* finish any pending sweep phase */ |
| 641 | while (g->gcstate != GCSfinalize) { | 633 | while (g->gcstate != GCSfinalize) { |
| 642 | lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); | 634 | lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); |
| @@ -646,7 +638,7 @@ void luaC_fullgc (lua_State *L) { | |||
| 646 | while (g->gcstate != GCSpause) { | 638 | while (g->gcstate != GCSpause) { |
| 647 | singlestep(L); | 639 | singlestep(L); |
| 648 | } | 640 | } |
| 649 | g->GCthreshold = 2*g->estimate; | 641 | setthreshold(g); |
| 650 | } | 642 | } |
| 651 | 643 | ||
| 652 | 644 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 2.9 2004/09/15 20:38:15 roberto Exp $ | 2 | ** $Id: lgc.h,v 2.10 2005/01/19 15:54:26 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 | */ |
| @@ -47,8 +47,10 @@ | |||
| 47 | ** bit 3 - for tables: has weak keys | 47 | ** bit 3 - for tables: has weak keys |
| 48 | ** bit 4 - for tables: has weak values | 48 | ** bit 4 - for tables: has weak values |
| 49 | ** bit 5 - object is fixed (should not be collected) | 49 | ** bit 5 - object is fixed (should not be collected) |
| 50 | ** bit 6 - object is "super" fixed (only the main thread) | ||
| 50 | */ | 51 | */ |
| 51 | 52 | ||
| 53 | |||
| 52 | #define WHITE0BIT 0 | 54 | #define WHITE0BIT 0 |
| 53 | #define WHITE1BIT 1 | 55 | #define WHITE1BIT 1 |
| 54 | #define BLACKBIT 2 | 56 | #define BLACKBIT 2 |
| @@ -56,21 +58,23 @@ | |||
| 56 | #define KEYWEAKBIT 3 | 58 | #define KEYWEAKBIT 3 |
| 57 | #define VALUEWEAKBIT 4 | 59 | #define VALUEWEAKBIT 4 |
| 58 | #define FIXEDBIT 5 | 60 | #define FIXEDBIT 5 |
| 61 | #define SFIXEDBIT 6 | ||
| 62 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | ||
| 59 | 63 | ||
| 60 | 64 | ||
| 61 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | 65 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) |
| 62 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | 66 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) |
| 63 | #define isgray(x) (!isblack(x) && !iswhite(x)) | 67 | #define isgray(x) (!isblack(x) && !iswhite(x)) |
| 64 | 68 | ||
| 65 | #define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT)) | 69 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) |
| 66 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g)) | 70 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) |
| 67 | 71 | ||
| 68 | #define changewhite(x) ((x)->gch.marked ^= bit2mask(WHITE0BIT, WHITE1BIT)) | 72 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) |
| 69 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) | 73 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) |
| 70 | 74 | ||
| 71 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | 75 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) |
| 72 | 76 | ||
| 73 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite) | 77 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
| 74 | 78 | ||
| 75 | 79 | ||
| 76 | #define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \ | 80 | #define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.22 2005/01/14 14:19:42 roberto Exp $ | 2 | ** $Id: lstate.c,v 2.23 2005/01/18 17:18:09 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 | */ |
| @@ -114,7 +114,7 @@ static void close_state (lua_State *L) { | |||
| 114 | global_State *g = G(L); | 114 | global_State *g = G(L); |
| 115 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | 115 | luaF_close(L, L->stack); /* close all upvalues for this thread */ |
| 116 | luaC_freeall(L); /* collect all objects */ | 116 | luaC_freeall(L); /* collect all objects */ |
| 117 | lua_assert(g->rootgc == NULL); | 117 | lua_assert(g->rootgc == obj2gco(L)); |
| 118 | lua_assert(g->strt.nuse == 0); | 118 | lua_assert(g->strt.nuse == 0); |
| 119 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); | 119 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); |
| 120 | luaZ_freebuffer(L, &g->buff); | 120 | luaZ_freebuffer(L, &g->buff); |
| @@ -156,8 +156,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 156 | g = &((LG *)L)->g; | 156 | g = &((LG *)L)->g; |
| 157 | L->next = NULL; | 157 | L->next = NULL; |
| 158 | L->tt = LUA_TTHREAD; | 158 | L->tt = LUA_TTHREAD; |
| 159 | L->marked = g->currentwhite = bitmask(WHITE0BIT); | 159 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); |
| 160 | setbit(L->marked, FIXEDBIT); | 160 | L->marked = luaC_white(g); |
| 161 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT); | ||
| 161 | preinit_state(L, g); | 162 | preinit_state(L, g); |
| 162 | g->realloc = f; | 163 | g->realloc = f; |
| 163 | g->ud = ud; | 164 | g->ud = ud; |
