Next: 7.1 mark
Up: ソフトウェア特論 講義資料 C言語によるLisp処理系
Previous: 6.2 macroexpand (xleval.c)
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日