aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-12-29 16:00:23 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-12-29 16:00:23 -0200
commit868ff40339fc72b7bf3c916afcdc2a992398346c (patch)
tree86864c97d7b1e7620a8c09e43e40cd7d6d3a5f89
parentaa6faa6331e3e5e326bf5830474ffd9b04425678 (diff)
downloadlua-868ff40339fc72b7bf3c916afcdc2a992398346c.tar.gz
lua-868ff40339fc72b7bf3c916afcdc2a992398346c.tar.bz2
lua-868ff40339fc72b7bf3c916afcdc2a992398346c.zip
full collection does not restart collector + avoid changing GC
state if an error happens in a step
-rw-r--r--lapi.c10
-rw-r--r--lgc.c32
-rw-r--r--lgc.h3
3 files changed, 25 insertions, 20 deletions
diff --git a/lapi.c b/lapi.c
index 73cf1108..9b824577 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.142 2010/12/20 18:17:46 roberto Exp roberto $ 2** $Id: lapi.c,v 2.143 2010/12/20 19:40:07 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -969,7 +969,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
969 break; 969 break;
970 } 970 }
971 case LUA_GCCOLLECT: { 971 case LUA_GCCOLLECT: {
972 g->gcrunning = 1; /* restart collector if stopped ?? */
973 luaC_fullgc(L, 0); 972 luaC_fullgc(L, 0);
974 break; 973 break;
975 } 974 }
@@ -983,22 +982,19 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
983 break; 982 break;
984 } 983 }
985 case LUA_GCSTEP: { 984 case LUA_GCSTEP: {
986 int running = g->gcrunning;
987 g->gcrunning = 1; /* allow steps */
988 if (g->gckind == KGC_GEN) { /* generational mode? */ 985 if (g->gckind == KGC_GEN) { /* generational mode? */
989 res = (g->lastmajormem == 0); /* 1 if will do major collection */ 986 res = (g->lastmajormem == 0); /* 1 if will do major collection */
990 luaC_step(L); /* do a single step */ 987 luaC_forcestep(L); /* do a single step */
991 } 988 }
992 else { 989 else {
993 while (data-- >= 0) { 990 while (data-- >= 0) {
994 luaC_step(L); 991 luaC_forcestep(L);
995 if (g->gcstate == GCSpause) { /* end of cycle? */ 992 if (g->gcstate == GCSpause) { /* end of cycle? */
996 res = 1; /* signal it */ 993 res = 1; /* signal it */
997 break; 994 break;
998 } 995 }
999 } 996 }
1000 } 997 }
1001 g->gcrunning = running; /* restore previous state */
1002 break; 998 break;
1003 } 999 }
1004 case LUA_GCSETPAUSE: { 1000 case LUA_GCSETPAUSE: {
diff --git a/lgc.c b/lgc.c
index 933b035b..55101120 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.106 2010/12/20 18:17:46 roberto Exp roberto $ 2** $Id: lgc.c,v 2.107 2010/12/20 19:40:07 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*/
@@ -318,8 +318,7 @@ static void remarkupvals (global_State *g) {
318** mark root set and reset all gray lists, to start a new 318** mark root set and reset all gray lists, to start a new
319** incremental (or full) collection 319** incremental (or full) collection
320*/ 320*/
321static void markroot (lua_State *L) { 321static void markroot (global_State *g) {
322 global_State *g = G(L);
323 g->gray = g->grayagain = NULL; 322 g->gray = g->grayagain = NULL;
324 g->weak = g->allweak = g->ephemeron = NULL; 323 g->weak = g->allweak = g->ephemeron = NULL;
325 markobject(g, g->mainthread); 324 markobject(g, g->mainthread);
@@ -889,7 +888,7 @@ static l_mem singlestep (lua_State *L) {
889 switch (g->gcstate) { 888 switch (g->gcstate) {
890 case GCSpause: { 889 case GCSpause: {
891 if (!isgenerational(g)) 890 if (!isgenerational(g))
892 markroot(L); /* start a new collection */ 891 markroot(g); /* start a new collection */
893 /* in any case, root must be marked */ 892 /* in any case, root must be marked */
894 lua_assert(!iswhite(obj2gco(g->mainthread)) 893 lua_assert(!iswhite(obj2gco(g->mainthread))
895 && !iswhite(gcvalue(&g->l_registry))); 894 && !iswhite(gcvalue(&g->l_registry)));
@@ -986,15 +985,24 @@ static void step (lua_State *L) {
986} 985}
987 986
988 987
989void luaC_step (lua_State *L) { 988/*
989** performs a basic GC step even if the collector is stopped
990*/
991void luaC_forcestep (lua_State *L) {
990 global_State *g = G(L); 992 global_State *g = G(L);
991 if (g->gcrunning) { 993 int i;
992 int i; 994 if (isgenerational(g)) generationalcollection(L);
993 if (isgenerational(g)) generationalcollection(L); 995 else step(L);
994 else step(L); 996 for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++)
995 for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++) 997 GCTM(L, 1); /* Call a few pending finalizers */
996 GCTM(L, 1); /* Call a few pending finalizers */ 998}
997 } 999
1000
1001/*
1002** performs a basic GC step only if collector is running
1003*/
1004void luaC_step (lua_State *L) {
1005 if (G(L)->gcrunning) luaC_forcestep(L);
998} 1006}
999 1007
1000 1008
diff --git a/lgc.h b/lgc.h
index 8a430294..b0520f36 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.47 2010/12/17 12:02:29 roberto Exp roberto $ 2** $Id: lgc.h,v 2.48 2010/12/20 18:17:46 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*/
@@ -128,6 +128,7 @@
128LUAI_FUNC void luaC_separateudata (lua_State *L, int all); 128LUAI_FUNC void luaC_separateudata (lua_State *L, int all);
129LUAI_FUNC void luaC_freeallobjects (lua_State *L); 129LUAI_FUNC void luaC_freeallobjects (lua_State *L);
130LUAI_FUNC void luaC_step (lua_State *L); 130LUAI_FUNC void luaC_step (lua_State *L);
131LUAI_FUNC void luaC_forcestep (lua_State *L);
131LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 132LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
132LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 133LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
133LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, 134LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,