diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-09-13 13:21:52 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-09-13 13:21:52 -0300 |
commit | 686e57cf9c61070ff961407e3304071e171542f4 (patch) | |
tree | 902f64eb6a46bcd57d4d1140efd5bdcf7f1e501f /lgc.c | |
parent | 06156e7575dee21026595a30dcf76f400c447a33 (diff) | |
download | lua-686e57cf9c61070ff961407e3304071e171542f4.tar.gz lua-686e57cf9c61070ff961407e3304071e171542f4.tar.bz2 lua-686e57cf9c61070ff961407e3304071e171542f4.zip |
GC local pause configurable
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 46 |
1 files changed, 19 insertions, 27 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.163 2013/09/11 14:47:08 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.164 2013/09/11 14:56:15 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 | */ |
@@ -25,12 +25,6 @@ | |||
25 | 25 | ||
26 | 26 | ||
27 | /* | 27 | /* |
28 | ** How much memory to allocate before a new local collection | ||
29 | */ | ||
30 | #define GCLOCALPAUSE 8000 | ||
31 | |||
32 | |||
33 | /* | ||
34 | ** cost of sweeping one element (the size of a small object divided | 28 | ** cost of sweeping one element (the size of a small object divided |
35 | ** by some adjust for the sweep speed) | 29 | ** by some adjust for the sweep speed) |
36 | */ | 30 | */ |
@@ -149,7 +143,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { | |||
149 | global_State *g = G(L); | 143 | global_State *g = G(L); |
150 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 144 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
151 | lua_assert(g->gcstate != GCSpause); | 145 | lua_assert(g->gcstate != GCSpause); |
152 | lua_assert(gch(o)->tt != LUA_TTABLE); | 146 | lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */ |
153 | if (keepinvariant(g)) /* must keep invariant? */ | 147 | if (keepinvariant(g)) /* must keep invariant? */ |
154 | reallymarkobject(g, v); /* restore invariant */ | 148 | reallymarkobject(g, v); /* restore invariant */ |
155 | else { /* sweep phase */ | 149 | else { /* sweep phase */ |
@@ -888,19 +882,18 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
888 | return; /* nothing to be done */ | 882 | return; /* nothing to be done */ |
889 | else { /* move 'o' to 'finobj' list */ | 883 | else { /* move 'o' to 'finobj' list */ |
890 | GCObject **p; | 884 | GCObject **p; |
891 | GCheader *ho = gch(o); | 885 | if (g->sweepgc == &o->gch.next) { /* avoid removing current sweep object */ |
892 | if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ | ||
893 | lua_assert(issweepphase(g)); | 886 | lua_assert(issweepphase(g)); |
894 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); | 887 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); |
895 | } | 888 | } |
896 | /* search for pointer pointing to 'o' */ | 889 | /* search for pointer pointing to 'o' */ |
897 | p = (testbit(ho->marked, LOCALMARK)) ? &g->allgc : &g->localgc; | 890 | p = (testbit(o->gch.marked, LOCALMARK)) ? &g->allgc : &g->localgc; |
898 | for (; *p != o; p = &gch(*p)->next) { /* empty */ } | 891 | for (; *p != o; p = &gch(*p)->next) { /* empty */ } |
899 | *p = ho->next; /* remove 'o' from its list */ | 892 | *p = o->gch.next; /* remove 'o' from its list */ |
900 | p = (testbit(ho->marked, LOCALMARK)) ? &g->finobj : &g->localfin; | 893 | p = (testbit(o->gch.marked, LOCALMARK)) ? &g->finobj : &g->localfin; |
901 | ho->next = *p; /* link it in a "fin" list */ | 894 | o->gch.next = *p; /* link it in a "fin" list */ |
902 | *p = o; | 895 | *p = o; |
903 | l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */ | 896 | l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */ |
904 | if (issweepphase(g)) | 897 | if (issweepphase(g)) |
905 | makewhite(g, o); /* "sweep" object */ | 898 | makewhite(g, o); /* "sweep" object */ |
906 | } | 899 | } |
@@ -1032,7 +1025,7 @@ static void setpause (global_State *g, l_mem estimate) { | |||
1032 | ? estimate * g->gcpause /* no overflow */ | 1025 | ? estimate * g->gcpause /* no overflow */ |
1033 | : MAX_LMEM; /* overflow; truncate to maximum */ | 1026 | : MAX_LMEM; /* overflow; truncate to maximum */ |
1034 | g->GCthreshold = threshold; | 1027 | g->GCthreshold = threshold; |
1035 | luaE_setdebt(g, -GCLOCALPAUSE); | 1028 | luaE_setdebt(g, -g->gclocalpause); |
1036 | } | 1029 | } |
1037 | 1030 | ||
1038 | 1031 | ||
@@ -1050,8 +1043,6 @@ static int entersweep (lua_State *L) { | |||
1050 | g->gcstate = GCSswplocalgc; | 1043 | g->gcstate = GCSswplocalgc; |
1051 | lua_assert(g->sweepgc == NULL); | 1044 | lua_assert(g->sweepgc == NULL); |
1052 | g->sweepgc = sweeptolive(L, &g->localgc, &n); | 1045 | g->sweepgc = sweeptolive(L, &g->localgc, &n); |
1053 | if (g->sweepgc == NULL) /* no live objects in local list? */ | ||
1054 | g->sweepgc = &g->localgc; /* 'sweepgc' cannot be NULL here */ | ||
1055 | return n; | 1046 | return n; |
1056 | } | 1047 | } |
1057 | 1048 | ||
@@ -1099,7 +1090,7 @@ static l_mem atomic (lua_State *L) { | |||
1099 | work += g->GCmemtrav; /* stop counting (objects being finalized) */ | 1090 | work += g->GCmemtrav; /* stop counting (objects being finalized) */ |
1100 | separatetobefnz(g, 0); /* separate objects to be finalized */ | 1091 | separatetobefnz(g, 0); /* separate objects to be finalized */ |
1101 | markbeingfnz(g); /* mark objects that will be finalized */ | 1092 | markbeingfnz(g); /* mark objects that will be finalized */ |
1102 | propagateall(g); /* remark, to propagate `preserveness' */ | 1093 | propagateall(g); /* remark, to propagate 'resurrection' */ |
1103 | work -= g->GCmemtrav; /* restart counting */ | 1094 | work -= g->GCmemtrav; /* restart counting */ |
1104 | convergeephemerons(g); | 1095 | convergeephemerons(g); |
1105 | /* at this point, all resurrected objects are marked. */ | 1096 | /* at this point, all resurrected objects are marked. */ |
@@ -1117,14 +1108,15 @@ static l_mem atomic (lua_State *L) { | |||
1117 | 1108 | ||
1118 | static lu_mem sweepstep (lua_State *L, global_State *g, | 1109 | static lu_mem sweepstep (lua_State *L, global_State *g, |
1119 | int nextstate, GCObject **nextlist) { | 1110 | int nextstate, GCObject **nextlist) { |
1120 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | 1111 | if (g->sweepgc) { |
1121 | if (g->sweepgc) /* is there still something to sweep? */ | 1112 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); |
1122 | return (GCSWEEPMAX * GCSWEEPCOST); | 1113 | if (g->sweepgc) /* is there still something to sweep? */ |
1123 | else { /* enter next state */ | 1114 | return (GCSWEEPMAX * GCSWEEPCOST); |
1124 | g->gcstate = nextstate; | ||
1125 | g->sweepgc = nextlist; | ||
1126 | return 0; | ||
1127 | } | 1115 | } |
1116 | /* else enter next state */ | ||
1117 | g->gcstate = nextstate; | ||
1118 | g->sweepgc = nextlist; | ||
1119 | return 0; | ||
1128 | } | 1120 | } |
1129 | 1121 | ||
1130 | 1122 | ||
@@ -1245,7 +1237,7 @@ void luaC_step (lua_State *L) { | |||
1245 | luaC_forcestep(L); /* restart collection */ | 1237 | luaC_forcestep(L); /* restart collection */ |
1246 | } | 1238 | } |
1247 | else | 1239 | else |
1248 | luaE_setdebt(g, -GCLOCALPAUSE); | 1240 | luaE_setdebt(g, -g->gclocalpause); |
1249 | } | 1241 | } |
1250 | } | 1242 | } |
1251 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ | 1243 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ |