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 /lgc.c | |
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
Diffstat (limited to 'lgc.c')
-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 | ||