class.c: use 2-way set-associative method cache

Right-shift class pointer by 4 before hashing to remove
always-zero alignment bits, improving hash distribution.
Organize 256 cache entries as 128 sets x 2 ways to reduce
conflict misses when multiple methods share a hash bucket.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-03-04 22:48:34 +09:00
parent 7675601b92
commit d0d2c3072c
+12 -2
View File
@@ -2621,9 +2621,16 @@ mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym
mrb_method_t m;
#ifndef MRB_NO_METHOD_CACHE
struct RClass *oc = c;
int h = mrb_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
struct mrb_cache_entry *mc = &mrb->cache[h];
int h = mrb_int_hash_func(mrb, ((intptr_t)oc >> 4) ^ mid) & (MRB_METHOD_CACHE_SIZE/2-1);
struct mrb_cache_entry *mc = &mrb->cache[h * 2];
/* check way 0 */
if (mc->c == c && mc->mid == mid) {
*cp = mc->c0;
return mc->m;
}
/* check way 1 */
mc++;
if (mc->c == c && mc->mid == mid) {
*cp = mc->c0;
return mc->m;
@@ -2641,6 +2648,9 @@ mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym
*cp = c;
m = create_method_value(mrb, flags, ptr);
#ifndef MRB_NO_METHOD_CACHE
mc--; /* back to way 0 */
if (mc->c != NULL && mc[1].c == NULL)
mc++; /* way 1 is empty, use it */
mc->c = oc;
mc->c0 = c;
mc->mid = mid;