From: Takaaki Tateishi Date: 2002-01-17T22:46:54+09:00 Subject: [ruby-dev:15706] Re: method cache 立石です. At Thu, 17 Jan 2002 21:26:16 +0900, nobu.nakada@nifty.ne.jp wrote: > ちょっと試してみましたが、結構微妙です。 僕が想定していたのは違って,次のような感じにしておけば 良いなと思っていました.damageを受けたmidを*全部*保存し ておくのです. struct damaged_entry { ID mid; struct damaged_entry *mid; } static struct damaged_entry *cache_damage[CACHE_SIZE]; /* あとはご想像におまかせ… */ そのため,ひょっとして速度は多少落ちるかと思っていましたので… 中田さんの方法だと,異なるIDに対して同じスロットが使われた時 にやっぱり問題になる気がしますがどうなのでしょう? そして,先ほど僕もつけてしまっていましたが,/* is it in the method cache? */ のコメントの後ろではキャッシュが変更されて いないのでCACHE_DAMAGEは必要ないかもしれません. 中田さんのものを参考にして多少変えてみました.カウントする方 法だとこんな感じでしょうか? Index: eval.c =================================================================== RCS file: /src/ruby/eval.c,v retrieving revision 1.246 diff -u -r1.246 eval.c --- eval.c 2002/01/17 08:04:57 1.246 +++ eval.c 2002/01/17 13:43:20 @@ -186,7 +186,20 @@ }; static struct cache_entry cache[CACHE_SIZE]; +static int cache_damage[CACHE_SIZE]; +#define CACHE_DAMAGED(id) (cache_damage[id&CACHE_MASK]>0) +#define CACHE_DAMAGE(id) {\ + if( cache_damage[id&CACHE_MASK] < 2 )\ + cache_damage[id&CACHE_MASK]++; \ +} +#define CACHE_UNDAMAGE(id) {\ + if( cache_damage[id&CACHE_MASK] == 1 ) \ + cache_damage[id&CACHE_MASK] = 0; \ +} +#define CACHE_CLEAR_DAMAGE() memset(cache_damage,0,sizeof(cache_damage)) + + void rb_clear_cache() { @@ -197,6 +210,7 @@ ent->mid = 0; ent++; } + CACHE_CLEAR_DAMAGE(); } static void @@ -205,6 +219,8 @@ { struct cache_entry *ent, *end; + if( !CACHE_DAMAGED(id) ) return ; + CACHE_UNDAMAGE(id); ent = cache; end = ent + CACHE_SIZE; while (ent < end) { if (ent->mid == id) { @@ -264,7 +280,8 @@ if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) { /* store empty info in cache */ - ent = cache + EXPR1(klass, id); + ent = cache + EXPR1(klass, id); + CACHE_DAMAGE(id); ent->klass = klass; ent->origin = klass; ent->mid = ent->mid0 = id; @@ -276,6 +293,7 @@ /* store in cache */ ent = cache + EXPR1(klass, id); + CACHE_DAMAGE(id); ent->klass = klass; ent->noex = body->nd_noex; body = body->nd_body;