diff options
-rw-r--r-- | lgc.c | 28 | ||||
-rw-r--r-- | lgc.h | 17 | ||||
-rw-r--r-- | lstring.c | 6 | ||||
-rw-r--r-- | ltests.c | 5 |
4 files changed, 35 insertions, 21 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.62 2009/11/18 13:13:47 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.63 2009/11/26 11:39:20 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 | */ |
@@ -785,6 +785,21 @@ void luaC_step (lua_State *L) { | |||
785 | } | 785 | } |
786 | 786 | ||
787 | 787 | ||
788 | /* | ||
789 | ** advances the garbage collector until it reaches a "valid" state | ||
790 | ** (defined by the caller) | ||
791 | */ | ||
792 | void luaC_runtilstate (lua_State *L, int validstates) { | ||
793 | global_State *g = G(L); | ||
794 | while (!(g->gcstate & validstates)) | ||
795 | singlestep(L); | ||
796 | } | ||
797 | |||
798 | |||
799 | /* | ||
800 | ** performs a full GC cycle; if "isememrgency", does not call | ||
801 | ** finalizers (which could change stack positions) | ||
802 | */ | ||
788 | void luaC_fullgc (lua_State *L, int isemergency) { | 803 | void luaC_fullgc (lua_State *L, int isemergency) { |
789 | global_State *g = G(L); | 804 | global_State *g = G(L); |
790 | lua_assert(g->gckind == KGC_NORMAL); | 805 | lua_assert(g->gckind == KGC_NORMAL); |
@@ -796,16 +811,13 @@ void luaC_fullgc (lua_State *L, int isemergency) { | |||
796 | g->gcstate = GCSsweepstring; | 811 | g->gcstate = GCSsweepstring; |
797 | } | 812 | } |
798 | /* finish any pending sweep phase */ | 813 | /* finish any pending sweep phase */ |
799 | while (issweep(g)) singlestep(L); | 814 | luaC_runtilstate(L, ~(GCSsweepstring | GCSsweep)); |
800 | markroot(L); /* start a new collection */ | 815 | markroot(L); /* start a new collection */ |
801 | /* run collector up to finalizers */ | 816 | /* run collector up to finalizers */ |
802 | while (g->gcstate != GCSfinalize) | 817 | luaC_runtilstate(L, GCSfinalize); |
803 | singlestep(L); | ||
804 | g->gckind = KGC_NORMAL; | 818 | g->gckind = KGC_NORMAL; |
805 | if (!isemergency) { /* do not run finalizers during emergency GC */ | 819 | if (!isemergency) /* do not run finalizers during emergency GC */ |
806 | while (g->gcstate != GCSpause) | 820 | luaC_runtilstate(L, ~GCSfinalize); |
807 | singlestep(L); | ||
808 | } | ||
809 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; | 821 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; |
810 | } | 822 | } |
811 | 823 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.23 2009/11/18 13:13:47 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.24 2009/11/26 11:39:20 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 | */ |
@@ -14,16 +14,14 @@ | |||
14 | /* | 14 | /* |
15 | ** Possible states of the Garbage Collector | 15 | ** Possible states of the Garbage Collector |
16 | */ | 16 | */ |
17 | #define GCSpause 0 | 17 | #define GCSpause 1 |
18 | #define GCSpropagate 1 | 18 | #define GCSpropagate 2 |
19 | #define GCSatomic 2 | 19 | #define GCSatomic 4 |
20 | #define GCSsweepstring 3 | 20 | #define GCSsweepstring 8 |
21 | #define GCSsweep 4 | 21 | #define GCSsweep 16 |
22 | #define GCSfinalize 5 | 22 | #define GCSfinalize 32 |
23 | 23 | ||
24 | 24 | ||
25 | #define issweep(g) (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) | ||
26 | |||
27 | 25 | ||
28 | /* | 26 | /* |
29 | ** some useful bit tricks | 27 | ** some useful bit tricks |
@@ -98,6 +96,7 @@ | |||
98 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); | 96 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); |
99 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | 97 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
100 | LUAI_FUNC void luaC_step (lua_State *L); | 98 | LUAI_FUNC void luaC_step (lua_State *L); |
99 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int validstates); | ||
101 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 100 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
102 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | 101 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); |
103 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); | 102 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.12 2009/04/17 14:40:13 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.13 2009/04/29 17:09:41 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -22,8 +22,8 @@ | |||
22 | void luaS_resize (lua_State *L, int newsize) { | 22 | void luaS_resize (lua_State *L, int newsize) { |
23 | int i; | 23 | int i; |
24 | stringtable *tb = &G(L)->strt; | 24 | stringtable *tb = &G(L)->strt; |
25 | if (G(L)->gcstate == GCSsweepstring) | 25 | /* cannot resize while GC is traversing strings */ |
26 | return; /* cannot resize during GC traverse */ | 26 | luaC_runtilstate(L, ~GCSsweepstring); |
27 | if (newsize > tb->size) { | 27 | if (newsize > tb->size) { |
28 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | 28 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); |
29 | for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; | 29 | for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.81 2009/12/01 16:49:48 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.82 2009/12/10 18:21:28 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -167,6 +167,9 @@ void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { | |||
167 | ** ======================================================= | 167 | ** ======================================================= |
168 | */ | 168 | */ |
169 | 169 | ||
170 | #define issweep(g) (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) | ||
171 | |||
172 | |||
170 | static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { | 173 | static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { |
171 | if (isdead(g,t)) return 0; | 174 | if (isdead(g,t)) return 0; |
172 | if (g->gcstate == GCSpropagate) | 175 | if (g->gcstate == GCSpropagate) |