diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2008-02-11 13:46:03 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2008-02-11 13:46:03 -0200 |
| commit | 5f0a2f6248941f758d0b1cee77a8890ff8b05c68 (patch) | |
| tree | 6ae8a7cd9d9a6d91499a5c0b11a41a814f967c3e | |
| parent | a73930228aada18cb9300f53dbcc6fafcb75caf9 (diff) | |
| download | lua-5f0a2f6248941f758d0b1cee77a8890ff8b05c68.tar.gz lua-5f0a2f6248941f758d0b1cee77a8890ff8b05c68.tar.bz2 lua-5f0a2f6248941f758d0b1cee77a8890ff8b05c68.zip | |
more options for 'kinds' of Garbage Collection + more agressive
shrinking of stacks and string hash
| -rw-r--r-- | lgc.c | 55 |
1 files changed, 26 insertions, 29 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.41 2007/10/29 16:51:20 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.42 2007/10/31 15:41:19 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 | */ |
| @@ -308,17 +308,18 @@ static void traverseclosure (global_State *g, Closure *cl) { | |||
| 308 | 308 | ||
| 309 | 309 | ||
| 310 | static void checkstacksizes (lua_State *L, StkId max) { | 310 | static void checkstacksizes (lua_State *L, StkId max) { |
| 311 | int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ | 311 | /* should not change the stack when handling overflow or |
| 312 | int s_used = cast_int(max - L->stack); /* part of stack in use */ | 312 | during an emergency gc cycle */ |
| 313 | if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ | 313 | if (L->size_ci > LUAI_MAXCALLS || G(L)->gckind == KGC_EMERGENCY) |
| 314 | return; /* do not touch the stacks */ | 314 | return; /* do not touch the stacks */ |
| 315 | if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) | 315 | else { |
| 316 | luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ | 316 | int ci_used = cast_int(L->ci - L->base_ci) + 1; /* number of `ci' in use */ |
| 317 | condhardstacktests(luaD_reallocCI(L, ci_used + 1)); | 317 | int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */ |
| 318 | if (4*s_used < L->stacksize && | 318 | if (2*ci_used < L->size_ci) |
| 319 | 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) | 319 | luaD_reallocCI(L, 2*ci_used); |
| 320 | luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ | 320 | if (2*s_used < (L->stacksize - EXTRA_STACK)) |
| 321 | condhardstacktests(luaD_reallocstack(L, s_used)); | 321 | luaD_reallocstack(L, 2*s_used); |
| 322 | } | ||
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | 325 | ||
| @@ -337,8 +338,7 @@ static void traversestack (global_State *g, lua_State *l) { | |||
| 337 | markvalue(g, o); | 338 | markvalue(g, o); |
| 338 | for (; o <= lim; o++) | 339 | for (; o <= lim; o++) |
| 339 | setnilvalue(o); | 340 | setnilvalue(o); |
| 340 | if (!g->emergencygc) /* cannot change stack in emergency... */ | 341 | checkstacksizes(l, lim); |
| 341 | checkstacksizes(l, lim); /* ...(mutator does not expect that change) */ | ||
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | 344 | ||
| @@ -498,15 +498,9 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | |||
| 498 | 498 | ||
| 499 | static void checkSizes (lua_State *L) { | 499 | static void checkSizes (lua_State *L) { |
| 500 | global_State *g = G(L); | 500 | global_State *g = G(L); |
| 501 | /* check size of string hash */ | 501 | if (g->strt.nuse < cast(lu_int32, g->strt.size)) |
| 502 | if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && | 502 | luaS_resize(L, 1 << luaO_ceillog2(g->strt.nuse)); |
| 503 | g->strt.size > MINSTRTABSIZE*2) | 503 | luaZ_freebuffer(L, &g->buff); |
| 504 | luaS_resize(L, g->strt.size/2); /* table is too big */ | ||
| 505 | /* check size of buffer */ | ||
| 506 | if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ | ||
| 507 | size_t newsize = luaZ_sizebuffer(&g->buff) / 2; | ||
| 508 | luaZ_resizebuffer(L, &g->buff, newsize); | ||
| 509 | } | ||
| 510 | } | 504 | } |
| 511 | 505 | ||
| 512 | 506 | ||
| @@ -698,7 +692,7 @@ static l_mem singlestep (lua_State *L) { | |||
| 698 | void luaC_step (lua_State *L) { | 692 | void luaC_step (lua_State *L) { |
| 699 | global_State *g = G(L); | 693 | global_State *g = G(L); |
| 700 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; | 694 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; |
| 701 | lua_assert(!g->emergencygc); | 695 | lua_assert(g->gckind == KGC_NORMAL); |
| 702 | if (lim == 0) | 696 | if (lim == 0) |
| 703 | lim = (MAX_LUMEM-1)/2; /* no limit */ | 697 | lim = (MAX_LUMEM-1)/2; /* no limit */ |
| 704 | g->gcdept += g->totalbytes - g->GCthreshold; | 698 | g->gcdept += g->totalbytes - g->GCthreshold; |
| @@ -723,9 +717,9 @@ void luaC_step (lua_State *L) { | |||
| 723 | 717 | ||
| 724 | 718 | ||
| 725 | void luaC_fullgc (lua_State *L, int isemergency) { | 719 | void luaC_fullgc (lua_State *L, int isemergency) { |
| 726 | int stopstate; | ||
| 727 | global_State *g = G(L); | 720 | global_State *g = G(L); |
| 728 | g->emergencygc = isemergency; | 721 | lua_assert(g->gckind == KGC_NORMAL); |
| 722 | g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED; | ||
| 729 | if (g->gcstate <= GCSpropagate) { | 723 | if (g->gcstate <= GCSpropagate) { |
| 730 | /* reset sweep marks to sweep all elements (returning them to white) */ | 724 | /* reset sweep marks to sweep all elements (returning them to white) */ |
| 731 | g->sweepstrgc = 0; | 725 | g->sweepstrgc = 0; |
| @@ -743,12 +737,15 @@ void luaC_fullgc (lua_State *L, int isemergency) { | |||
| 743 | singlestep(L); | 737 | singlestep(L); |
| 744 | } | 738 | } |
| 745 | markroot(L); | 739 | markroot(L); |
| 746 | /* do not run finalizers during emergency GC */ | 740 | /* run collector up to finalizers */ |
| 747 | stopstate = isemergency ? GCSfinalize : GCSpause; | 741 | while (g->gcstate != GCSfinalize) |
| 748 | while (g->gcstate != stopstate) | ||
| 749 | singlestep(L); | 742 | singlestep(L); |
| 743 | g->gckind = KGC_NORMAL; | ||
| 744 | if (!isemergency) { /* do not run finalizers during emergency GC */ | ||
| 745 | while (g->gcstate != GCSpause) | ||
| 746 | singlestep(L); | ||
| 747 | } | ||
| 750 | setthreshold(g); | 748 | setthreshold(g); |
| 751 | g->emergencygc = 0; | ||
| 752 | } | 749 | } |
| 753 | 750 | ||
| 754 | 751 | ||
