aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-03-31 16:02:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-03-31 16:02:03 -0300
commit8d4feb504f34c182ad991102d5ccd974b3a5f1b8 (patch)
tree3d71b61cda8fce8431534531e6da512721243990
parentd77a7a8c26b54d9fad496e50c2f5c86516924939 (diff)
downloadlua-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.c29
1 files changed, 11 insertions, 18 deletions
diff --git a/lgc.c b/lgc.c
index 55c1e4f6..5eae15d7 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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*/
757static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { 757static 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*/
960static int entersweep (lua_State *L) { 956static 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);