diff --git a/include/mrbconf.h b/include/mrbconf.h index bcef1b1..b31988e 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -59,6 +59,9 @@ /* fixed size GC arena */ //#define MRB_GC_FIXED_ARENA +/* method cache */ +//#define MRB_METHOD_CACHE + /* -DDISABLE_XXXX to drop following features */ //#define DISABLE_STDIO /* use of stdio */ diff --git a/include/mruby.h b/include/mruby.h index e925502..ddd88d7 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -96,6 +96,19 @@ enum gc_state { GC_STATE_SWEEP }; +#ifdef MRB_METHOD_CACHE +#define MRB_CACHE_SIZE 0x800 +#define MRB_CACHE_MASK 0x7ff +#define MRB_CACHE(c,m) ((((((unsigned long)(void*)c))>>3)^(m))&MRB_CACHE_MASK) + +/* method hash table. */ +struct mrb_cache_entry { + mrb_sym mid; + struct RClass *c; + struct RProc* p; +}; +#endif + typedef struct mrb_state { void *jmp; @@ -162,6 +175,10 @@ typedef struct mrb_state { struct RClass *eStandardError_class; void *ud; /* auxiliary data */ + +#ifdef MRB_METHOD_CACHE + struct mrb_cache_entry cache[MRB_CACHE_SIZE]; +#endif } mrb_state; typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value); diff --git a/src/class.c b/src/class.c index d290892..c35e4f1 100644 --- a/src/class.c +++ b/src/class.c @@ -991,6 +991,14 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) struct RProc *m; struct RClass *c = *cp; +#ifdef MRB_METHOD_CACHE + struct mrb_cache_entry* ce; + ce = mrb->cache + MRB_CACHE(c, mid); + if (ce->c == c && ce->mid == mid) { + return ce->p; + } +#endif + while (c) { khash_t(mt) *h = c->mt; @@ -999,6 +1007,11 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) if (k != kh_end(h)) { m = kh_value(h, k); if (!m) break; +#ifdef MRB_METHOD_CACHE + ce->mid = mid; + ce->c = *cp; + ce->p = m; +#endif *cp = c; return m; }