aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2008-02-11 13:46:03 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2008-02-11 13:46:03 -0200
commit5f0a2f6248941f758d0b1cee77a8890ff8b05c68 (patch)
tree6ae8a7cd9d9a6d91499a5c0b11a41a814f967c3e /lgc.c
parenta73930228aada18cb9300f53dbcc6fafcb75caf9 (diff)
downloadlua-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.c55
1 files changed, 26 insertions, 29 deletions
diff --git a/lgc.c b/lgc.c
index d9a23307..770a38fd 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
310static void checkstacksizes (lua_State *L, StkId max) { 310static 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
499static void checkSizes (lua_State *L) { 499static 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) {
698void luaC_step (lua_State *L) { 692void 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
725void luaC_fullgc (lua_State *L, int isemergency) { 719void 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