aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-04 15:22:42 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-04 15:22:42 -0200
commit9db1942bac5fb509c6e46ccc825351a6be546792 (patch)
treed9f8091bf61610b7681c10b9b769031fc787f65e /lgc.c
parentc6eac44a9420a26a2f8907dcd5266a6aecdb18ea (diff)
downloadlua-9db1942bac5fb509c6e46ccc825351a6be546792.tar.gz
lua-9db1942bac5fb509c6e46ccc825351a6be546792.tar.bz2
lua-9db1942bac5fb509c6e46ccc825351a6be546792.zip
sweep of strings also incremental
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c52
1 files changed, 35 insertions, 17 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);