Index: eval.c =================================================================== RCS file: /src/ruby/eval.c,v retrieving revision 1.288 diff -u -u -r1.288 eval.c --- eval.c 2002/04/26 00:38:44 1.288 +++ eval.c 2002/04/26 14:57:39 @@ -190,6 +190,79 @@ static struct cache_entry cache[CACHE_SIZE]; +#define CACHE_DAMAGE_TYPE 2 +#if CACHE_DAMAGE_TYPE == 1 +static int cache_damage[CACHE_SIZE]; +#define Init_cache() ((void)0) +#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) : 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 st_table *cache_damage; +#define Init_cache() (cache_damage = st_init_numtable_with_size(CACHE_SIZE)) +#define CACHE_DAMAGE(id) st_insert(cache_damage, (char *)(id), NULL) +#define CACHE_UNDAMAGE(id) ((void)(id)) +#define CACHE_DAMAGED_P(id) st_delete(cache_damage, (char **)&(id), NULL) +#define CACHE_CLEAR_DAMAGE() st_cleanup_safe(cache_damage, 0) +#elif CACHE_DAMAGE_TYPE == 3 +struct damaged_entry { + ID mid; + struct damaged_entry *next; +}; +static struct damaged_entry *cache_damage[CACHE_SIZE]; +#define Init_cache() ((void)0) +#define CACHE_DAMAGE(id) damage(id) +#define CACHE_UNDAMAGE(id) ((void)(id)) +#define CACHE_DAMAGED_P(id) damaged_p(id) +#define CACHE_CLEAR_DAMAGE() clear_damage() +static void damage _((ID id)); +static int damaged_p _((ID id)); +static void clear_damage _((void)); +static void damage(id) + ID id; +{ + struct damaged_entry *ent, **entp = &cache_damage[id & CACHE_MASK]; + for (ent = *entp; ent; ent = ent->next) { + if (ent->mid == id) return; + } + ent = ALLOC(struct damaged_entry); + ent->mid = id; + ent->next = *entp; + *entp = ent; +} +static int damaged_p(id) + ID id; +{ + struct damaged_entry *ent = cache_damage[id & CACHE_MASK]; + for (; ent; ent = ent->next) { + if (ent->mid == id) return 1; + } + return 0; +} +static void clear_damage() +{ + struct damaged_entry **ent = cache_damage, **end = cache_damage + CACHE_SIZE; + for (; ent < end; ent++) { + struct damaged_entry *ptr = *ent; + if (ptr) { + do { + struct damaged_entry *next = ptr->next; + free(ptr); + ptr = next; + } while (ptr); + *ent = NULL; + } + } +} +#else +#define Init_cache() ((void)0) +#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() { @@ -200,6 +273,7 @@ ent->mid = 0; ent++; } + CACHE_CLEAR_DAMAGE(); } static void @@ -208,6 +282,8 @@ { struct cache_entry *ent, *end; + if (!CACHE_DAMAGED_P(id)) return; + CACHE_UNDAMAGE(id); ent = cache; end = ent + CACHE_SIZE; while (ent < end) { if (ent->mid == id) { @@ -265,6 +341,7 @@ NODE * volatile body; struct cache_entry *ent; + CACHE_DAMAGE(id); if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) { /* store empty info in cache */ ent = cache + EXPR1(klass, id); @@ -1044,6 +1121,7 @@ Init_stack(0); Init_heap(); + Init_cache(); PUSH_SCOPE(); ruby_scope->local_vars = 0; ruby_scope->local_tbl = 0;