diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 4063fde..f560ba6 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1776,21 +1776,26 @@ moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t * otherwise c points to a class object */ } -#if 0 - mcidx = ((moo_oow_t)c + (moo_oow_t)selector) % MOO_METHOD_CACHE_SIZE; /* TODO: change hash function */ + /*mcidx = MOO_HASH_INIT; + mcidx = MOO_HASH_VALUE(mcidx, (moo_oow_t)c); + mcidx = MOO_HASH_VALUE(mcidx, (moo_oow_t)selector); + mcidx &= (MOO_METHOD_CACHE_SIZE - 1);*/ + /*mcidx = ((moo_oow_t)c + (moo_oow_t)selector) % MOO_METHOD_CACHE_SIZE; */ + mcidx = ((moo_oow_t)_class ^ (moo_oow_t)selector) & (MOO_METHOD_CACHE_SIZE - 1); mcitm = &moo->method_cache[mcidx]; if (mcitm->receiver_class == c && mcitm->selector == selector && mcitm->method_type == mth_type) { - /* cache hit */ + /* cache hit */ + /* TODO: moo->method_cache_hits++; */ return mcitm->method; } -#endif /* [IMPORT] the method lookup logic should be the same as ciim_on_each_method() in comp.c */ mth = find_method_in_class_chain(moo, c, mth_type, &message); if (mth) { + /* TODO: moo->method_cache_misses++; */ mcitm->receiver_class = c; mcitm->selector = selector; mcitm->method_type = mth_type; @@ -1803,19 +1808,26 @@ not_found: { /* the object is an instance of Class. find the method * in an instance method dictionary of Class also */ -#if 0 - mcidx = ((moo_oow_t)_class + (moo_oow_t)selector) % MOO_METHOD_CACHE_SIZE; /* TODO: change hash function */ + + /*mcidx = MOO_HASH_INIT; + mcidx = MOO_HASH_VALUE(mcidx, (moo_oow_t)_class); + mcidx = MOO_HASH_VALUE(mcidx, (moo_oow_t)selector); + mcidx &= (MOO_METHOD_CACHE_SIZE - 1); */ + /* mcidx = ((moo_oow_t)_class + (moo_oow_t)selector) % MOO_METHOD_CACHE_SIZE; */ + mcidx = ((moo_oow_t)_class ^ (moo_oow_t)selector) & (MOO_METHOD_CACHE_SIZE - 1); mcitm = &moo->method_cache[mcidx]; if (mcitm->receiver_class == _class && mcitm->selector == selector && mcitm->method_type == MOO_METHOD_INSTANCE) { /* cache hit */ + /* TODO: moo->method_cache_hits++; */ return mcitm->method; } -#endif + mth = find_method_in_class(moo, _class, MOO_METHOD_INSTANCE, &message); if (mth) { + /* TODO: moo->method_cache_misses++; */ mcitm->receiver_class = c; mcitm->selector = selector; mcitm->method_type = MOO_METHOD_INSTANCE; @@ -1829,6 +1841,11 @@ not_found: return MOO_NULL; } +void moo_clearmethodcache (moo_t* moo) +{ + MOO_MEMSET (moo->method_cache, 0, MOO_SIZEOF(moo->method_cache)); +} + static int start_initial_process_and_context (moo_t* moo, const moo_oocs_t* objname, const moo_oocs_t* mthname) { /* the initial context is a fake context. if objname is 'Stix' and @@ -6028,6 +6045,8 @@ int moo_invoke (moo_t* moo, const moo_oocs_t* objname, const moo_oocs_t* mthname MOO_ASSERT (moo, moo->active_context == MOO_NULL); MOO_ASSERT (moo, moo->active_method == MOO_NULL); + moo_clearmethodcache (moo); + if (start_initial_process_and_context(moo, objname, mthname) <= -1) return -1; moo->initial_context = moo->processor->active->initial_context; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index c81c9bf..c3c5ac5 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -1039,6 +1039,9 @@ void moo_gc (moo_t* moo) if (moo->active_method) moo->active_code = MOO_METHOD_GET_CODE_BYTE(moo->active_method); /* update moo->active_code */ if (gcfin_count > 0) moo->sem_gcfin_sigreq = 1; + /* invalidate method cache. TODO: GCing entries on the method cache is also one way instead of full invalidation */ + moo_clearmethodcache (moo); + /* TODO: include some gc statstics like number of live objects, gc performance, etc */ MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO, "Finished GC curheap base %p ptr %p newheap base %p ptr %p\n", diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 2bd1174..a4a5313 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1508,6 +1508,9 @@ moo_pfbase_t* moo_getpfnum ( moo_ooi_t* pfnum ); +void moo_clearmethodcache ( + moo_t* moo +); moo_oop_method_t moo_findmethod ( moo_t* moo, moo_oop_t receiver, diff --git a/moo/lib/moo.h b/moo/lib/moo.h index bfb100d..eb532c7 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1336,6 +1336,7 @@ struct moo_method_cache_item_t }; typedef struct moo_method_cache_item_t moo_method_cache_item_t; +/* it must be a power of 2. otherwise cache hash will fail miserably */ #define MOO_METHOD_CACHE_SIZE 4096 /* =========================================================================