aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lapi.c18
-rw-r--r--lbaselib.c10
-rw-r--r--lgc.h4
-rw-r--r--lobject.c18
-rw-r--r--lobject.h4
-rw-r--r--manual/manual.of69
-rw-r--r--testes/files.lua2
-rw-r--r--testes/gc.lua29
8 files changed, 98 insertions, 56 deletions
diff --git a/lapi.c b/lapi.c
index dcdc1cd3..9ff1b851 100644
--- a/lapi.c
+++ b/lapi.c
@@ -416,10 +416,11 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
416 luaC_checkGC(L); 416 luaC_checkGC(L);
417 o = index2value(L, idx); /* previous call may reallocate the stack */ 417 o = index2value(L, idx); /* previous call may reallocate the stack */
418 } 418 }
419 if (len != NULL)
420 *len = tsslen(tsvalue(o));
421 lua_unlock(L); 419 lua_unlock(L);
422 return getstr(tsvalue(o)); 420 if (len != NULL)
421 return getlstr(tsvalue(o), *len);
422 else
423 return getstr(tsvalue(o));
423} 424}
424 425
425 426
@@ -1174,11 +1175,16 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
1174 } 1175 }
1175 case LUA_GCSTEP: { 1176 case LUA_GCSTEP: {
1176 lu_byte oldstp = g->gcstp; 1177 lu_byte oldstp = g->gcstp;
1178 l_obj n = va_arg(argp, int);
1179 int work = 0; /* true if GC did some work */
1177 g->gcstp = 0; /* allow GC to run (other bits must be zero here) */ 1180 g->gcstp = 0; /* allow GC to run (other bits must be zero here) */
1178 luaC_step(L); /* run one basic step */ 1181 if (n <= 0)
1179 g->gcstp = oldstp; /* restore previous state */ 1182 n = g->GCdebt; /* force to run one basic step */
1180 if (g->gcstate == GCSpause) /* end of cycle? */ 1183 luaE_setdebt(g, g->GCdebt - n);
1184 luaC_condGC(L, (void)0, work = 1);
1185 if (work && g->gcstate == GCSpause) /* end of cycle? */
1181 res = 1; /* signal it */ 1186 res = 1; /* signal it */
1187 g->gcstp = oldstp; /* restore previous state */
1182 break; 1188 break;
1183 } 1189 }
1184 case LUA_GCISRUNNING: { 1190 case LUA_GCISRUNNING: {
diff --git a/lbaselib.c b/lbaselib.c
index a9d39e9f..25dcaf52 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -213,7 +213,8 @@ static int luaB_collectgarbage (lua_State *L) {
213 return 1; 213 return 1;
214 } 214 }
215 case LUA_GCSTEP: { 215 case LUA_GCSTEP: {
216 int res = lua_gc(L, o); 216 lua_Integer n = luaL_optinteger(L, 2, 0);
217 int res = lua_gc(L, o, (int)n);
217 checkvalres(res); 218 checkvalres(res);
218 lua_pushboolean(L, res); 219 lua_pushboolean(L, res);
219 return 1; 220 return 1;
@@ -239,7 +240,7 @@ static int luaB_collectgarbage (lua_State *L) {
239 LUA_GCPPAUSE, LUA_GCPSTEPMUL, LUA_GCPSTEPSIZE}; 240 LUA_GCPPAUSE, LUA_GCPSTEPMUL, LUA_GCPSTEPSIZE};
240 int p = pnum[luaL_checkoption(L, 2, NULL, params)]; 241 int p = pnum[luaL_checkoption(L, 2, NULL, params)];
241 lua_Integer value = luaL_checkinteger(L, 3); 242 lua_Integer value = luaL_checkinteger(L, 3);
242 lua_pushinteger(L, lua_gc(L, o, p, value)); 243 lua_pushinteger(L, lua_gc(L, o, p, (int)value));
243 return 1; 244 return 1;
244 } 245 }
245 default: { 246 default: {
@@ -337,10 +338,7 @@ static int load_aux (lua_State *L, int status, int envidx) {
337 338
338static const char *getmode (lua_State *L, int idx) { 339static const char *getmode (lua_State *L, int idx) {
339 const char *mode = luaL_optstring(L, idx, "bt"); 340 const char *mode = luaL_optstring(L, idx, "bt");
340 int i = 0; 341 if (strchr(mode, 'B') != NULL) /* Lua code cannot use fixed buffers */
341 if (mode[i] == 'b') i++;
342 if (mode[i] == 't') i++;
343 if (mode[i] != '\0')
344 luaL_argerror(L, idx, "invalid mode"); 342 luaL_argerror(L, idx, "invalid mode");
345 return mode; 343 return mode;
346} 344}
diff --git a/lgc.h b/lgc.h
index 9aff11f5..b4c4f234 100644
--- a/lgc.h
+++ b/lgc.h
@@ -171,13 +171,13 @@
171** Major collections will shift to minor ones after a collection 171** Major collections will shift to minor ones after a collection
172** collects at least LUAI_MAJORMINOR% of the new objects. 172** collects at least LUAI_MAJORMINOR% of the new objects.
173*/ 173*/
174#define LUAI_MAJORMINOR 80 174#define LUAI_MAJORMINOR 50
175 175
176/* 176/*
177** A young (minor) collection will run after creating LUAI_GENMINORMUL% 177** A young (minor) collection will run after creating LUAI_GENMINORMUL%
178** new objects. 178** new objects.
179*/ 179*/
180#define LUAI_GENMINORMUL 20 180#define LUAI_GENMINORMUL 25
181 181
182 182
183/* incremental */ 183/* incremental */
diff --git a/lobject.c b/lobject.c
index 4091b9d7..5a9b435e 100644
--- a/lobject.c
+++ b/lobject.c
@@ -50,22 +50,22 @@ int luaO_ceillog2 (unsigned int x) {
50} 50}
51 51
52/* 52/*
53** Encodes 'p'% as a floating-point byte, represented as (eeeeexxx). 53** Encodes 'p'% as a floating-point byte, represented as (eeeexxxx).
54** The exponent is represented using excess-7. Mimicking IEEE 754, the 54** The exponent is represented using excess-7. Mimicking IEEE 754, the
55** representation normalizes the number when possible, assuming an extra 55** representation normalizes the number when possible, assuming an extra
56** 1 before the mantissa (xxx) and adding one to the exponent (eeeeexxx) 56** 1 before the mantissa (xxxx) and adding one to the exponent (eeee)
57** to signal that. So, the real value is (1xxx) * 2^(eeeee - 8) if 57** to signal that. So, the real value is (1xxxx) * 2^(eeee - 7 - 1) if
58** eeeee != 0, and (xxx) * 2^-7 otherwise. 58** eeee != 0, and (xxxx) * 2^-7 otherwise (subnormal numbers).
59*/ 59*/
60unsigned int luaO_codeparam (unsigned int p) { 60unsigned int luaO_codeparam (unsigned int p) {
61 if (p >= (cast(lu_mem, 0xF) << 0xF) / 128 * 100) /* overflow? */ 61 if (p >= (cast(lu_mem, 0x1F) << (0xF - 7 - 1)) * 100u) /* overflow? */
62 return 0xFF; /* return maximum value */ 62 return 0xFF; /* return maximum value */
63 else { 63 else {
64 p = (p * 128u) / 100; 64 p = (cast(l_uint32, p) * 128 + 99) / 100; /* round up the division */
65 if (p <= 0xF) 65 if (p < 0x10) /* subnormal number? */
66 return p; 66 return p; /* exponent bits are already zero; nothing else to do */
67 else { 67 else {
68 int log = luaO_ceillog2(p + 1) - 5; 68 int log = luaO_ceillog2(p + 1) - 5; /* preserve 5 bits */
69 return ((p >> log) - 0x10) | ((log + 1) << 4); 69 return ((p >> log) - 0x10) | ((log + 1) << 4);
70 } 70 }
71 } 71 }
diff --git a/lobject.h b/lobject.h
index a7d85762..81dfd475 100644
--- a/lobject.h
+++ b/lobject.h
@@ -427,8 +427,8 @@ typedef struct TString {
427** Get string and length */ 427** Get string and length */
428#define getlstr(ts, len) \ 428#define getlstr(ts, len) \
429 (strisshr(ts) \ 429 (strisshr(ts) \
430 ? (cast_void(len = (ts)->shrlen), rawgetshrstr(ts)) \ 430 ? (cast_void((len) = (ts)->shrlen), rawgetshrstr(ts)) \
431 : (cast_void(len = (ts)->u.lnglen), (ts)->contents)) 431 : (cast_void((len) = (ts)->u.lnglen), (ts)->contents))
432 432
433/* }================================================================== */ 433/* }================================================================== */
434 434
diff --git a/manual/manual.of b/manual/manual.of
index 92d408e5..6fd0df6d 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -666,18 +666,6 @@ A value of 200 means that the collector waits for
666the total number of objects to double before starting a new cycle. 666the total number of objects to double before starting a new cycle.
667The default value is 300; the maximum value is 1000. 667The default value is 300; the maximum value is 1000.
668 668
669The garbage-collector step multiplier
670controls the speed of the collector relative to
671object creation,
672that is,
673how many objects it marks or sweeps for each object created.
674Larger values make the collector more aggressive.
675Beware that values too small can
676make the collector too slow to ever finish a cycle.
677The default value is 200; the maximum value is 1000.
678As a special case, a zero value means unlimited work,
679effectively producing a non-incremental, stop-the-world collector.
680
681The garbage-collector step size controls the 669The garbage-collector step size controls the
682size of each incremental step, 670size of each incremental step,
683specifically how many objects the interpreter creates 671specifically how many objects the interpreter creates
@@ -686,6 +674,17 @@ A value of @M{n} means the interpreter will create
686approximately @M{n} objects between steps. 674approximately @M{n} objects between steps.
687The default value is 250. 675The default value is 250.
688 676
677The garbage-collector step multiplier
678controls the size of each GC step.
679A value of @M{n} means the interpreter will mark or sweep,
680in each step, @M{n%} objects for each created object.
681Larger values make the collector more aggressive.
682Beware that values too small can
683make the collector too slow to ever finish a cycle.
684The default value is 200; the maximum value is 1000.
685As a special case, a zero value means unlimited work,
686effectively producing a non-incremental, stop-the-world collector.
687
689} 688}
690 689
691@sect3{genmode| @title{Generational Garbage Collection} 690@sect3{genmode| @title{Generational Garbage Collection}
@@ -707,11 +706,12 @@ and the @def{major-minor multiplier}.
707The minor multiplier controls the frequency of minor collections. 706The minor multiplier controls the frequency of minor collections.
708For a minor multiplier @M{x}, 707For a minor multiplier @M{x},
709a new minor collection will be done when the number of objects 708a new minor collection will be done when the number of objects
710grows @M{x%} larger than the number in use just after the last collection. 709grows @M{x%} larger than the number in use just
710after the last major collection.
711For instance, for a multiplier of 20, 711For instance, for a multiplier of 20,
712the collector will do a minor collection when the number of objects 712the collector will do a minor collection when the number of objects
713gets 20% larger than the total after the last major collection. 713gets 20% larger than the total after the last major collection.
714The default value is 20. 714The default value is 25.
715 715
716The minor-major multiplier controls the shift to major collections. 716The minor-major multiplier controls the shift to major collections.
717For a multiplier @M{x}, 717For a multiplier @M{x},
@@ -728,11 +728,10 @@ For a multiplier @M{x},
728the collector will shift back to minor collections 728the collector will shift back to minor collections
729after a major collection collects at least @M{x%} 729after a major collection collects at least @M{x%}
730of the objects allocated during the last cycle. 730of the objects allocated during the last cycle.
731
732In particular, for a multiplier of 0, 731In particular, for a multiplier of 0,
733the collector will immediately shift back to minor collections 732the collector will immediately shift back to minor collections
734after doing one cycle of major collections. 733after doing one cycle of major collections.
735The default value is 80. 734The default value is 50.
736 735
737} 736}
738 737
@@ -3327,7 +3326,7 @@ Returns the remainder of dividing the current amount of bytes of
3327memory in use by Lua by 1024. 3326memory in use by Lua by 1024.
3328} 3327}
3329 3328
3330@item{@defid{LUA_GCSTEP}| 3329@item{@defid{LUA_GCSTEP} (int n)|
3331Performs a step of garbage collection. 3330Performs a step of garbage collection.
3332} 3331}
3333 3332
@@ -3686,9 +3685,12 @@ Moreover, for a fixed buffer,
3686the reader function should return the entire chunk in the first read. 3685the reader function should return the entire chunk in the first read.
3687(As an example, @Lid{luaL_loadbufferx} does that.) 3686(As an example, @Lid{luaL_loadbufferx} does that.)
3688 3687
3689@id{lua_load} uses the stack internally, 3688The function @Lid{lua_load} fully preserves the Lua stack
3690so the reader function must always leave the stack 3689through the calls to the reader function,
3691unmodified when returning. 3690except that it may push some values for internal use
3691before the first call,
3692and it restores the stack size to its original size plus one
3693(for the pushed result) after the last call.
3692 3694
3693@id{lua_load} can return 3695@id{lua_load} can return
3694@Lid{LUA_OK}, @Lid{LUA_ERRSYNTAX}, or @Lid{LUA_ERRMEM}. 3696@Lid{LUA_OK}, @Lid{LUA_ERRSYNTAX}, or @Lid{LUA_ERRMEM}.
@@ -6344,13 +6346,24 @@ gives the exact number of bytes in use by Lua.
6344 6346
6345@item{@St{step}| 6347@item{@St{step}|
6346Performs a garbage-collection step. 6348Performs a garbage-collection step.
6349This option may be followed by an extra argument,
6350an integer with the step size.
6351The default for this argument is zero.
6352
6353If the size is a positive @id{n},
6354the collector acts as if @id{n} new objects have been created.
6355If the size is zero,
6356the collector performs a basic step.
6347In incremental mode, 6357In incremental mode,
6348that step corresponds to the current step size; 6358a basic step corresponds to the current step size.
6349the function returns @true if the step finished a collection cycle.
6350In generational mode, 6359In generational mode,
6351the step performs a full minor collection or 6360a basic step performs a full minor collection or
6352a major collection, 6361a major collection,
6353if the collector has scheduled one; 6362if the collector has scheduled one.
6363
6364In incremental mode,
6365the function returns @true if the step finished a collection cycle.
6366In generational mode,
6354the function returns @true if the step performed a major collection. 6367the function returns @true if the step performed a major collection.
6355} 6368}
6356 6369
@@ -6382,13 +6395,9 @@ The argument @id{param} must have one of the following values:
6382@item{@St{stepmul}| The step multiplier. } 6395@item{@St{stepmul}| The step multiplier. }
6383@item{@St{stepsize}| The step size. } 6396@item{@St{stepsize}| The step size. }
6384} 6397}
6385To be able to divide by 100 6398Lua rounds these values before storing them;
6386(as most parameters are given as percentages)
6387without using floating-point arithmetic,
6388Lua stores these parameters encoded.
6389This encoding approximates the real value;
6390so, the value returned as the previous value may not be 6399so, the value returned as the previous value may not be
6391equal to the last value set. 6400exactly the last value set.
6392} 6401}
6393 6402
6394} 6403}
diff --git a/testes/files.lua b/testes/files.lua
index 2582406f..4f925f50 100644
--- a/testes/files.lua
+++ b/testes/files.lua
@@ -74,6 +74,8 @@ io.input(io.stdin); io.output(io.stdout);
74 74
75os.remove(file) 75os.remove(file)
76assert(not loadfile(file)) 76assert(not loadfile(file))
77-- Lua code cannot use chunks with fixed buffers
78checkerr("invalid mode", load, "", "", "B")
77checkerr("", dofile, file) 79checkerr("", dofile, file)
78assert(not io.open(file)) 80assert(not io.open(file))
79io.output(file) 81io.output(file)
diff --git a/testes/gc.lua b/testes/gc.lua
index 8bacffa0..c26de406 100644
--- a/testes/gc.lua
+++ b/testes/gc.lua
@@ -35,7 +35,7 @@ do
35 collectgarbage("setparam", "pause", t[i]) 35 collectgarbage("setparam", "pause", t[i])
36 for j = 1, #t do 36 for j = 1, #t do
37 collectgarbage("setparam", "stepmul", t[j]) 37 collectgarbage("setparam", "stepmul", t[j])
38 collectgarbage("step") 38 collectgarbage("step", t[j])
39 end 39 end
40 end 40 end
41 -- restore original parameters 41 -- restore original parameters
@@ -45,6 +45,33 @@ do
45end 45end
46 46
47 47
48--
49-- test the "size" of basic GC steps (whatever they mean...)
50--
51do print("steps")
52
53 local function dosteps (siz)
54 collectgarbage()
55 local a = {}
56 for i=1,100 do a[i] = {{}}; local b = {} end
57 local x = gcinfo()
58 local i = 0
59 repeat -- do steps until it completes a collection cycle
60 i = i+1
61 until collectgarbage("step", siz)
62 assert(gcinfo() < x)
63 return i -- number of steps
64 end
65
66 collectgarbage"stop"
67
68 if not _port then
69 assert(dosteps(10) < dosteps(2))
70 end
71
72end
73
74
48_G["while"] = 234 75_G["while"] = 234
49 76
50 77