diff options
| -rw-r--r-- | lapi.c | 24 | ||||
| -rw-r--r-- | lbaselib.c | 34 | ||||
| -rw-r--r-- | lgc.c | 16 | ||||
| -rw-r--r-- | lgc.h | 3 | ||||
| -rw-r--r-- | lstate.c | 12 | ||||
| -rw-r--r-- | lstate.h | 7 | ||||
| -rw-r--r-- | ltests.c | 12 | ||||
| -rw-r--r-- | ltests.h | 2 | ||||
| -rw-r--r-- | lua.c | 2 | ||||
| -rw-r--r-- | lua.h | 21 | ||||
| -rw-r--r-- | manual/manual.of | 92 | ||||
| -rw-r--r-- | testes/gc.lua | 11 | ||||
| -rw-r--r-- | testes/gengc.lua | 5 |
13 files changed, 163 insertions, 78 deletions
| @@ -1186,27 +1186,37 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { | |||
| 1186 | break; | 1186 | break; |
| 1187 | } | 1187 | } |
| 1188 | case LUA_GCGEN: { | 1188 | case LUA_GCGEN: { |
| 1189 | #if defined(LUA_COMPAT_GCPARAMS) | ||
| 1189 | int minormul = va_arg(argp, int); | 1190 | int minormul = va_arg(argp, int); |
| 1190 | int minormajor = va_arg(argp, int); | 1191 | int minormajor = va_arg(argp, int); |
| 1191 | int majorminor = va_arg(argp, int); | 1192 | if (minormul > 0) setgcparam(g, MINORMUL, minormul); |
| 1193 | if (minormajor > 0) setgcparam(g, MINORMAJOR, minormajor); | ||
| 1194 | #endif | ||
| 1192 | res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN; | 1195 | res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN; |
| 1193 | setgcparam(g, gcpgenminormul, minormul); | ||
| 1194 | setgcparam(g, gcpminormajor, minormajor); | ||
| 1195 | setgcparam(g, gcpmajorminor, majorminor); | ||
| 1196 | luaC_changemode(L, KGC_GENMINOR); | 1196 | luaC_changemode(L, KGC_GENMINOR); |
| 1197 | break; | 1197 | break; |
| 1198 | } | 1198 | } |
| 1199 | case LUA_GCINC: { | 1199 | case LUA_GCINC: { |
| 1200 | #if defined(LUA_COMPAT_GCPARAMS) | ||
| 1200 | int pause = va_arg(argp, int); | 1201 | int pause = va_arg(argp, int); |
| 1201 | int stepmul = va_arg(argp, int); | 1202 | int stepmul = va_arg(argp, int); |
| 1202 | int stepsize = va_arg(argp, int); | 1203 | int stepsize = va_arg(argp, int); |
| 1204 | if (pause > 0) setgcparam(g, PAUSE, pause); | ||
| 1205 | if (stepmul > 0) setgcparam(g, STEPMUL, stepmul); | ||
| 1206 | if (stepsize > 0) setgcparam(g, STEPSIZE, 1u << stepsize); | ||
| 1207 | #endif | ||
| 1203 | res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN; | 1208 | res = (g->gckind == KGC_INC) ? LUA_GCINC : LUA_GCGEN; |
| 1204 | setgcparam(g, gcppause, pause); | ||
| 1205 | setgcparam(g, gcpstepmul, stepmul); | ||
| 1206 | setgcparam(g, gcpstepsize, stepsize); | ||
| 1207 | luaC_changemode(L, KGC_INC); | 1209 | luaC_changemode(L, KGC_INC); |
| 1208 | break; | 1210 | break; |
| 1209 | } | 1211 | } |
| 1212 | case LUA_GCSETPARAM: { | ||
| 1213 | int param = va_arg(argp, int); | ||
| 1214 | int value = va_arg(argp, int); | ||
| 1215 | api_check(L, 0 <= param && param < LUA_GCPN, "invalid parameter"); | ||
| 1216 | res = luaO_applyparam(g->gcparams[param], 100); | ||
| 1217 | g->gcparams[param] = luaO_codeparam(value); | ||
| 1218 | break; | ||
| 1219 | } | ||
| 1210 | default: res = -1; /* invalid option */ | 1220 | default: res = -1; /* invalid option */ |
| 1211 | } | 1221 | } |
| 1212 | va_end(argp); | 1222 | va_end(argp); |
| @@ -198,9 +198,11 @@ static int pushmode (lua_State *L, int oldmode) { | |||
| 198 | 198 | ||
| 199 | static int luaB_collectgarbage (lua_State *L) { | 199 | static int luaB_collectgarbage (lua_State *L) { |
| 200 | static const char *const opts[] = {"stop", "restart", "collect", | 200 | static const char *const opts[] = {"stop", "restart", "collect", |
| 201 | "count", "step", "isrunning", "generational", "incremental", NULL}; | 201 | "count", "step", "isrunning", "generational", "incremental", |
| 202 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, | 202 | "setparam", NULL}; |
| 203 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; | 203 | static const char optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
| 204 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC, | ||
| 205 | LUA_GCSETPARAM}; | ||
| 204 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; | 206 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
| 205 | switch (o) { | 207 | switch (o) { |
| 206 | case LUA_GCCOUNT: { | 208 | case LUA_GCCOUNT: { |
| @@ -224,17 +226,39 @@ static int luaB_collectgarbage (lua_State *L) { | |||
| 224 | return 1; | 226 | return 1; |
| 225 | } | 227 | } |
| 226 | case LUA_GCGEN: { | 228 | case LUA_GCGEN: { |
| 229 | #if defined(LUA_COMPAT_GCPARAMS) | ||
| 227 | int minormul = (int)luaL_optinteger(L, 2, -1); | 230 | int minormul = (int)luaL_optinteger(L, 2, -1); |
| 228 | int majorminor = (int)luaL_optinteger(L, 3, -1); | 231 | int majorminor = (int)luaL_optinteger(L, 3, -1); |
| 229 | int minormajor = (int)luaL_optinteger(L, 4, -1); | 232 | #else |
| 230 | return pushmode(L, lua_gc(L, o, minormul, majorminor, minormajor)); | 233 | int minormul = 0; |
| 234 | int majorminor = 0; | ||
| 235 | #endif | ||
| 236 | return pushmode(L, lua_gc(L, o, minormul, majorminor)); | ||
| 231 | } | 237 | } |
| 232 | case LUA_GCINC: { | 238 | case LUA_GCINC: { |
| 239 | #if defined(LUA_COMPAT_GCPARAMS) | ||
| 233 | int pause = (int)luaL_optinteger(L, 2, -1); | 240 | int pause = (int)luaL_optinteger(L, 2, -1); |
| 234 | int stepmul = (int)luaL_optinteger(L, 3, -1); | 241 | int stepmul = (int)luaL_optinteger(L, 3, -1); |
| 235 | int stepsize = (int)luaL_optinteger(L, 4, -1); | 242 | int stepsize = (int)luaL_optinteger(L, 4, -1); |
| 243 | #else | ||
| 244 | int pause = 0; | ||
| 245 | int stepmul = 0; | ||
| 246 | int stepsize = 0; | ||
| 247 | #endif | ||
| 236 | return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize)); | 248 | return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize)); |
| 237 | } | 249 | } |
| 250 | case LUA_GCSETPARAM: { | ||
| 251 | static const char *const params[] = { | ||
| 252 | "minormul", "majorminor", "minormajor", | ||
| 253 | "pause", "stepmul", "stepsize", NULL}; | ||
| 254 | static const char pnum[] = { | ||
| 255 | LUA_GCPMINORMUL, LUA_GCPMAJORMINOR, LUA_GCPMINORMAJOR, | ||
| 256 | LUA_GCPPAUSE, LUA_GCPSTEPMUL, LUA_GCPSTEPSIZE}; | ||
| 257 | int p = pnum[luaL_checkoption(L, 2, NULL, params)]; | ||
| 258 | lua_Integer value = luaL_checkinteger(L, 3); | ||
| 259 | lua_pushinteger(L, lua_gc(L, o, p, value)); | ||
| 260 | return 1; | ||
| 261 | } | ||
| 238 | default: { | 262 | default: { |
| 239 | int res = lua_gc(L, o); | 263 | int res = lua_gc(L, o); |
| 240 | checkvalres(res); | 264 | checkvalres(res); |
| @@ -1049,7 +1049,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
| 1049 | ** approximately (marked * pause / 100). | 1049 | ** approximately (marked * pause / 100). |
| 1050 | */ | 1050 | */ |
| 1051 | static void setpause (global_State *g) { | 1051 | static void setpause (global_State *g) { |
| 1052 | l_obj threshold = luaO_applyparam(g->gcppause, g->marked); | 1052 | l_obj threshold = applygcparam(g, PAUSE, g->marked); |
| 1053 | l_obj debt = threshold - gettotalobjs(g); | 1053 | l_obj debt = threshold - gettotalobjs(g); |
| 1054 | if (debt < 0) debt = 0; | 1054 | if (debt < 0) debt = 0; |
| 1055 | luaE_setdebt(g, debt); | 1055 | luaE_setdebt(g, debt); |
| @@ -1239,7 +1239,7 @@ static void minor2inc (lua_State *L, global_State *g, int kind) { | |||
| 1239 | g->finobjrold = g->finobjold1 = g->finobjsur = NULL; | 1239 | g->finobjrold = g->finobjold1 = g->finobjsur = NULL; |
| 1240 | entersweep(L); /* continue as an incremental cycle */ | 1240 | entersweep(L); /* continue as an incremental cycle */ |
| 1241 | /* set a debt equal to the step size */ | 1241 | /* set a debt equal to the step size */ |
| 1242 | luaE_setdebt(g, luaO_applyparam(g->gcpstepsize, 100)); | 1242 | luaE_setdebt(g, applygcparam(g, STEPSIZE, 100)); |
| 1243 | } | 1243 | } |
| 1244 | 1244 | ||
| 1245 | 1245 | ||
| @@ -1255,8 +1255,8 @@ static void minor2inc (lua_State *L, global_State *g, int kind) { | |||
| 1255 | ** major collection. (That percentage is computed in 'limit'.) | 1255 | ** major collection. (That percentage is computed in 'limit'.) |
| 1256 | */ | 1256 | */ |
| 1257 | static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) { | 1257 | static int checkminormajor (lua_State *L, global_State *g, l_obj addedold1) { |
| 1258 | l_obj step = luaO_applyparam(g->gcpgenminormul, g->GCmajorminor); | 1258 | l_obj step = applygcparam(g, MINORMUL, g->GCmajorminor); |
| 1259 | l_obj limit = luaO_applyparam(g->gcpminormajor, g->GCmajorminor); | 1259 | l_obj limit = applygcparam(g, MINORMAJOR, g->GCmajorminor); |
| 1260 | //printf("-> major? %ld %ld %ld %ld (%ld)\n", g->marked, limit, step, addedold1, gettotalobjs(g)); | 1260 | //printf("-> major? %ld %ld %ld %ld (%ld)\n", g->marked, limit, step, addedold1, gettotalobjs(g)); |
| 1261 | if (addedold1 >= (step >> 1) || g->marked >= limit) { | 1261 | if (addedold1 >= (step >> 1) || g->marked >= limit) { |
| 1262 | minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */ | 1262 | minor2inc(L, g, KGC_GENMAJOR); /* go to major mode */ |
| @@ -1347,7 +1347,7 @@ static void atomic2gen (lua_State *L, global_State *g) { | |||
| 1347 | ** total number of objects grows 'genminormul'%. | 1347 | ** total number of objects grows 'genminormul'%. |
| 1348 | */ | 1348 | */ |
| 1349 | static void setminordebt (global_State *g) { | 1349 | static void setminordebt (global_State *g) { |
| 1350 | luaE_setdebt(g, luaO_applyparam(g->gcpgenminormul, g->GCmajorminor)); | 1350 | luaE_setdebt(g, applygcparam(g, MINORMUL, g->GCmajorminor)); |
| 1351 | } | 1351 | } |
| 1352 | 1352 | ||
| 1353 | 1353 | ||
| @@ -1404,7 +1404,7 @@ static int checkmajorminor (lua_State *L, global_State *g) { | |||
| 1404 | if (g->gckind == KGC_GENMAJOR) { | 1404 | if (g->gckind == KGC_GENMAJOR) { |
| 1405 | l_obj numobjs = gettotalobjs(g); | 1405 | l_obj numobjs = gettotalobjs(g); |
| 1406 | l_obj addedobjs = numobjs - g->GCmajorminor; | 1406 | l_obj addedobjs = numobjs - g->GCmajorminor; |
| 1407 | l_obj limit = luaO_applyparam(g->gcpmajorminor, addedobjs); | 1407 | l_obj limit = applygcparam(g, MAJORMINOR, addedobjs); |
| 1408 | l_obj tobecollected = numobjs - g->marked; | 1408 | l_obj tobecollected = numobjs - g->marked; |
| 1409 | //printf("-> minor? %ld %ld %ld\n", tobecollected, limit, numobjs); | 1409 | //printf("-> minor? %ld %ld %ld\n", tobecollected, limit, numobjs); |
| 1410 | if (tobecollected > limit) { | 1410 | if (tobecollected > limit) { |
| @@ -1634,8 +1634,8 @@ void luaC_runtilstate (lua_State *L, int state, int fast) { | |||
| 1634 | ** controls when next step will be performed. | 1634 | ** controls when next step will be performed. |
| 1635 | */ | 1635 | */ |
| 1636 | static void incstep (lua_State *L, global_State *g) { | 1636 | static void incstep (lua_State *L, global_State *g) { |
| 1637 | l_obj stepsize = luaO_applyparam(g->gcpstepsize, 100); | 1637 | l_obj stepsize = applygcparam(g, STEPSIZE, 100); |
| 1638 | l_obj work2do = luaO_applyparam(g->gcpstepmul, stepsize); | 1638 | l_obj work2do = applygcparam(g, STEPMUL, stepsize); |
| 1639 | int fast = 0; | 1639 | int fast = 0; |
| 1640 | if (work2do == 0) { /* special case: do a full collection */ | 1640 | if (work2do == 0) { /* special case: do a full collection */ |
| 1641 | work2do = MAX_LOBJ; /* do unlimited work */ | 1641 | work2do = MAX_LOBJ; /* do unlimited work */ |
| @@ -193,7 +193,8 @@ | |||
| 193 | #define LUAI_GCSTEPSIZE 250 | 193 | #define LUAI_GCSTEPSIZE 250 |
| 194 | 194 | ||
| 195 | 195 | ||
| 196 | #define setgcparam(g,p,v) if ((v) >= 0) {g->p = luaO_codeparam(v);} | 196 | #define setgcparam(g,p,v) (g->gcparams[LUA_GCP##p] = luaO_codeparam(v)) |
| 197 | #define applygcparam(g,p,x) luaO_applyparam(g->gcparams[LUA_GCP##p], x) | ||
| 197 | 198 | ||
| 198 | /* | 199 | /* |
| 199 | ** Control when GC is running: | 200 | ** Control when GC is running: |
| @@ -365,12 +365,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud, unsigned int seed) { | |||
| 365 | g->marked = 0; | 365 | g->marked = 0; |
| 366 | g->GCdebt = 0; | 366 | g->GCdebt = 0; |
| 367 | setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ | 367 | setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ |
| 368 | setgcparam(g, gcppause, LUAI_GCPAUSE); | 368 | setgcparam(g, PAUSE, LUAI_GCPAUSE); |
| 369 | setgcparam(g, gcpstepmul, LUAI_GCMUL); | 369 | setgcparam(g, STEPMUL, LUAI_GCMUL); |
| 370 | setgcparam(g, gcpstepsize, LUAI_GCSTEPSIZE); | 370 | setgcparam(g, STEPSIZE, LUAI_GCSTEPSIZE); |
| 371 | setgcparam(g, gcpgenminormul, LUAI_GENMINORMUL); | 371 | setgcparam(g, MINORMUL, LUAI_GENMINORMUL); |
| 372 | setgcparam(g, gcpminormajor, LUAI_MINORMAJOR); | 372 | setgcparam(g, MINORMAJOR, LUAI_MINORMAJOR); |
| 373 | setgcparam(g, gcpmajorminor, LUAI_MAJORMINOR); | 373 | setgcparam(g, MAJORMINOR, LUAI_MAJORMINOR); |
| 374 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; | 374 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; |
| 375 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { | 375 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
| 376 | /* memory allocation error: free partial state */ | 376 | /* memory allocation error: free partial state */ |
| @@ -264,12 +264,7 @@ typedef struct global_State { | |||
| 264 | TValue l_registry; | 264 | TValue l_registry; |
| 265 | TValue nilvalue; /* a nil value */ | 265 | TValue nilvalue; /* a nil value */ |
| 266 | unsigned int seed; /* randomized seed for hashes */ | 266 | unsigned int seed; /* randomized seed for hashes */ |
| 267 | lu_byte gcpgenminormul; /* control minor generational collections */ | 267 | lu_byte gcparams[LUA_GCPN]; |
| 268 | lu_byte gcpmajorminor; /* control shift major->minor */ | ||
| 269 | lu_byte gcpminormajor; /* control shift minor->major */ | ||
| 270 | lu_byte gcppause; /* size of pause between successive GCs */ | ||
| 271 | lu_byte gcpstepmul; /* GC "speed" */ | ||
| 272 | lu_byte gcpstepsize; /* GC granularity */ | ||
| 273 | lu_byte currentwhite; | 268 | lu_byte currentwhite; |
| 274 | lu_byte gcstate; /* state of garbage collector */ | 269 | lu_byte gcstate; /* state of garbage collector */ |
| 275 | lu_byte gckind; /* kind of GC running */ | 270 | lu_byte gckind; /* kind of GC running */ |
| @@ -1037,12 +1037,12 @@ static int query_GCparams (lua_State *L) { | |||
| 1037 | global_State *g = G(L); | 1037 | global_State *g = G(L); |
| 1038 | lua_pushinteger(L, gettotalobjs(g)); | 1038 | lua_pushinteger(L, gettotalobjs(g)); |
| 1039 | lua_pushinteger(L, g->GCdebt); | 1039 | lua_pushinteger(L, g->GCdebt); |
| 1040 | lua_pushinteger(L, luaO_applyparam(g->gcpgenminormul, 100)); | 1040 | lua_pushinteger(L, applygcparam(g, MINORMUL, 100)); |
| 1041 | lua_pushinteger(L, luaO_applyparam(g->gcpmajorminor, 100)); | 1041 | lua_pushinteger(L, applygcparam(g, MAJORMINOR, 100)); |
| 1042 | lua_pushinteger(L, luaO_applyparam(g->gcpminormajor, 100)); | 1042 | lua_pushinteger(L, applygcparam(g, MINORMAJOR, 100)); |
| 1043 | lua_pushinteger(L, luaO_applyparam(g->gcppause, 100)); | 1043 | lua_pushinteger(L, applygcparam(g, PAUSE, 100)); |
| 1044 | lua_pushinteger(L, luaO_applyparam(g->gcpstepmul, 100)); | 1044 | lua_pushinteger(L, applygcparam(g, STEPMUL, 100)); |
| 1045 | lua_pushinteger(L, luaO_applyparam(g->gcpstepsize, 100)); | 1045 | lua_pushinteger(L, applygcparam(g, STEPSIZE, 100)); |
| 1046 | return 8; | 1046 | return 8; |
| 1047 | } | 1047 | } |
| 1048 | 1048 | ||
| @@ -15,6 +15,8 @@ | |||
| 15 | #define LUA_COMPAT_MATHLIB | 15 | #define LUA_COMPAT_MATHLIB |
| 16 | #define LUA_COMPAT_LT_LE | 16 | #define LUA_COMPAT_LT_LE |
| 17 | 17 | ||
| 18 | #define LUA_COMPAT_GCPARAMS | ||
| 19 | |||
| 18 | 20 | ||
| 19 | #define LUA_DEBUG | 21 | #define LUA_DEBUG |
| 20 | 22 | ||
| @@ -646,7 +646,7 @@ static int pmain (lua_State *L) { | |||
| 646 | luai_openlibs(L); /* open standard libraries */ | 646 | luai_openlibs(L); /* open standard libraries */ |
| 647 | createargtable(L, argv, argc, script); /* create table 'arg' */ | 647 | createargtable(L, argv, argc, script); /* create table 'arg' */ |
| 648 | lua_gc(L, LUA_GCRESTART); /* start GC... */ | 648 | lua_gc(L, LUA_GCRESTART); /* start GC... */ |
| 649 | lua_gc(L, LUA_GCGEN, -1, -1, -1); /* ...in generational mode */ | 649 | lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */ |
| 650 | if (!(args & has_E)) { /* no option '-E'? */ | 650 | if (!(args & has_E)) { /* no option '-E'? */ |
| 651 | if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */ | 651 | if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */ |
| 652 | return 0; /* error running LUA_INIT */ | 652 | return 0; /* error running LUA_INIT */ |
| @@ -325,7 +325,7 @@ LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); | |||
| 325 | 325 | ||
| 326 | 326 | ||
| 327 | /* | 327 | /* |
| 328 | ** garbage-collection function and options | 328 | ** garbage-collection options |
| 329 | */ | 329 | */ |
| 330 | 330 | ||
| 331 | #define LUA_GCSTOP 0 | 331 | #define LUA_GCSTOP 0 |
| @@ -337,6 +337,25 @@ LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); | |||
| 337 | #define LUA_GCISRUNNING 6 | 337 | #define LUA_GCISRUNNING 6 |
| 338 | #define LUA_GCGEN 7 | 338 | #define LUA_GCGEN 7 |
| 339 | #define LUA_GCINC 8 | 339 | #define LUA_GCINC 8 |
| 340 | #define LUA_GCSETPARAM 9 | ||
| 341 | |||
| 342 | |||
| 343 | /* | ||
| 344 | ** garbage-collection parameters | ||
| 345 | */ | ||
| 346 | /* parameters for generational mode */ | ||
| 347 | #define LUA_GCPMINORMUL 0 /* control minor collections */ | ||
| 348 | #define LUA_GCPMAJORMINOR 1 /* control shift major->minor */ | ||
| 349 | #define LUA_GCPMINORMAJOR 2 /* control shift minor->major */ | ||
| 350 | |||
| 351 | /* parameters for incremental mode */ | ||
| 352 | #define LUA_GCPPAUSE 3 /* size of pause between successive GCs */ | ||
| 353 | #define LUA_GCPSTEPMUL 4 /* GC "speed" */ | ||
| 354 | #define LUA_GCPSTEPSIZE 5 /* GC granularity */ | ||
| 355 | |||
| 356 | /* number of parameters */ | ||
| 357 | #define LUA_GCPN 6 | ||
| 358 | |||
| 340 | 359 | ||
| 341 | LUA_API int (lua_gc) (lua_State *L, int what, ...); | 360 | LUA_API int (lua_gc) (lua_State *L, int what, ...); |
| 342 | 361 | ||
diff --git a/manual/manual.of b/manual/manual.of index e6a3cd9e..92d408e5 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -681,12 +681,10 @@ effectively producing a non-incremental, stop-the-world collector. | |||
| 681 | The garbage-collector step size controls the | 681 | The garbage-collector step size controls the |
| 682 | size of each incremental step, | 682 | size of each incremental step, |
| 683 | specifically how many objects the interpreter creates | 683 | specifically how many objects the interpreter creates |
| 684 | before performing a step. | 684 | before performing a step: |
| 685 | This parameter is logarithmic: | 685 | A value of @M{n} means the interpreter will create |
| 686 | A value of @M{n} means the interpreter will create @M{2@sp{n}} | 686 | approximately @M{n} objects between steps. |
| 687 | objects between steps. | 687 | The default value is 250. |
| 688 | The default value is 8, | ||
| 689 | which means steps of approximately @N{256 objects}. | ||
| 690 | 688 | ||
| 691 | } | 689 | } |
| 692 | 690 | ||
| @@ -728,11 +726,13 @@ The default value is 100. | |||
| 728 | The major-minor multiplier controls the shift back to minor collections. | 726 | The major-minor multiplier controls the shift back to minor collections. |
| 729 | For a multiplier @M{x}, | 727 | For a multiplier @M{x}, |
| 730 | the collector will shift back to minor collections | 728 | the collector will shift back to minor collections |
| 731 | after a major collection collects at least @M{x%} of the allocated objects. | 729 | after a major collection collects at least @M{x%} |
| 730 | of the objects allocated during the last cycle. | ||
| 731 | |||
| 732 | In particular, for a multiplier of 0, | 732 | In particular, for a multiplier of 0, |
| 733 | the collector will immediately shift back to minor collections | 733 | the collector will immediately shift back to minor collections |
| 734 | after doing one cycle of major collections. | 734 | after doing one cycle of major collections. |
| 735 | The default value is 20. | 735 | The default value is 80. |
| 736 | 736 | ||
| 737 | } | 737 | } |
| 738 | 738 | ||
| @@ -3336,19 +3336,32 @@ Returns a boolean that tells whether the collector is running | |||
| 3336 | (i.e., not stopped). | 3336 | (i.e., not stopped). |
| 3337 | } | 3337 | } |
| 3338 | 3338 | ||
| 3339 | @item{@defid{LUA_GCINC} (int pause, int stepmul, int stepsize)| | 3339 | @item{@defid{LUA_GCINC}| |
| 3340 | Changes the collector to incremental mode | 3340 | Changes the collector to incremental mode. |
| 3341 | with the given parameters @see{incmode}. | ||
| 3342 | Returns the previous mode (@id{LUA_GCGEN} or @id{LUA_GCINC}). | 3341 | Returns the previous mode (@id{LUA_GCGEN} or @id{LUA_GCINC}). |
| 3343 | } | 3342 | } |
| 3344 | 3343 | ||
| 3345 | @item{@defid{LUA_GCGEN} (int minormul, int minormajor, int majorminor)| | 3344 | @item{@defid{LUA_GCGEN}| |
| 3346 | Changes the collector to generational mode | 3345 | Changes the collector to generational mode. |
| 3347 | with the given parameters @see{genmode}. | ||
| 3348 | Returns the previous mode (@id{LUA_GCGEN} or @id{LUA_GCINC}). | 3346 | Returns the previous mode (@id{LUA_GCGEN} or @id{LUA_GCINC}). |
| 3349 | } | 3347 | } |
| 3350 | 3348 | ||
| 3349 | @item{@defid{LUA_GCSETPARAM} (int param, int value)| | ||
| 3350 | Changes the values of a parameter of the collector and returns | ||
| 3351 | the previous value of that parameter. | ||
| 3352 | The argument @id{param} must have one of the following values: | ||
| 3353 | @description{ | ||
| 3354 | @item{@defid{LUA_GCPMINORMUL}| The minor multiplier. } | ||
| 3355 | @item{@defid{LUA_GCPMAJORMINOR}| The major-minor multiplier. } | ||
| 3356 | @item{@defid{LUA_GCPMINORMAJOR}| The minor-major multiplier. } | ||
| 3357 | @item{@defid{LUA_GCPPAUSE}| The garbage-collector pause. } | ||
| 3358 | @item{@defid{LUA_GCPSTEPMUL}| The step multiplier. } | ||
| 3359 | @item{@defid{LUA_GCPSTEPSIZE}| The step size. } | ||
| 3360 | } | ||
| 3361 | } | ||
| 3362 | |||
| 3351 | } | 3363 | } |
| 3364 | |||
| 3352 | For more details about these options, | 3365 | For more details about these options, |
| 3353 | see @Lid{collectgarbage}. | 3366 | see @Lid{collectgarbage}. |
| 3354 | 3367 | ||
| @@ -6347,20 +6360,35 @@ Returns a boolean that tells whether the collector is running | |||
| 6347 | } | 6360 | } |
| 6348 | 6361 | ||
| 6349 | @item{@St{incremental}| | 6362 | @item{@St{incremental}| |
| 6350 | Change the collector mode to incremental. | 6363 | Changes the collector mode to incremental and returns the previous mode. |
| 6351 | This option can be followed by three numbers: | ||
| 6352 | the garbage-collector pause, | ||
| 6353 | the step multiplier, | ||
| 6354 | and the step size @see{incmode}. | ||
| 6355 | A -1 or absent value means to not change that value. | ||
| 6356 | } | 6364 | } |
| 6357 | 6365 | ||
| 6358 | @item{@St{generational}| | 6366 | @item{@St{generational}| |
| 6359 | Change the collector mode to generational. | 6367 | Changes the collector mode to generational and returns the previous mode. |
| 6360 | This option can be followed by three numbers: | 6368 | } |
| 6361 | the garbage-collector minor multiplier, | 6369 | |
| 6362 | the minor-major multiplier, and the major-minor multiplier @see{genmode}. | 6370 | @item{@St{setparam}| |
| 6363 | A -1 or absent value means to not change that value. | 6371 | Changes the values of a parameter of the collector and returns |
| 6372 | the previous value of that parameter. | ||
| 6373 | This option must be followed by two extra arguments: | ||
| 6374 | The name of the parameter being changed (a string) | ||
| 6375 | and the new value for that parameter (an integer). | ||
| 6376 | The argument @id{param} must have one of the following values: | ||
| 6377 | @description{ | ||
| 6378 | @item{@St{minormul}| The minor multiplier. } | ||
| 6379 | @item{@St{majorminor}| The major-minor multiplier. } | ||
| 6380 | @item{@St{minormajor}| The minor-major multiplier. } | ||
| 6381 | @item{@St{pause}| The garbage-collector pause. } | ||
| 6382 | @item{@St{stepmul}| The step multiplier. } | ||
| 6383 | @item{@St{stepsize}| The step size. } | ||
| 6384 | } | ||
| 6385 | To be able to divide by 100 | ||
| 6386 | (as most parameters are given as percentages) | ||
| 6387 | without using floating-point arithmetic, | ||
| 6388 | Lua stores these parameters encoded. | ||
| 6389 | This encoding approximates the real value; | ||
| 6390 | so, the value returned as the previous value may not be | ||
| 6391 | equal to the last value set. | ||
| 6364 | } | 6392 | } |
| 6365 | 6393 | ||
| 6366 | } | 6394 | } |
| @@ -9249,9 +9277,10 @@ declare a local variable with the same name in the loop body. | |||
| 9249 | @itemize{ | 9277 | @itemize{ |
| 9250 | 9278 | ||
| 9251 | @item{ | 9279 | @item{ |
| 9252 | There were several changes in the parameters | 9280 | Parameters for the garbage collection are not set |
| 9253 | for the options @St{incremental} and @St{generational} | 9281 | with the options @St{incremental} and @St{generational}; |
| 9254 | of the function @Lid{collectgarbage}. | 9282 | instead, there is a new option @St{setparam} to that end. |
| 9283 | Moreover, there were some changes in the parameters themselves. | ||
| 9255 | } | 9284 | } |
| 9256 | 9285 | ||
| 9257 | } | 9286 | } |
| @@ -9277,9 +9306,10 @@ to signal the end of the dump. | |||
| 9277 | } | 9306 | } |
| 9278 | 9307 | ||
| 9279 | @item{ | 9308 | @item{ |
| 9280 | There were several changes in the parameters | 9309 | Parameters for the garbage collection are not set |
| 9281 | for the options @Lid{LUA_GCINC} and @Lid{LUA_GCGEN} | 9310 | with the options @Lid{LUA_GCINC} and @Lid{LUA_GCGEN}; |
| 9282 | of the function @Lid{lua_gc}. | 9311 | instead, there is a new option @Lid{LUA_GCSETPARAM} to that end. |
| 9312 | Moreover, there were some changes in the parameters themselves. | ||
| 9283 | } | 9313 | } |
| 9284 | 9314 | ||
| 9285 | } | 9315 | } |
diff --git a/testes/gc.lua b/testes/gc.lua index d7e0c4ff..61b5da9c 100644 --- a/testes/gc.lua +++ b/testes/gc.lua | |||
| @@ -27,17 +27,20 @@ end | |||
| 27 | 27 | ||
| 28 | -- test weird parameters to 'collectgarbage' | 28 | -- test weird parameters to 'collectgarbage' |
| 29 | do | 29 | do |
| 30 | collectgarbage("incremental") | ||
| 31 | local opause = collectgarbage("setparam", "pause", 100) | ||
| 32 | local ostepmul = collectgarbage("setparam", "stepmul", 100) | ||
| 30 | local t = {0, 2, 10, 90, 500, 5000, 30000, 0x7ffffffe} | 33 | local t = {0, 2, 10, 90, 500, 5000, 30000, 0x7ffffffe} |
| 31 | for i = 1, #t do | 34 | for i = 1, #t do |
| 32 | local p = t[i] | 35 | collectgarbage("setparam", "pause", t[i]) |
| 33 | for j = 1, #t do | 36 | for j = 1, #t do |
| 34 | local m = t[j] | 37 | collectgarbage("setparam", "stepmul", t[j]) |
| 35 | collectgarbage("incremental", p, m) | ||
| 36 | collectgarbage("step") | 38 | collectgarbage("step") |
| 37 | end | 39 | end |
| 38 | end | 40 | end |
| 39 | -- restore original parameters | 41 | -- restore original parameters |
| 40 | collectgarbage("incremental", 200, 300) | 42 | collectgarbage("setparam", "pause", opause) |
| 43 | collectgarbage("setparam", "stepmul", ostepmul) | ||
| 41 | collectgarbage() | 44 | collectgarbage() |
| 42 | end | 45 | end |
| 43 | 46 | ||
diff --git a/testes/gengc.lua b/testes/gengc.lua index d708d7fc..cae07285 100644 --- a/testes/gengc.lua +++ b/testes/gengc.lua | |||
| @@ -163,14 +163,15 @@ assert(collectgarbage'isrunning') | |||
| 163 | 163 | ||
| 164 | 164 | ||
| 165 | do print"testing stop-the-world collection" | 165 | do print"testing stop-the-world collection" |
| 166 | collectgarbage("incremental", nil, 0) | 166 | local step = collectgarbage("setparam", "stepsize", 0); |
| 167 | collectgarbage("incremental") | ||
| 167 | 168 | ||
| 168 | -- each step does a complete cycle | 169 | -- each step does a complete cycle |
| 169 | assert(collectgarbage("step")) | 170 | assert(collectgarbage("step")) |
| 170 | assert(collectgarbage("step")) | 171 | assert(collectgarbage("step")) |
| 171 | 172 | ||
| 172 | -- back to default value | 173 | -- back to default value |
| 173 | collectgarbage("incremental", nil, 200) | 174 | collectgarbage("setparam", "stepsize", step); |
| 174 | end | 175 | end |
| 175 | 176 | ||
| 176 | collectgarbage(oldmode) | 177 | collectgarbage(oldmode) |
