aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lgc.c52
-rw-r--r--lgc.h7
-rw-r--r--lstate.c4
-rw-r--r--lstate.h3
-rw-r--r--lstring.c9
5 files changed, 50 insertions, 25 deletions
diff --git a/lgc.c b/lgc.c
index 183b91ef..c0ebef05 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.183 2003/12/03 12:30:41 roberto Exp roberto $ 2** $Id: lgc.c,v 1.184 2003/12/03 20:03:07 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*/
@@ -430,14 +430,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all,
430 GCObject *curr; 430 GCObject *curr;
431 global_State *g = G(L); 431 global_State *g = G(L);
432 l_mem lim = *plim; 432 l_mem lim = *plim;
433 int white = otherwhite(g); 433 int dead = otherwhite(g);
434 while ((curr = *p) != NULL) { 434 while ((curr = *p) != NULL) {
435 int mark = curr->gch.marked; 435 int mark = curr->gch.marked;
436 lua_assert(all || !(mark & g->currentwhite)); 436 lua_assert(all || !(mark & g->currentwhite));
437 if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { 437 lim -= objsize(curr);
438 if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) {
438 makewhite(g, curr); 439 makewhite(g, curr);
439 p = &curr->gch.next; 440 p = &curr->gch.next;
440 lim -= objsize(curr);
441 } 441 }
442 else { 442 else {
443 *p = curr->gch.next; 443 *p = curr->gch.next;
@@ -450,27 +450,32 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all,
450} 450}
451 451
452 452
453static void sweepstrings (lua_State *L, int all) { 453static l_mem sweepstrings (lua_State *L, int all, l_mem lim) {
454 int i; 454 int i;
455 global_State *g = G(L); 455 global_State *g = G(L);
456 int white = otherwhite(g); 456 int dead = otherwhite(g);
457 for (i = 0; i < g->strt.size; i++) { /* for each list */ 457 for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */
458 GCObject *curr; 458 GCObject *curr;
459 GCObject **p = &G(L)->strt.hash[i]; 459 GCObject **p = &G(L)->strt.hash[i];
460 while ((curr = *p) != NULL) { 460 while ((curr = *p) != NULL) {
461 int mark = curr->gch.marked; 461 int mark = curr->gch.marked;
462 lu_mem size = sizestring(gcotots(curr)->tsv.len);
462 lua_assert(all || !(mark & g->currentwhite)); 463 lua_assert(all || !(mark & g->currentwhite));
463 if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { 464 if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) {
464 makewhite(g, curr); 465 makewhite(g, curr);
465 p = &curr->gch.next; 466 p = &curr->gch.next;
466 } 467 }
467 else { 468 else {
468 g->strt.nuse--; 469 g->strt.nuse--;
469 *p = curr->gch.next; 470 *p = curr->gch.next;
470 luaM_free(L, curr, sizestring(gcotots(curr)->tsv.len)); 471 luaM_free(L, curr, size);
471 } 472 }
473 lim -= size;
472 } 474 }
475 if (lim <= 0) break;
473 } 476 }
477 g->sweepstrgc = i+1;
478 return lim;
474} 479}
475 480
476 481
@@ -527,7 +532,8 @@ void luaC_callGCTM (lua_State *L) {
527 532
528void luaC_sweepall (lua_State *L) { 533void luaC_sweepall (lua_State *L) {
529 l_mem dummy = MAXLMEM; 534 l_mem dummy = MAXLMEM;
530 sweepstrings(L, 1); 535 G(L)->sweepstrgc = 0;
536 sweepstrings(L, 1, dummy);
531 sweeplist(L, &G(L)->rootgc, 1, &dummy); 537 sweeplist(L, &G(L)->rootgc, 1, &dummy);
532} 538}
533 539
@@ -540,7 +546,6 @@ static void markroot (lua_State *L) {
540 makewhite(g, valtogco(g->mainthread)); 546 makewhite(g, valtogco(g->mainthread));
541 markobject(g, g->mainthread); 547 markobject(g, g->mainthread);
542 markvalue(g, registry(L)); 548 markvalue(g, registry(L));
543 markobject(g, g->firstudata);
544 markobject(g, L); /* mark running thread */ 549 markobject(g, L); /* mark running thread */
545 g->gcstate = GCSpropagate; 550 g->gcstate = GCSpropagate;
546} 551}
@@ -552,14 +557,25 @@ static void atomic (lua_State *L) {
552 marktmu(g); /* mark `preserved' userdata */ 557 marktmu(g); /* mark `preserved' userdata */
553 propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ 558 propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */
554 cleartable(g->weak); /* remove collected objects from weak tables */ 559 cleartable(g->weak); /* remove collected objects from weak tables */
555 /* echange current white */ 560 /* flip current white */
556 g->currentwhite = otherwhite(g); 561 g->currentwhite = otherwhite(g);
557 /* first element of root list will be used as temporary head for sweep 562 /* first element of root list will be used as temporary head for sweep
558 phase, so it won't be seeped */ 563 phase, so it won't be swept */
559 makewhite(g, g->rootgc); 564 makewhite(g, g->rootgc);
560 g->sweepgc = &g->rootgc->gch.next; 565 g->sweepgc = &g->rootgc->gch.next;
561 sweepstrings(L, 0); 566 g->sweepstrgc = 0;
562 g->gcstate = GCSsweep; 567 g->gcstate = GCSsweepstring;
568}
569
570
571static void sweepstringstep (lua_State *L) {
572 global_State *g = G(L);
573 l_mem lim = sweepstrings(L, 0, GCSTEPSIZE);
574 if (lim == GCSTEPSIZE) { /* nothing more to sweep? */
575 lua_assert(g->sweepstrgc > g->strt.size);
576 g->sweepstrgc = 0;
577 g->gcstate = GCSsweep; /* end sweep-string phase */
578 }
563} 579}
564 580
565 581
@@ -567,9 +583,8 @@ static void sweepstep (lua_State *L) {
567 global_State *g = G(L); 583 global_State *g = G(L);
568 l_mem lim = GCSTEPSIZE; 584 l_mem lim = GCSTEPSIZE;
569 g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); 585 g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim);
570 if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ 586 if (lim == GCSTEPSIZE) /* nothing more to sweep? */
571 g->gcstate = GCSfinalize; /* end sweep phase */ 587 g->gcstate = GCSfinalize; /* end sweep phase */
572 }
573} 588}
574 589
575 590
@@ -582,6 +597,9 @@ void luaC_collectgarbage (lua_State *L) {
582 propagatemarks(g, GCSTEPSIZE); 597 propagatemarks(g, GCSTEPSIZE);
583 /* atomic */ 598 /* atomic */
584 atomic(L); 599 atomic(L);
600 /* GCSsweepstring */
601 while (g->gcstate == GCSsweepstring)
602 sweepstringstep(L);
585 /* GCSsweep */ 603 /* GCSsweep */
586 while (g->gcstate == GCSsweep) 604 while (g->gcstate == GCSsweep)
587 sweepstep(L); 605 sweepstep(L);
diff --git a/lgc.h b/lgc.h
index 2946947b..9193e2cb 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 1.25 2003/12/01 16:33:30 roberto Exp roberto $ 2** $Id: lgc.h,v 1.26 2003/12/03 20:03:07 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*/
@@ -17,8 +17,9 @@
17#define GCSroot 0 17#define GCSroot 0
18#define GCSpropagate 1 18#define GCSpropagate 1
19#define GCSatomic 2 19#define GCSatomic 2
20#define GCSsweep 3 20#define GCSsweepstring 3
21#define GCSfinalize 4 21#define GCSsweep 4
22#define GCSfinalize 5
22 23
23 24
24/* 25/*
diff --git a/lstate.c b/lstate.c
index 99aeabdb..b52ff66d 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.131 2003/12/03 12:30:41 roberto Exp roberto $ 2** $Id: lstate.c,v 1.132 2003/12/03 20:03:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -81,6 +81,7 @@ static void f_luaopen (lua_State *L, void *ud) {
81 u->uv.metatable = NULL; 81 u->uv.metatable = NULL;
82 G(L)->firstudata = valtogco(u); 82 G(L)->firstudata = valtogco(u);
83 luaC_link(L, valtogco(u), LUA_TUSERDATA); 83 luaC_link(L, valtogco(u), LUA_TUSERDATA);
84 setbit(u->uv.marked, FIXEDBIT);
84 stack_init(L, L); /* init stack */ 85 stack_init(L, L); /* init stack */
85 sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ 86 sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
86 sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ 87 sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
@@ -167,6 +168,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
167 g->panic = NULL; 168 g->panic = NULL;
168 g->gcstate = 0; 169 g->gcstate = 0;
169 g->rootgc = NULL; 170 g->rootgc = NULL;
171 g->sweepstrgc = 0;
170 g->currentwhite = bitmask(WHITE0BIT); 172 g->currentwhite = bitmask(WHITE0BIT);
171 g->firstudata = NULL; 173 g->firstudata = NULL;
172 g->gray = NULL; 174 g->gray = NULL;
diff --git a/lstate.h b/lstate.h
index a0d49c65..c44828b6 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.116 2003/12/03 12:30:41 roberto Exp roberto $ 2** $Id: lstate.h,v 1.117 2003/12/03 20:03:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -101,6 +101,7 @@ typedef struct global_State {
101 GCObject *rootgc; /* list of all collectable objects */ 101 GCObject *rootgc; /* list of all collectable objects */
102 GCObject *firstudata; /* udata go to the end of `rootgc' */ 102 GCObject *firstudata; /* udata go to the end of `rootgc' */
103 GCObject **sweepgc; /* position of sweep in `rootgc' */ 103 GCObject **sweepgc; /* position of sweep in `rootgc' */
104 int sweepstrgc; /* position of sweep in `strt' */
104 GCObject *gray; /* list of gray objects */ 105 GCObject *gray; /* list of gray objects */
105 GCObject *weak; /* list of weak tables (to be cleared) */ 106 GCObject *weak; /* list of weak tables (to be cleared) */
106 GCObject *tmudata; /* list of userdata to be GC */ 107 GCObject *tmudata; /* list of userdata to be GC */
diff --git a/lstring.c b/lstring.c
index db0b98bf..5495542d 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 1.82 2003/12/03 12:30:41 roberto Exp roberto $ 2** $Id: lstring.c,v 1.83 2003/12/03 20:03:07 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -25,9 +25,12 @@ void luaS_freeall (lua_State *L) {
25 25
26 26
27void luaS_resize (lua_State *L, int newsize) { 27void luaS_resize (lua_State *L, int newsize) {
28 GCObject **newhash = luaM_newvector(L, newsize, GCObject *); 28 GCObject **newhash;
29 stringtable *tb = &G(L)->strt; 29 stringtable *tb;
30 int i; 30 int i;
31 if (G(L)->sweepstrgc > 0) return; /* cannot resize during GC traverse */
32 newhash = luaM_newvector(L, newsize, GCObject *);
33 tb = &G(L)->strt;
31 for (i=0; i<newsize; i++) newhash[i] = NULL; 34 for (i=0; i<newsize; i++) newhash[i] = NULL;
32 /* rehash */ 35 /* rehash */
33 for (i=0; i<tb->size; i++) { 36 for (i=0; i<tb->size; i++) {