diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-14 12:19:42 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-14 12:19:42 -0200 |
commit | 5be517602e5334573297fe8d421a92eb0184ce86 (patch) | |
tree | a3253a42f85b2aff30ed46e840e8e547f6746a94 /lgc.c | |
parent | d2bda8046c1061c353f9e787e987772b9f96099b (diff) | |
download | lua-5be517602e5334573297fe8d421a92eb0184ce86.tar.gz lua-5be517602e5334573297fe8d421a92eb0184ce86.tar.bz2 lua-5be517602e5334573297fe8d421a92eb0184ce86.zip |
no more generational collector (and no more `noinc' mode)
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 57 |
1 files changed, 24 insertions, 33 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.19 2004/12/13 12:15:11 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.20 2005/01/05 18:20:51 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 | */ |
@@ -23,11 +23,10 @@ | |||
23 | #include "ltm.h" | 23 | #include "ltm.h" |
24 | 24 | ||
25 | 25 | ||
26 | #define GCSTEPSIZE 1000 | 26 | #define GCSTEPSIZE 1024u |
27 | #define GCSWEEPMAX 10 | 27 | #define GCSWEEPMAX 40 |
28 | #define GCSWEEPCOST 30 | 28 | #define GCSWEEPCOST 10 |
29 | #define GCFINALIZECOST 100 | 29 | #define GCFINALIZECOST 100 |
30 | #define GCSTEPMUL 8 | ||
31 | 30 | ||
32 | 31 | ||
33 | #define FIXEDMASK bitmask(FIXEDBIT) | 32 | #define FIXEDMASK bitmask(FIXEDBIT) |
@@ -411,12 +410,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) { | |||
411 | global_State *g = G(L); | 410 | global_State *g = G(L); |
412 | int whitebit = otherwhite(g); | 411 | int whitebit = otherwhite(g); |
413 | int deadmask = whitebit | FIXEDMASK; | 412 | int deadmask = whitebit | FIXEDMASK; |
414 | int generational = g->gcgenerational; | ||
415 | while ((curr = *p) != NULL && count-- > 0) { | 413 | while ((curr = *p) != NULL && count-- > 0) { |
416 | if ((curr->gch.marked ^ whitebit) & deadmask) { | 414 | if ((curr->gch.marked ^ whitebit) & deadmask) { |
417 | lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); | 415 | lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); |
418 | if (!generational || isdead(g, curr)) | 416 | makewhite(g, curr); |
419 | makewhite(g, curr); | ||
420 | if (curr->gch.tt == LUA_TTHREAD) | 417 | if (curr->gch.tt == LUA_TTHREAD) |
421 | sweepwholelist(L, &gco2th(curr)->openupval); | 418 | sweepwholelist(L, &gco2th(curr)->openupval); |
422 | p = &curr->gch.next; | 419 | p = &curr->gch.next; |
@@ -532,7 +529,6 @@ static void remarkupvals (global_State *g) { | |||
532 | static void atomic (lua_State *L) { | 529 | static void atomic (lua_State *L) { |
533 | global_State *g = G(L); | 530 | global_State *g = G(L); |
534 | size_t udsize; /* total size of userdata to be finalized */ | 531 | size_t udsize; /* total size of userdata to be finalized */ |
535 | int aux; | ||
536 | /* remark objects cautch by write barrier */ | 532 | /* remark objects cautch by write barrier */ |
537 | propagateall(g); | 533 | propagateall(g); |
538 | /* remark occasional upvalues of (maybe) dead threads */ | 534 | /* remark occasional upvalues of (maybe) dead threads */ |
@@ -556,10 +552,6 @@ static void atomic (lua_State *L) { | |||
556 | g->sweepstrgc = 0; | 552 | g->sweepstrgc = 0; |
557 | g->sweepgc = &g->rootgc; | 553 | g->sweepgc = &g->rootgc; |
558 | g->gcstate = GCSsweepstring; | 554 | g->gcstate = GCSsweepstring; |
559 | aux = g->gcgenerational; | ||
560 | g->gcgenerational = g->incgc && (g->estimate/2 <= g->prevestimate); | ||
561 | if (!aux) /* last collection was full? */ | ||
562 | g->prevestimate = g->estimate; /* keep estimate of last full collection */ | ||
563 | g->estimate = g->totalbytes - udsize; /* first estimate */ | 555 | g->estimate = g->totalbytes - udsize; /* first estimate */ |
564 | } | 556 | } |
565 | 557 | ||
@@ -569,11 +561,7 @@ static l_mem singlestep (lua_State *L) { | |||
569 | /*lua_checkmemory(L);*/ | 561 | /*lua_checkmemory(L);*/ |
570 | switch (g->gcstate) { | 562 | switch (g->gcstate) { |
571 | case GCSpause: { | 563 | case GCSpause: { |
572 | /* start a new collection */ | 564 | markroot(L); /* start a new collection */ |
573 | if (g->gcgenerational) | ||
574 | atomic(L); | ||
575 | else | ||
576 | markroot(L); | ||
577 | return 0; | 565 | return 0; |
578 | } | 566 | } |
579 | case GCSpropagate: { | 567 | case GCSpropagate: { |
@@ -613,6 +601,7 @@ static l_mem singlestep (lua_State *L) { | |||
613 | } | 601 | } |
614 | else { | 602 | else { |
615 | g->gcstate = GCSpause; /* end collection */ | 603 | g->gcstate = GCSpause; /* end collection */ |
604 | g->gcdept = 0; | ||
616 | return 0; | 605 | return 0; |
617 | } | 606 | } |
618 | } | 607 | } |
@@ -623,25 +612,31 @@ static l_mem singlestep (lua_State *L) { | |||
623 | 612 | ||
624 | void luaC_step (lua_State *L) { | 613 | void luaC_step (lua_State *L) { |
625 | global_State *g = G(L); | 614 | global_State *g = G(L); |
626 | l_mem lim = (g->totalbytes - (g->GCthreshold - GCSTEPSIZE)) * GCSTEPMUL; | 615 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; |
616 | g->gcdept += g->totalbytes - g->GCthreshold; | ||
627 | do { | 617 | do { |
628 | lim -= singlestep(L); | 618 | lim -= singlestep(L); |
629 | if (g->gcstate == GCSpause) | 619 | if (g->gcstate == GCSpause) |
630 | break; | 620 | break; |
631 | } while (lim > 0 || !g->incgc); | 621 | } while (lim > 0); |
632 | if (g->gcstate != GCSpause) | 622 | if (g->gcstate != GCSpause) { |
633 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/STEPMUL; */ | 623 | if (g->gcdept < GCSTEPSIZE) |
624 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ | ||
625 | else { | ||
626 | g->gcdept -= GCSTEPSIZE; | ||
627 | g->GCthreshold = g->totalbytes; | ||
628 | } | ||
629 | } | ||
634 | else { | 630 | else { |
635 | lua_assert(g->totalbytes >= g->estimate); | 631 | lua_assert(g->totalbytes >= g->estimate); |
636 | g->GCthreshold = g->estimate + ((g->estimate/GCDIV) * g->gcpace); | 632 | g->GCthreshold = (g->estimate/100) * g->gcpace; |
637 | } | 633 | } |
638 | } | 634 | } |
639 | 635 | ||
640 | 636 | ||
641 | void luaC_fullgc (lua_State *L) { | 637 | void luaC_fullgc (lua_State *L) { |
642 | global_State *g = G(L); | 638 | global_State *g = G(L); |
643 | if (g->gcstate <= GCSpropagate || g->gcgenerational) { | 639 | if (g->gcstate <= GCSpropagate) { |
644 | g->gcgenerational = 0; | ||
645 | /* reset sweep marks to sweep all elements (returning them to white) */ | 640 | /* reset sweep marks to sweep all elements (returning them to white) */ |
646 | g->sweepstrgc = 0; | 641 | g->sweepstrgc = 0; |
647 | g->sweepgc = &g->rootgc; | 642 | g->sweepgc = &g->rootgc; |
@@ -657,10 +652,8 @@ void luaC_fullgc (lua_State *L) { | |||
657 | singlestep(L); | 652 | singlestep(L); |
658 | } | 653 | } |
659 | markroot(L); | 654 | markroot(L); |
660 | lua_assert(!g->gcgenerational); | ||
661 | while (g->gcstate != GCSpause) { | 655 | while (g->gcstate != GCSpause) { |
662 | singlestep(L); | 656 | singlestep(L); |
663 | g->gcgenerational = 0; /* keep it in this mode */ | ||
664 | } | 657 | } |
665 | g->GCthreshold = 2*g->estimate; | 658 | g->GCthreshold = 2*g->estimate; |
666 | } | 659 | } |
@@ -669,11 +662,10 @@ void luaC_fullgc (lua_State *L) { | |||
669 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 662 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { |
670 | global_State *g = G(L); | 663 | global_State *g = G(L); |
671 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 664 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
672 | lua_assert(g->gcgenerational || | 665 | lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); |
673 | (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); | ||
674 | lua_assert(ttype(&o->gch) != LUA_TTABLE); | 666 | lua_assert(ttype(&o->gch) != LUA_TTABLE); |
675 | /* must keep invariant? */ | 667 | /* must keep invariant? */ |
676 | if (g->gcstate == GCSpropagate || g->gcgenerational) | 668 | if (g->gcstate == GCSpropagate) |
677 | reallymarkobject(g, v); /* restore invariant */ | 669 | reallymarkobject(g, v); /* restore invariant */ |
678 | else /* don't mind */ | 670 | else /* don't mind */ |
679 | makewhite(g, o); /* mark as white just to avoid other barriers */ | 671 | makewhite(g, o); /* mark as white just to avoid other barriers */ |
@@ -683,8 +675,7 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | |||
683 | void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { | 675 | void luaC_barrierback (lua_State *L, GCObject *o, GCObject *v) { |
684 | global_State *g = G(L); | 676 | global_State *g = G(L); |
685 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 677 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
686 | lua_assert(g->gcgenerational || | 678 | lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); |
687 | (g->gcstate != GCSfinalize && g->gcstate != GCSpause)); | ||
688 | black2gray(o); /* make table gray (again) */ | 679 | black2gray(o); /* make table gray (again) */ |
689 | gco2h(o)->gclist = g->grayagain; | 680 | gco2h(o)->gclist = g->grayagain; |
690 | g->grayagain = o; | 681 | g->grayagain = o; |
@@ -706,7 +697,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { | |||
706 | o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ | 697 | o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ |
707 | g->rootgc = o; | 698 | g->rootgc = o; |
708 | if (isgray(o)) { | 699 | if (isgray(o)) { |
709 | if (g->gcstate == GCSpropagate || g->gcgenerational) { | 700 | if (g->gcstate == GCSpropagate) { |
710 | gray2black(o); /* closed upvalues need barrier */ | 701 | gray2black(o); /* closed upvalues need barrier */ |
711 | luaC_barrier(L, uv, uv->v); | 702 | luaC_barrier(L, uv, uv->v); |
712 | } | 703 | } |