diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-12-29 16:00:23 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-12-29 16:00:23 -0200 |
commit | 868ff40339fc72b7bf3c916afcdc2a992398346c (patch) | |
tree | 86864c97d7b1e7620a8c09e43e40cd7d6d3a5f89 | |
parent | aa6faa6331e3e5e326bf5830474ffd9b04425678 (diff) | |
download | lua-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.c | 10 | ||||
-rw-r--r-- | lgc.c | 32 | ||||
-rw-r--r-- | lgc.h | 3 |
3 files changed, 25 insertions, 20 deletions
@@ -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: { |
@@ -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 | */ |
321 | static void markroot (lua_State *L) { | 321 | static 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 | ||
989 | void luaC_step (lua_State *L) { | 988 | /* |
989 | ** performs a basic GC step even if the collector is stopped | ||
990 | */ | ||
991 | void 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 | */ | ||
1004 | void luaC_step (lua_State *L) { | ||
1005 | if (G(L)->gcrunning) luaC_forcestep(L); | ||
998 | } | 1006 | } |
999 | 1007 | ||
1000 | 1008 | ||
@@ -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 @@ | |||
128 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); | 128 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); |
129 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | 129 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
130 | LUAI_FUNC void luaC_step (lua_State *L); | 130 | LUAI_FUNC void luaC_step (lua_State *L); |
131 | LUAI_FUNC void luaC_forcestep (lua_State *L); | ||
131 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); | 132 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); |
132 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 133 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
133 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, | 134 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, |