From 11ed51b23684431ad1876ac10f0d5492ad263ad7 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Thu, 25 Jun 2015 07:14:29 +0900 Subject: [PATCH] use khash for registers --- extlib/benz/gc.c | 27 +++++++++++++++++---------- extlib/benz/include/picrin/reg.h | 4 +++- extlib/benz/reg.c | 31 +++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index cbbf5253..ff56d26d 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -622,16 +622,20 @@ gc_mark_phase(pic_state *pic) do { struct pic_object *key; pic_value val; - xh_entry *it; + khiter_t it; + khash_t(reg) *h; struct pic_reg *reg; j = 0; reg = pic->regs; while (reg != NULL) { - for (it = xh_begin(®->hash); it != NULL; it = xh_next(it)) { - key = xh_key(it, struct pic_object *); - val = xh_val(it, pic_value); + h = ®->hash; + for (it = kh_begin(h); it != kh_end(h); ++it) { + if (! kh_exist(h, it)) + continue; + key = kh_key(h, it); + val = kh_val(h, it); if (gc_obj_is_marked(key) && gc_value_need_mark(val)) { gc_mark(pic, val); ++j; @@ -718,7 +722,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) } case PIC_TT_REG: { struct pic_reg *reg = (struct pic_reg *)obj; - xh_destroy(®->hash); + kh_destroy(reg, ®->hash); break; } case PIC_TT_CP: { @@ -813,14 +817,17 @@ static void gc_sweep_phase(pic_state *pic) { struct heap_page *page = pic->heap->pages; - xh_entry *it, *next; + khiter_t it; + khash_t(reg) *h; /* registries */ while (pic->regs != NULL) { - for (it = xh_begin(&pic->regs->hash); it != NULL; it = next) { - next = xh_next(it); - if (! gc_obj_is_marked(xh_key(it, struct pic_object *))) { - xh_del_ptr(&pic->regs->hash, xh_key(it, struct pic_object *)); + h = &pic->regs->hash; + for (it = kh_begin(h); it != kh_end(h); ++it) { + if (! kh_exist(h, it)) + continue; + if (! gc_obj_is_marked(kh_key(h, it))) { + kh_del(reg, h, it); } } pic->regs = pic->regs->prev; diff --git a/extlib/benz/include/picrin/reg.h b/extlib/benz/include/picrin/reg.h index d9622c06..c64c548f 100644 --- a/extlib/benz/include/picrin/reg.h +++ b/extlib/benz/include/picrin/reg.h @@ -9,9 +9,11 @@ extern "C" { #endif +KHASH_DECLARE(reg, void *, pic_value) + struct pic_reg { PIC_OBJECT_HEADER - xhash hash; + khash_t(reg) hash; struct pic_reg *prev; /* for GC */ }; diff --git a/extlib/benz/reg.c b/extlib/benz/reg.c index 7ba1499a..c5268b2e 100644 --- a/extlib/benz/reg.c +++ b/extlib/benz/reg.c @@ -4,6 +4,8 @@ #include "picrin.h" +KHASH_DEFINE(reg, void *, pic_value, kh_ptr_hash_func, kh_ptr_hash_equal) + struct pic_reg * pic_make_reg(pic_state *pic) { @@ -11,7 +13,7 @@ pic_make_reg(pic_state *pic) reg = (struct pic_reg *)pic_obj_alloc(pic, sizeof(struct pic_reg), PIC_TT_REG); reg->prev = NULL; - xh_init_ptr(®->hash, sizeof(pic_value)); + kh_init(reg, ®->hash); return reg; } @@ -19,35 +21,44 @@ pic_make_reg(pic_state *pic) pic_value pic_reg_ref(pic_state *pic, struct pic_reg *reg, void *key) { - xh_entry *e; + khash_t(reg) *h = ®->hash; + khiter_t it; - e = xh_get_ptr(®->hash, key); - if (! e) { + it = kh_get(reg, h, key); + if (it == kh_end(h)) { pic_errorf(pic, "element not found for a key: ~s", pic_obj_value(key)); } - return xh_val(e, pic_value); + return kh_val(h, it); } void pic_reg_set(pic_state PIC_UNUSED(*pic), struct pic_reg *reg, void *key, pic_value val) { - xh_put_ptr(®->hash, key, &val); + khash_t(reg) *h = ®->hash; + int ret; + khiter_t it; + + it = kh_put(reg, h, key, &ret); + kh_val(h, it) = val; } bool pic_reg_has(pic_state PIC_UNUSED(*pic), struct pic_reg *reg, void *key) { - return xh_get_ptr(®->hash, key) != NULL; + return kh_get(reg, ®->hash, key) != kh_end(®->hash); } void pic_reg_del(pic_state *pic, struct pic_reg *reg, void *key) { - if (xh_get_ptr(®->hash, key) == NULL) { + khash_t(reg) *h = ®->hash; + khiter_t it; + + it = kh_get(reg, h, key); + if (it == kh_end(h)) { pic_errorf(pic, "no slot named ~s found in register", pic_obj_value(key)); } - - xh_del_ptr(®->hash, key); + kh_del(reg, h, it); }