From 06c998e0b2eba0522e83113e31619945eef9ad1b Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 20 Jan 2015 17:38:34 +0900 Subject: [PATCH] add symbol gc --- extlib/benz/gc.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 5c5ef412..0db0c4c1 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -530,6 +530,20 @@ gc_mark_trie(pic_state *pic, struct pic_trie *trie) static void gc_mark_global_symbols(pic_state *pic) { + M(sDEFINE); M(sLAMBDA); M(sIF); M(sBEGIN); M(sQUOTE); M(sSETBANG); + M(sQUASIQUOTE); M(sUNQUOTE); M(sUNQUOTE_SPLICING); + M(sDEFINE_SYNTAX); M(sIMPORT); M(sEXPORT); + M(sDEFINE_LIBRARY); M(sIN_LIBRARY); + M(sCOND_EXPAND); M(sAND); M(sOR); M(sELSE); M(sLIBRARY); + M(sONLY); M(sRENAME); M(sPREFIX); M(sEXCEPT); + M(sCONS); M(sCAR); M(sCDR); M(sNILP); + M(sSYMBOLP); M(sPAIRP); + M(sADD); M(sSUB); M(sMUL); M(sDIV); M(sMINUS); + M(sEQ); M(sLT); M(sLE); M(sGT); M(sGE); M(sNOT); + M(sREAD); M(sFILE); + M(sCALL); M(sTAILCALL); M(sCALL_WITH_VALUES); M(sTAILCALL_WITH_VALUES); + M(sGREF); M(sLREF); M(sCREF); M(sRETURN); + M(rDEFINE); M(rLAMBDA); M(rIF); M(rBEGIN); M(rQUOTE); M(rSETBANG); M(rDEFINE_SYNTAX); M(rIMPORT); M(rEXPORT); M(rDEFINE_LIBRARY); M(rIN_LIBRARY); @@ -573,14 +587,9 @@ gc_mark_phase(pic_state *pic) gc_mark_object(pic, pic->arena[j]); } - /* mark reserved uninterned symbols */ + /* mark reserved symbols */ gc_mark_global_symbols(pic); - /* mark all interned symbols */ - for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { - gc_mark_object(pic, (struct pic_object *)xh_val(it, pic_sym *)); - } - /* global variables */ if (pic->globals) { gc_mark_object(pic, (struct pic_object *)pic->globals); @@ -709,6 +718,31 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) } } +static void +gc_sweep_symbols(pic_state *pic) +{ + xh_entry *it; + xvect xv; + size_t i; + char *cstr; + + xv_init(&xv, sizeof(xh_entry *)); + + for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { + if (! gc_obj_is_marked((struct pic_object *)xh_val(it, pic_sym *))) { + xv_push(&xv, &it); + } + } + + for (i = 0; i < xv_size(&xv); ++i) { + cstr = xh_key(*(xh_entry **)xv_get(&xv, i), char *); + + xh_del_str(&pic->syms, cstr); + + pic_free(pic, cstr); + } +} + static void gc_sweep_page(pic_state *pic, struct heap_page *page) { @@ -775,6 +809,8 @@ gc_sweep_phase(pic_state *pic) } } while (it != NULL); + gc_sweep_symbols(pic); + while (page) { gc_sweep_page(pic, page); page = page->next;