diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-05-28 17:41:00 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-05-28 17:41:00 -0300 |
| commit | 51e8f08e609b20af6f70641855d9be5edb2f1328 (patch) | |
| tree | 53225bf78b0a37cd79b08186ff4666e5cbd5f3d5 | |
| parent | 5adb5a4812f1894a70650e7529808968c522de9d (diff) | |
| download | lua-51e8f08e609b20af6f70641855d9be5edb2f1328.tar.gz lua-51e8f08e609b20af6f70641855d9be5edb2f1328.tar.bz2 lua-51e8f08e609b20af6f70641855d9be5edb2f1328.zip | |
more efficient way to apply 'stepmul' + some changes in GC parameters
| -rw-r--r-- | lgc.c | 47 |
1 files changed, 29 insertions, 18 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.127 2012/05/22 18:38:56 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.128 2012/05/23 15:43:14 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 | */ |
| @@ -24,8 +24,11 @@ | |||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | /* cost of sweeping one element (half the size of a small object) */ | 27 | /* |
| 28 | #define GCSWEEPCOST ((sizeof(TString) + 4) / 2) | 28 | ** cost of sweeping one element (the size of a small object divided |
| 29 | ** by some adjust for the sweep speed) | ||
| 30 | */ | ||
| 31 | #define GCSWEEPCOST ((sizeof(TString) + 4) / 4) | ||
| 29 | 32 | ||
| 30 | /* maximum number of elements to sweep in each single step */ | 33 | /* maximum number of elements to sweep in each single step */ |
| 31 | #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) | 34 | #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) |
| @@ -33,25 +36,27 @@ | |||
| 33 | /* maximum number of finalizers to call in each GC step */ | 36 | /* maximum number of finalizers to call in each GC step */ |
| 34 | #define GCFINALIZENUM 4 | 37 | #define GCFINALIZENUM 4 |
| 35 | 38 | ||
| 36 | /* (arbitrary) cost of atomic step */ | ||
| 37 | #define GCATOMICCOST GCSTEPSIZE | ||
| 38 | 39 | ||
| 40 | /* | ||
| 41 | ** macro to adjust 'stepmul': 'stepmul' is actually used like | ||
| 42 | ** 'stepmul / STEPMULADJ' (value chosen by tests) | ||
| 43 | */ | ||
| 44 | #define STEPMULADJ 200 | ||
| 39 | 45 | ||
| 40 | /* | 46 | /* |
| 41 | ** macro to apply the "speed" of the garbage collector: the constant | 47 | ** macro to adjust 'pause': 'pause' is actually used like |
| 42 | ** 80 makes the standard 'stepmul' of 200 results in the GC handling | 48 | ** 'pause / PAUSEADJ' (value chosen by tests) |
| 43 | ** 80/200 = 1/2.5 = 0.4Kbytes for every 1Kb allocated. | ||
| 44 | ** (The computation tries to avoid overflows or underflows.) | ||
| 45 | */ | 49 | */ |
| 46 | #define workrate(x,mul) \ | 50 | #define PAUSEADJ 200 |
| 47 | ((x) < MAX_INT/80 ? ((x) * 80) / mul : ((x) / mul) * 80) | 51 | |
| 52 | |||
| 48 | 53 | ||
| 49 | 54 | ||
| 50 | /* | 55 | /* |
| 51 | ** standard negative debt for GC; a reasonable "time" to wait before | 56 | ** standard negative debt for GC; a reasonable "time" to wait before |
| 52 | ** starting a new cycle | 57 | ** starting a new cycle |
| 53 | */ | 58 | */ |
| 54 | #define stddebtest(g,e) (-cast(l_mem, (e)/100) * g->gcpause) | 59 | #define stddebtest(g,e) (-cast(l_mem, (e)/PAUSEADJ) * g->gcpause) |
| 55 | #define stddebt(g) stddebtest(g, gettotalbytes(g)) | 60 | #define stddebt(g) stddebtest(g, gettotalbytes(g)) |
| 56 | 61 | ||
| 57 | 62 | ||
| @@ -672,7 +677,7 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
| 672 | case LUA_TTABLE: luaH_free(L, gco2t(o)); break; | 677 | case LUA_TTABLE: luaH_free(L, gco2t(o)); break; |
| 673 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; | 678 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; |
| 674 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; | 679 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; |
| 675 | case LUA_TSHRSTR: | 680 | case LUA_TSHRSTR: |
| 676 | G(L)->strt.nuse--; | 681 | G(L)->strt.nuse--; |
| 677 | /* go through */ | 682 | /* go through */ |
| 678 | case LUA_TLNGSTR: { | 683 | case LUA_TLNGSTR: { |
| @@ -955,8 +960,9 @@ void luaC_freeallobjects (lua_State *L) { | |||
| 955 | } | 960 | } |
| 956 | 961 | ||
| 957 | 962 | ||
| 958 | static void atomic (lua_State *L) { | 963 | static l_mem atomic (lua_State *L) { |
| 959 | global_State *g = G(L); | 964 | global_State *g = G(L); |
| 965 | l_mem trav = g->GCmemtrav; | ||
| 960 | GCObject *origweak, *origall; | 966 | GCObject *origweak, *origall; |
| 961 | lua_assert(!iswhite(obj2gco(g->mainthread))); | 967 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
| 962 | markobject(g, L); /* mark running thread */ | 968 | markobject(g, L); /* mark running thread */ |
| @@ -976,6 +982,7 @@ static void atomic (lua_State *L) { | |||
| 976 | separatetobefnz(L, 0); /* separate objects to be finalized */ | 982 | separatetobefnz(L, 0); /* separate objects to be finalized */ |
| 977 | markbeingfnz(g); /* mark userdata that will be finalized */ | 983 | markbeingfnz(g); /* mark userdata that will be finalized */ |
| 978 | propagateall(g); /* remark, to propagate `preserveness' */ | 984 | propagateall(g); /* remark, to propagate `preserveness' */ |
| 985 | trav = g->GCmemtrav - trav; /* avoid adding convergence twice */ | ||
| 979 | convergeephemerons(g); | 986 | convergeephemerons(g); |
| 980 | /* at this point, all resurrected objects are marked. */ | 987 | /* at this point, all resurrected objects are marked. */ |
| 981 | /* remove dead objects from weak tables */ | 988 | /* remove dead objects from weak tables */ |
| @@ -987,6 +994,7 @@ static void atomic (lua_State *L) { | |||
| 987 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | 994 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ |
| 988 | entersweep(L); /* prepare to sweep strings */ | 995 | entersweep(L); /* prepare to sweep strings */ |
| 989 | /*lua_checkmemory(L);*/ | 996 | /*lua_checkmemory(L);*/ |
| 997 | return trav; /* reasonable estimate of the work done by 'atomic' */ | ||
| 990 | } | 998 | } |
| 991 | 999 | ||
| 992 | 1000 | ||
| @@ -1012,8 +1020,7 @@ static lu_mem singlestep (lua_State *L) { | |||
| 1012 | else { /* no more `gray' objects */ | 1020 | else { /* no more `gray' objects */ |
| 1013 | g->gcstate = GCSatomic; /* finish mark phase */ | 1021 | g->gcstate = GCSatomic; /* finish mark phase */ |
| 1014 | g->GCestimate = g->GCmemtrav; /* save what was counted */ | 1022 | g->GCestimate = g->GCmemtrav; /* save what was counted */ |
| 1015 | atomic(L); | 1023 | return atomic(L); |
| 1016 | return GCATOMICCOST; | ||
| 1017 | } | 1024 | } |
| 1018 | } | 1025 | } |
| 1019 | case GCSsweepstring: { | 1026 | case GCSsweepstring: { |
| @@ -1086,14 +1093,18 @@ static void step (lua_State *L) { | |||
| 1086 | global_State *g = G(L); | 1093 | global_State *g = G(L); |
| 1087 | l_mem debt = g->GCdebt; | 1094 | l_mem debt = g->GCdebt; |
| 1088 | int stepmul = g->gcstepmul; | 1095 | int stepmul = g->gcstepmul; |
| 1089 | if (stepmul <= 0) stepmul = 1; | 1096 | if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values */ |
| 1097 | /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ | ||
| 1098 | debt = (debt / STEPMULADJ) + 1; | ||
| 1099 | debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; | ||
| 1090 | do { /* always perform at least one single step */ | 1100 | do { /* always perform at least one single step */ |
| 1091 | lu_mem work = singlestep(L); /* do some work */ | 1101 | lu_mem work = singlestep(L); /* do some work */ |
| 1092 | work = workrate(work, stepmul); /* apply work rate */ | ||
| 1093 | debt -= work; | 1102 | debt -= work; |
| 1094 | } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); | 1103 | } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); |
| 1095 | if (g->gcstate == GCSpause) | 1104 | if (g->gcstate == GCSpause) |
| 1096 | debt = stddebtest(g, g->GCestimate); /* pause until next cycle */ | 1105 | debt = stddebtest(g, g->GCestimate); /* pause until next cycle */ |
| 1106 | else | ||
| 1107 | debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ | ||
| 1097 | luaE_setdebt(g, debt); | 1108 | luaE_setdebt(g, debt); |
| 1098 | } | 1109 | } |
| 1099 | 1110 | ||
