diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-05-21 10:18:10 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-05-21 10:18:10 -0300 |
commit | 398811a3131cb025ca61d1a0839e3f99ba632ae9 (patch) | |
tree | d9643a0d86495befa7c498de2d9dbcd89fad4779 | |
parent | 2a66b34f720cdfb34e3455eb3dbc7fb8aa931981 (diff) | |
download | lua-398811a3131cb025ca61d1a0839e3f99ba632ae9.tar.gz lua-398811a3131cb025ca61d1a0839e3f99ba632ae9.tar.bz2 lua-398811a3131cb025ca61d1a0839e3f99ba632ae9.zip |
simpler macro 'luaC_condGC' + better 'step' in 'lua_gc' +
micro bug in 'luaC_checkfinalizer' (current sweep object could be
removed from 'allgc' list)
-rw-r--r-- | lapi.c | 18 | ||||
-rw-r--r-- | lgc.c | 30 | ||||
-rw-r--r-- | lgc.h | 4 |
3 files changed, 35 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.159 2011/11/30 12:32:05 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.160 2012/05/11 19:22:33 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 | */ |
@@ -1046,16 +1046,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { | |||
1046 | case LUA_GCSTEP: { | 1046 | case LUA_GCSTEP: { |
1047 | if (g->gckind == KGC_GEN) { /* generational mode? */ | 1047 | if (g->gckind == KGC_GEN) { /* generational mode? */ |
1048 | res = (g->lastmajormem == 0); /* 1 if will do major collection */ | 1048 | res = (g->lastmajormem == 0); /* 1 if will do major collection */ |
1049 | luaC_step(L); /* do a single step */ | 1049 | luaC_forcestep(L); /* do a single step */ |
1050 | } | 1050 | } |
1051 | else { | 1051 | else { |
1052 | while (data-- >= 0) { | 1052 | lu_mem debt = cast(lu_mem, data) * 1024; /* count in Kbytes */ |
1053 | luaC_step(L); | 1053 | if (g->gcrunning) |
1054 | if (g->gcstate == GCSpause) { /* end of cycle? */ | 1054 | debt += g->GCdebt; /* include current debt */ |
1055 | res = 1; /* signal it */ | 1055 | luaE_setdebt(g, debt); |
1056 | break; | 1056 | luaC_forcestep(L); |
1057 | } | 1057 | if (g->gcstate == GCSpause) /* end of cycle? */ |
1058 | } | 1058 | res = 1; /* signal it */ |
1059 | } | 1059 | } |
1060 | break; | 1060 | break; |
1061 | } | 1061 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.122 2012/05/14 17:52:56 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.123 2012/05/20 20:36:44 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 | */ |
@@ -863,11 +863,18 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
863 | return; /* nothing to be done */ | 863 | return; /* nothing to be done */ |
864 | else { /* move 'o' to 'finobj' list */ | 864 | else { /* move 'o' to 'finobj' list */ |
865 | GCObject **p; | 865 | GCObject **p; |
866 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) ; | 866 | GCheader *ho = gch(o); |
867 | *p = gch(o)->next; /* remove 'o' from root list */ | 867 | /* avoid removing current sweep object */ |
868 | gch(o)->next = g->finobj; /* link it in list 'finobj' */ | 868 | if (g->gcstate == GCSsweep && g->sweepgc == &ho->next) { |
869 | /* step to next object in the list */ | ||
870 | g->sweepgc = (ho->next == NULL) ? NULL : &gch(ho->next)->next; | ||
871 | } | ||
872 | /* search for pointer pointing to 'o' */ | ||
873 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } | ||
874 | *p = ho->next; /* remove 'o' from root list */ | ||
875 | ho->next = g->finobj; /* link it in list 'finobj' */ | ||
869 | g->finobj = o; | 876 | g->finobj = o; |
870 | l_setbit(gch(o)->marked, SEPARATED); /* mark it as such */ | 877 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ |
871 | resetoldbit(o); /* see MOVE OLD rule */ | 878 | resetoldbit(o); /* see MOVE OLD rule */ |
872 | } | 879 | } |
873 | } | 880 | } |
@@ -1085,7 +1092,7 @@ static void step (lua_State *L) { | |||
1085 | /* | 1092 | /* |
1086 | ** performs a basic GC step | 1093 | ** performs a basic GC step |
1087 | */ | 1094 | */ |
1088 | void luaC_step (lua_State *L) { | 1095 | void luaC_forcestep (lua_State *L) { |
1089 | global_State *g = G(L); | 1096 | global_State *g = G(L); |
1090 | int i; | 1097 | int i; |
1091 | if (isgenerational(g)) generationalcollection(L); | 1098 | if (isgenerational(g)) generationalcollection(L); |
@@ -1097,6 +1104,17 @@ void luaC_step (lua_State *L) { | |||
1097 | 1104 | ||
1098 | 1105 | ||
1099 | /* | 1106 | /* |
1107 | ** performs a basic GC step only if collector is running | ||
1108 | */ | ||
1109 | void luaC_step (lua_State *L) { | ||
1110 | global_State *g = G(L); | ||
1111 | if (g->gcrunning) luaC_forcestep(L); | ||
1112 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ | ||
1113 | } | ||
1114 | |||
1115 | |||
1116 | |||
1117 | /* | ||
1100 | ** performs a full GC cycle; if "isemergency", does not call | 1118 | ** performs a full GC cycle; if "isemergency", does not call |
1101 | ** finalizers (which could change stack positions) | 1119 | ** finalizers (which could change stack positions) |
1102 | */ | 1120 | */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.53 2012/01/23 20:29:12 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.54 2012/05/11 19:22:33 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 | */ |
@@ -104,7 +104,7 @@ | |||
104 | 104 | ||
105 | 105 | ||
106 | #define luaC_condGC(L,c) \ | 106 | #define luaC_condGC(L,c) \ |
107 | {if (G(L)->GCdebt > 0 && G(L)->gcrunning) {c;}; condchangemem(L);} | 107 | {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} |
108 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) | 108 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) |
109 | 109 | ||
110 | 110 | ||