diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-03-31 16:02:03 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-03-31 16:02:03 -0300 |
commit | 8d4feb504f34c182ad991102d5ccd974b3a5f1b8 (patch) | |
tree | 3d71b61cda8fce8431534531e6da512721243990 | |
parent | d77a7a8c26b54d9fad496e50c2f5c86516924939 (diff) | |
download | lua-8d4feb504f34c182ad991102d5ccd974b3a5f1b8.tar.gz lua-8d4feb504f34c182ad991102d5ccd974b3a5f1b8.tar.bz2 lua-8d4feb504f34c182ad991102d5ccd974b3a5f1b8.zip |
do not try to ensure that 'sweepgc' points to a live object
when entering sweep phase ('entersweep'); that may be too
expensive to be done still inside the atomic step. Walking
one single object more often than not will work.
-rw-r--r-- | lgc.c | 29 |
1 files changed, 11 insertions, 18 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.210 2015/11/03 18:10:44 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.211 2015/12/10 18:12:30 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 | */ |
@@ -754,14 +754,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | |||
754 | /* | 754 | /* |
755 | ** sweep a list until a live object (or end of list) | 755 | ** sweep a list until a live object (or end of list) |
756 | */ | 756 | */ |
757 | static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { | 757 | static GCObject **sweeptolive (lua_State *L, GCObject **p) { |
758 | GCObject **old = p; | 758 | GCObject **old = p; |
759 | int i = 0; | ||
760 | do { | 759 | do { |
761 | i++; | ||
762 | p = sweeplist(L, p, 1); | 760 | p = sweeplist(L, p, 1); |
763 | } while (p == old); | 761 | } while (p == old); |
764 | if (n) *n += i; | ||
765 | return p; | 762 | return p; |
766 | } | 763 | } |
767 | 764 | ||
@@ -909,7 +906,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
909 | if (issweepphase(g)) { | 906 | if (issweepphase(g)) { |
910 | makewhite(g, o); /* "sweep" object 'o' */ | 907 | makewhite(g, o); /* "sweep" object 'o' */ |
911 | if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ | 908 | if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ |
912 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */ | 909 | g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ |
913 | } | 910 | } |
914 | /* search for pointer pointing to 'o' */ | 911 | /* search for pointer pointing to 'o' */ |
915 | for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } | 912 | for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } |
@@ -951,19 +948,16 @@ static void setpause (global_State *g) { | |||
951 | 948 | ||
952 | /* | 949 | /* |
953 | ** Enter first sweep phase. | 950 | ** Enter first sweep phase. |
954 | ** The call to 'sweeptolive' makes pointer point to an object inside | 951 | ** The call to 'sweeplist' tries to make pointer point to an object |
955 | ** the list (instead of to the header), so that the real sweep do not | 952 | ** inside the list (instead of to the header), so that the real sweep do |
956 | ** need to skip objects created between "now" and the start of the real | 953 | ** not need to skip objects created between "now" and the start of the |
957 | ** sweep. | 954 | ** real sweep. |
958 | ** Returns how many objects it swept. | ||
959 | */ | 955 | */ |
960 | static int entersweep (lua_State *L) { | 956 | static void entersweep (lua_State *L) { |
961 | global_State *g = G(L); | 957 | global_State *g = G(L); |
962 | int n = 0; | ||
963 | g->gcstate = GCSswpallgc; | 958 | g->gcstate = GCSswpallgc; |
964 | lua_assert(g->sweepgc == NULL); | 959 | lua_assert(g->sweepgc == NULL); |
965 | g->sweepgc = sweeptolive(L, &g->allgc, &n); | 960 | g->sweepgc = sweeplist(L, &g->allgc, 1); |
966 | return n; | ||
967 | } | 961 | } |
968 | 962 | ||
969 | 963 | ||
@@ -1064,12 +1058,11 @@ static lu_mem singlestep (lua_State *L) { | |||
1064 | } | 1058 | } |
1065 | case GCSatomic: { | 1059 | case GCSatomic: { |
1066 | lu_mem work; | 1060 | lu_mem work; |
1067 | int sw; | ||
1068 | propagateall(g); /* make sure gray list is empty */ | 1061 | propagateall(g); /* make sure gray list is empty */ |
1069 | work = atomic(L); /* work is what was traversed by 'atomic' */ | 1062 | work = atomic(L); /* work is what was traversed by 'atomic' */ |
1070 | sw = entersweep(L); | 1063 | entersweep(L); |
1071 | g->GCestimate = gettotalbytes(g); /* first estimate */; | 1064 | g->GCestimate = gettotalbytes(g); /* first estimate */; |
1072 | return work + sw * GCSWEEPCOST; | 1065 | return work; |
1073 | } | 1066 | } |
1074 | case GCSswpallgc: { /* sweep "regular" objects */ | 1067 | case GCSswpallgc: { /* sweep "regular" objects */ |
1075 | return sweepstep(L, g, GCSswpfinobj, &g->finobj); | 1068 | return sweepstep(L, g, GCSswpfinobj, &g->finobj); |