use khash for pic->syms

This commit is contained in:
Yuichi Nishiwaki 2015-06-25 07:05:41 +09:00
parent 03a649ed23
commit 0fb87449fc
4 changed files with 36 additions and 22 deletions

View File

@ -741,16 +741,19 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
static void static void
gc_sweep_symbols(pic_state *pic) gc_sweep_symbols(pic_state *pic)
{ {
xh_entry *it; khash_t(s) *h = &pic->syms;
char *cstr; khiter_t it;
pic_sym *sym;
const char *cstr;
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { for (it = kh_begin(h); it != kh_end(h); ++it) {
if (! gc_obj_is_marked((struct pic_object *)xh_val(it, pic_sym *))) { if (! kh_exist(h, it))
cstr = xh_key(it, char *); continue;
sym = kh_val(h, it);
xh_del_str(&pic->syms, cstr); if (! gc_obj_is_marked((struct pic_object *)sym)) {
cstr = kh_key(h, it);
pic_free(pic, cstr); kh_del(s, h, it);
pic_free(pic, (void *)cstr);
} }
} }
} }

View File

@ -48,6 +48,8 @@ typedef struct pic_state pic_state;
#include "picrin/read.h" #include "picrin/read.h"
#include "picrin/gc.h" #include "picrin/gc.h"
KHASH_DECLARE(s, const char *, pic_sym *);
typedef struct pic_checkpoint { typedef struct pic_checkpoint {
PIC_OBJECT_HEADER PIC_OBJECT_HEADER
struct pic_proc *in; struct pic_proc *in;
@ -125,7 +127,7 @@ struct pic_state {
pic_value features; pic_value features;
xhash syms; /* name to symbol */ khash_t(s) syms; /* name to symbol */
int ucnt; int ucnt;
struct pic_dict *globals; struct pic_dict *globals;
struct pic_dict *macros; struct pic_dict *macros;

View File

@ -224,7 +224,7 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf)
pic->regs = NULL; pic->regs = NULL;
/* symbol table */ /* symbol table */
xh_init_str(&pic->syms, sizeof(pic_sym *)); kh_init(s, &pic->syms);
/* unique symbol count */ /* unique symbol count */
pic->ucnt = 0; pic->ucnt = 0;
@ -399,13 +399,17 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf)
void void
pic_close(pic_state *pic) pic_close(pic_state *pic)
{ {
xh_entry *it; khash_t(s) *h = &pic->syms;
khiter_t it;
pic_allocf allocf = pic->allocf; pic_allocf allocf = pic->allocf;
/* free symbol names */ /* free all symbols */
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { for (it = kh_begin(h); it != kh_end(h); ++it) {
allocf(xh_key(it, char *), 0); if (kh_exist(h, it)) {
allocf((void *)kh_key(h, it), 0);
}
} }
kh_clear(s, h);
/* clear out root objects */ /* clear out root objects */
pic->sp = pic->stbase; pic->sp = pic->stbase;
@ -416,7 +420,6 @@ pic_close(pic_state *pic)
pic->globals = NULL; pic->globals = NULL;
pic->macros = NULL; pic->macros = NULL;
pic->attrs = NULL; pic->attrs = NULL;
xh_clear(&pic->syms);
pic->features = pic_nil_value(); pic->features = pic_nil_value();
pic->libs = pic_nil_value(); pic->libs = pic_nil_value();
@ -438,7 +441,7 @@ pic_close(pic_state *pic)
allocf(pic->xpbase, 0); allocf(pic->xpbase, 0);
/* free global stacks */ /* free global stacks */
xh_destroy(&pic->syms); kh_destroy(s, h);
/* free GC arena */ /* free GC arena */
allocf(pic->arena, 0); allocf(pic->arena, 0);

View File

@ -4,6 +4,8 @@
#include "picrin.h" #include "picrin.h"
KHASH_DEFINE(s, const char *, pic_sym *, kh_str_hash_func, kh_str_hash_equal)
static pic_sym * static pic_sym *
pic_make_symbol(pic_state *pic, pic_str *str) pic_make_symbol(pic_state *pic, pic_str *str)
{ {
@ -17,22 +19,26 @@ pic_make_symbol(pic_state *pic, pic_str *str)
pic_sym * pic_sym *
pic_intern(pic_state *pic, pic_str *str) pic_intern(pic_state *pic, pic_str *str)
{ {
xh_entry *e; khash_t(s) *h = &pic->syms;
pic_sym *sym; pic_sym *sym;
char *cstr; char *cstr;
khiter_t it;
int ret;
e = xh_get_str(&pic->syms, pic_str_cstr(pic, str)); it = kh_put(s, h, pic_str_cstr(pic, str), &ret);
if (e) { if (ret == 0) { /* if exists */
sym = xh_val(e, pic_sym *); sym = kh_val(h, it);
pic_gc_protect(pic, pic_obj_value(sym)); pic_gc_protect(pic, pic_obj_value(sym));
return sym; return sym;
} }
cstr = pic_malloc(pic, pic_str_len(str) + 1); cstr = pic_malloc(pic, pic_str_len(str) + 1);
strcpy(cstr, pic_str_cstr(pic, str)); strcpy(cstr, pic_str_cstr(pic, str));
kh_key(h, it) = cstr;
sym = pic_make_symbol(pic, str); sym = pic_make_symbol(pic, str);
xh_put_str(&pic->syms, cstr, &sym); kh_val(h, it) = sym;
return sym; return sym;
} }