[#15625] rb_hash_initialize — Takaaki Tateishi <ttate@...>

立石です.

22 messages 2002/01/04
[#15627] Re: rb_hash_initialize — matz@... (Yukihiro Matsumoto) 2002/01/04

まつもと ゆきひろです

[#15628] Re: rb_hash_initialize — Takaaki Tateishi <ttate@...> 2002/01/04

立石です.

[#15685] undefined method `inherited' for false (NameError) — WATANABE Hirofumi <eban@...>

わたなべです。

13 messages 2002/01/15
[#15686] Re: undefined method `inherited' for false (NameError) — nobu.nakada@... 2002/01/15

なかだです。

[#15757] 文字列→整数変換 — nobu.nakada@...

なかだです。

30 messages 2002/01/25

[#15830] [ 提案 ] puts, print 等を IO から分離 — UENO Katsuhiro <unnie@...>

うえのです。

14 messages 2002/01/31

[ruby-dev:15705] Re: method cache

From: nobu.nakada@...
Date: 2002-01-17 12:26:16 UTC
List: ruby-dev #15705
なかだです。

At Thu, 17 Jan 2002 20:42:42 +0900,
Takaaki Tateishi <ttate@kt.jaist.ac.jp> wrote:
> > |その場合,定義したメソッドのIDがキャッシュされている可能性があ
> > |る場合にのみ全探索してエントリを削除するというように変更すると,
> > |多少スピードが上がるようです.
> > 
> > 基本的なアイディアは評価できますが、CACHE_DAMAGEはクリアして
> > はいけないような気がします(たまたま同じスロットを使うIDも
> > DAMAGEを受けているかもしれないので)。
> 
> 気づいてませんでした.確かにまずいですね.
> rb_clear_cache_by_id()については,cache_damageでカウントしておいて,
> 2度以上damageを受ける(同じスロットが異なるidで使われる可能性がある)
> とundamageできないようにしておくというのはどうでしょう?
> そして,rb_clear_cache()の場合には全部undamageします.
> この方法でsample/test.rbを実行しても,ほとんど実行時間は変わらないよ
> うです.
> 
> # 他の方法としてはハッシュですべてのdamageを受けたIDを覚えておくとい
> # うくらいでしょうか…

ちょっと試してみましたが、結構微妙です。


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.245
diff -u -2 -p -r1.245 eval.c
--- eval.c	2002/01/16 09:32:51	1.245
+++ eval.c	2002/01/17 12:01:37
@@ -188,4 +188,23 @@ struct cache_entry {		/* method hash tab
 static struct cache_entry cache[CACHE_SIZE];
 
+#if CACHE_DAMAGE_TYPE == 1
+static int cache_damage[CACHE_SIZE];
+#define CACHE_DAMAGE(id) (cache_damage[(id)&CACHE_MASK]++)
+#define CACHE_UNDAMAGE(id) (cache_damage[(id)&CACHE_MASK] == 1 && cache_damage[(id)&CACHE_MASK] = 0)
+#define CACHE_DAMAGED_P(id) (cache_damage[(id)&CACHE_MASK])
+#define CACHE_CLEAR_DAMAGE() memset(cache_damage, 0, sizeof cache_damage)
+#elif CACHE_DAMAGE_TYPE == 2
+static ID cache_damage[CACHE_SIZE];
+#define CACHE_DAMAGE(id) (cache_damage[(id)&CACHE_MASK] = (id))
+#define CACHE_UNDAMAGE(id) (cache_damage[(id)&CACHE_MASK] = 0)
+#define CACHE_DAMAGED_P(id) (cache_damage[(id)&CACHE_MASK] == (id))
+#define CACHE_CLEAR_DAMAGE() memset(cache_damage, 0, sizeof cache_damage)
+#else
+#define CACHE_DAMAGE(id) ((void)(id))
+#define CACHE_UNDAMAGE(id) ((void)(id))
+#define CACHE_DAMAGED_P(id) (1)
+#define CACHE_CLEAR_DAMAGE() ((void)0)
+#endif
+
 void
 rb_clear_cache()
@@ -198,4 +217,5 @@ rb_clear_cache()
 	ent++;
     }
+    CACHE_CLEAR_DAMAGE();
 }
 
@@ -206,4 +226,6 @@ rb_clear_cache_by_id(id)
     struct cache_entry *ent, *end;
 
+    if (!CACHE_DAMAGED_P(id)) return;
+    CACHE_UNDAMAGE(id);
     ent = cache; end = ent + CACHE_SIZE;
     while (ent < end) {
@@ -266,4 +288,5 @@ rb_get_method_body(klassp, idp, noexp)
 	/* store empty info in cache */
 	ent = cache + EXPR1(klass, id);
+	CACHE_DAMAGE(id);
 	ent->klass  = klass;
 	ent->origin = klass;
@@ -277,4 +300,5 @@ rb_get_method_body(klassp, idp, noexp)
     /* store in cache */
     ent = cache + EXPR1(klass, id);
+    CACHE_DAMAGE(id);
     ent->klass  = klass;
     ent->noex   = body->nd_noex;
@@ -4628,4 +4652,5 @@ rb_call(klass, recv, mid, argc, argv, sc
     ent = cache + EXPR1(klass, mid);
     if (ent->mid == mid && ent->klass == klass) {
+	CACHE_DAMAGE(id);
 	if (!ent->method)
 	    return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread