next up previous
Next: 7.1 mark Up: ソフトウェア特論 講義資料 C言語によるLisp処理系 Previous: 6.2 macroexpand (xleval.c)

7 ガーベッジコレクション

Xlispのガーベッジコレクション(GC)のプログラムを以下に示します. GCのアルゴリズムにはかなり多くのものが提案されています. 通常のLispでは,GCが始まると処理が止まってしまうため, 対話的な実時間処理に向かないということで,リアルタイムGCという ものも研究されています. Xlispでは,従来からよく使われるmark-and-sweep法が用いられています. これは,ゴミでないものをマークしてゆき,マークのついていないものを かきあつめるという方法です.

/* gc - garbage collect (only called here and in xlimage.c) */
gc()
{
    register LVAL **p,*ap,tmp;
    char buf[STRMAX+1];
    LVAL *newfp,fun;

    /* print the start of the gc message */
    if (s_gcflag && getvalue(s_gcflag)) {
        sprintf(buf,"[ gc: total %ld, ",nnodes);
        stdputstr(buf);
    }

 /* mark the obarray, 
        the argument list and the current environment */
    if (obarray)
        mark(obarray);
    if (xlenv)
        mark(xlenv);
    if (xlfenv)
        mark(xlfenv);
    if (xldenv)
        mark(xldenv);

    /* mark the evaluation stack */
    for (p = xlstack; p < xlstktop; ++p)
        if (tmp = **p)
            mark(tmp);

    /* mark the argument stack */
    for (ap = xlargstkbase; ap < xlsp; ++ap)
        if (tmp = *ap)
            mark(tmp);

    /* sweep memory collecting all unmarked nodes */
    sweep();

    /* count the gc call */
    ++gccalls;

    /* call the *gc-hook* if necessary */
    if (s_gchook && (fun = getvalue(s_gchook))) {
        newfp = xlsp;
        pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
        pusharg(fun);
        pusharg(cvfixnum((FIXTYPE)2));
        pusharg(cvfixnum((FIXTYPE)nnodes));
        pusharg(cvfixnum((FIXTYPE)nfree));
        xlfp = newfp;
        xlapply(2);
    }

    /* print the end of the gc message */
    if (s_gcflag && getvalue(s_gcflag)) {
        sprintf(buf,"%ld free ]\n",nfree);
        stdputstr(buf);
    }
}




generated through LaTeX2HTML. M.Inaba 平成18年5月6日