From fd248d31bd5452afa1e9b77f5a51f5d324f648dd Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Mon, 8 Feb 2016 03:36:20 +0900 Subject: [PATCH] optimize symbol->string --- extlib/benz/eval.c | 6 ++--- extlib/benz/gc.c | 3 ++- extlib/benz/include/picrin.h | 2 +- extlib/benz/include/picrin/khash.h | 29 +++++------------------- extlib/benz/include/picrin/string.h | 1 + extlib/benz/include/picrin/symbol.h | 2 +- extlib/benz/string.c | 13 +++++++++++ extlib/benz/symbol.c | 34 +++++++++++++---------------- 8 files changed, 42 insertions(+), 48 deletions(-) diff --git a/extlib/benz/eval.c b/extlib/benz/eval.c index 96689b18..4198f72f 100644 --- a/extlib/benz/eval.c +++ b/extlib/benz/eval.c @@ -117,7 +117,7 @@ analyzer_scope_destroy(pic_state *pic, analyze_scope *scope) } static bool -search_scope(analyze_scope *scope, pic_sym *sym) +search_scope(pic_state *pic, analyze_scope *scope, pic_sym *sym) { return kh_get(a, &scope->args, sym) != kh_end(&scope->args) || kh_get(a, &scope->locals, sym) != kh_end(&scope->locals) || scope->depth == 0; } @@ -128,7 +128,7 @@ find_var(pic_state *pic, analyze_scope *scope, pic_sym *sym) int depth = 0, ret; while (scope) { - if (search_scope(scope, sym)) { + if (search_scope(pic, scope, sym)) { if (depth > 0) { kh_put(a, &scope->captures, sym, &ret); /* capture! */ } @@ -145,7 +145,7 @@ define_var(pic_state *pic, analyze_scope *scope, pic_sym *sym) { int ret; - if (search_scope(scope, sym)) { + if (search_scope(pic, scope, sym)) { if (scope->depth > 0 || pic_reg_has(pic, pic->globals, sym)) { pic_warnf(pic, "redefining variable: ~s", pic_obj_value(sym)); } diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 79203fe6..879dd953 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -384,6 +384,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) break; } case PIC_TT_SYMBOL: { + LOOP(obj->u.sym.str); break; } case PIC_TT_REG: { @@ -559,7 +560,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) break; } case PIC_TT_SYMBOL: { - pic_free(pic, (void *)obj->u.sym.cstr); + /* TODO: remove this symbol's entry from pic->syms immediately */ break; } case PIC_TT_REG: { diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index 6d301890..47942e6d 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -45,7 +45,7 @@ typedef struct pic_state pic_state; #include "picrin/read.h" #include "picrin/gc.h" -KHASH_DECLARE(s, const char *, pic_sym *) +KHASH_DECLARE(s, pic_str *, pic_sym *) typedef struct pic_checkpoint { PIC_OBJECT_HEADER diff --git a/extlib/benz/include/picrin/khash.h b/extlib/benz/include/picrin/khash.h index 3d8d2ed9..157926ee 100644 --- a/extlib/benz/include/picrin/khash.h +++ b/extlib/benz/include/picrin/khash.h @@ -27,6 +27,8 @@ #ifndef AC_KHASH_H #define AC_KHASH_H +#include + typedef int khint_t; typedef khint_t khiter_t; @@ -41,23 +43,6 @@ typedef khint_t khiter_t; #define ac_roundup32(x) \ (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) -PIC_INLINE khint_t ac_X31_hash_string(const char *s) -{ - khint_t h = (khint_t)*s; - if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; - return h; -} -PIC_INLINE khint_t ac_Wang_hash(khint_t key) -{ - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; -} - #define ac_fsize(m) ((m) < 16? 1 : (m)>>4) #define ac_hash_upper(x) ((((x) * 2) * 77 / 100 + 1) / 2) @@ -71,7 +56,7 @@ PIC_INLINE khint_t ac_Wang_hash(khint_t key) void kh_init_##name(kh_##name##_t *h); \ void kh_destroy_##name(pic_state *, kh_##name##_t *h); \ void kh_clear_##name(kh_##name##_t *h); \ - khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ + khint_t kh_get_##name(pic_state *, const kh_##name##_t *h, khkey_t key); \ void kh_resize_##name(pic_state *, kh_##name##_t *h, khint_t new_n_buckets); \ khint_t kh_put_##name(pic_state *, kh_##name##_t *h, khkey_t key, int *ret); \ void kh_del_##name(kh_##name##_t *h, khint_t x); @@ -95,8 +80,9 @@ PIC_INLINE khint_t ac_Wang_hash(khint_t key) h->size = h->n_occupied = 0; \ } \ } \ - khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ + khint_t kh_get_##name(pic_state *pic, const kh_##name##_t *h, khkey_t key) \ { \ + (void)pic; \ if (h->n_buckets) { \ khint_t k, i, last, mask, step = 0; \ mask = h->n_buckets - 1; \ @@ -220,9 +206,6 @@ PIC_INLINE khint_t ac_Wang_hash(khint_t key) #define kh_ptr_hash_equal(a, b) ((a) == (b)) #define kh_int_hash_func(key) (int)(key) #define kh_int_hash_equal(a, b) ((a) == (b)) -#define kh_str_hash_func(key) ac_X31_hash_string(key) -#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) -#define kh_int_hash_func2(k) ac_Wang_hash((khint_t)key) /* --- END OF HASH FUNCTIONS --- */ @@ -232,7 +215,7 @@ PIC_INLINE khint_t ac_Wang_hash(khint_t key) #define kh_clear(name, h) kh_clear_##name(h) #define kh_resize(name, h, s) kh_resize_##name(pic, h, s) #define kh_put(name, h, k, r) kh_put_##name(pic, h, k, r) -#define kh_get(name, h, k) kh_get_##name(h, k) +#define kh_get(name, h, k) kh_get_##name(pic, h, k) #define kh_del(name, h, k) kh_del_##name(h, k) #define kh_exist(h, x) (!ac_iseither((h)->flags, (x))) diff --git a/extlib/benz/include/picrin/string.h b/extlib/benz/include/picrin/string.h index 2f5e8361..f3343e2d 100644 --- a/extlib/benz/include/picrin/string.h +++ b/extlib/benz/include/picrin/string.h @@ -29,6 +29,7 @@ int pic_str_len(pic_str *); pic_str *pic_str_cat(pic_state *, pic_str *, pic_str *); pic_str *pic_str_sub(pic_state *, pic_str *, int, int); int pic_str_cmp(pic_state *, pic_str *, pic_str *); +int pic_str_hash(pic_state *, pic_str *); const char *pic_str_cstr(pic_state *, pic_str *); pic_str *pic_format(pic_state *, const char *, ...); diff --git a/extlib/benz/include/picrin/symbol.h b/extlib/benz/include/picrin/symbol.h index 1237357d..07d70634 100644 --- a/extlib/benz/include/picrin/symbol.h +++ b/extlib/benz/include/picrin/symbol.h @@ -13,7 +13,7 @@ struct pic_id { union { struct pic_symbol { PIC_OBJECT_HEADER - const char *cstr; + pic_str *str; } sym; struct { PIC_OBJECT_HEADER diff --git a/extlib/benz/string.c b/extlib/benz/string.c index 0df0d631..fb3d3ae9 100644 --- a/extlib/benz/string.c +++ b/extlib/benz/string.c @@ -288,6 +288,19 @@ pic_str_cmp(pic_state *pic, pic_str *str1, pic_str *str2) return strcmp(pic_str_cstr(pic, str1), pic_str_cstr(pic, str2)); } +int +pic_str_hash(pic_state *pic, pic_str *str) +{ + const char *s; + int h = 0; + + s = pic_str_cstr(pic, str); + while (*s) { + h = (h << 5) - h + *s++; + } + return h; +} + const char * pic_str_cstr(pic_state *pic, pic_str *str) { diff --git a/extlib/benz/symbol.c b/extlib/benz/symbol.c index 3edc4f4a..4bf4d52c 100644 --- a/extlib/benz/symbol.c +++ b/extlib/benz/symbol.c @@ -4,43 +4,39 @@ #include "picrin.h" -KHASH_DEFINE(s, const char *, pic_sym *, kh_str_hash_func, kh_str_hash_equal) +#define kh_pic_str_hash(a) (pic_str_hash(pic, (a))) +#define kh_pic_str_cmp(a, b) (pic_str_cmp(pic, (a), (b)) == 0) -pic_sym * -pic_intern_str(pic_state *pic, pic_str *str) -{ - return pic_intern(pic, pic_str_cstr(pic, str)); -} +KHASH_DEFINE(s, pic_str *, pic_sym *, kh_pic_str_hash, kh_pic_str_cmp) pic_sym * -pic_intern(pic_state *pic, const char *cstr) +pic_intern_str(pic_state *pic, pic_str *str) { khash_t(s) *h = &pic->syms; pic_sym *sym; khiter_t it; int ret; - char *copy; - it = kh_put(s, h, cstr, &ret); + it = kh_put(s, h, str, &ret); if (ret == 0) { /* if exists */ sym = kh_val(h, it); pic_gc_protect(pic, pic_obj_value(sym)); return sym; } - copy = pic_malloc(pic, strlen(cstr) + 1); - strcpy(copy, cstr); - kh_key(h, it) = copy; - - kh_val(h, it) = pic->sQUOTE; /* insert dummy */ - sym = (pic_sym *)pic_obj_alloc(pic, sizeof(pic_sym), PIC_TT_SYMBOL); - sym->cstr = copy; + sym->str = str; kh_val(h, it) = sym; return sym; } +pic_sym * +pic_intern(pic_state *pic, const char *cstr) +{ + return pic_intern_str(pic, pic_make_cstr(pic, cstr)); +} + pic_id * pic_make_identifier(pic_state *pic, pic_id *id, struct pic_env *env) { @@ -53,9 +49,9 @@ pic_make_identifier(pic_state *pic, pic_id *id, struct pic_env *env) } const char * -pic_symbol_name(pic_state PIC_UNUSED(*pic), pic_sym *sym) +pic_symbol_name(pic_state *pic, pic_sym *sym) { - return sym->cstr; + return pic_str_cstr(pic, sym->str); } const char * @@ -104,7 +100,7 @@ pic_symbol_symbol_to_string(pic_state *pic) pic_get_args(pic, "m", &sym); - return pic_obj_value(pic_make_cstr(pic, sym->cstr)); + return pic_obj_value(sym->str); } static pic_value