diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-04 15:22:42 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-04 15:22:42 -0200 |
commit | 9db1942bac5fb509c6e46ccc825351a6be546792 (patch) | |
tree | d9f8091bf61610b7681c10b9b769031fc787f65e /lgc.c | |
parent | c6eac44a9420a26a2f8907dcd5266a6aecdb18ea (diff) | |
download | lua-9db1942bac5fb509c6e46ccc825351a6be546792.tar.gz lua-9db1942bac5fb509c6e46ccc825351a6be546792.tar.bz2 lua-9db1942bac5fb509c6e46ccc825351a6be546792.zip |
sweep of strings also incremental
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 52 |
1 files changed, 35 insertions, 17 deletions
@@ -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 | ||
453 | static void sweepstrings (lua_State *L, int all) { | 453 | static 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 | ||
528 | void luaC_sweepall (lua_State *L) { | 533 | void 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 | |||
571 | static 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); |