vm.c: replace constant cache generation counter with direct invalidation

Remove the per-entry generation field and per-state generation
counter. Invalidation now clears entries directly, removing one
comparison from every OP_GETCONST hot path.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-03-05 09:07:19 +09:00
parent d0d2c3072c
commit 50bc8c6136
3 changed files with 21 additions and 7 deletions
+5 -2
View File
@@ -256,7 +256,6 @@ mrb_static_assert_powerof2(MRB_CONST_CACHE_SIZE);
struct mrb_const_cache_entry {
const struct mrb_irep *irep;
mrb_sym sym;
uint32_t generation;
mrb_value value;
};
#endif
@@ -316,7 +315,6 @@ struct mrb_state {
#endif
#ifndef MRB_NO_CONST_CACHE
uint32_t const_generation;
struct mrb_const_cache_entry const_cache[MRB_CONST_CACHE_SIZE];
#endif
@@ -1307,6 +1305,11 @@ MRB_API void mrb_method_cache_clear(mrb_state *mrb);
#else
#define mrb_method_cache_clear(mrb) ((void)0)
#endif
#ifndef MRB_NO_CONST_CACHE
void mrb_const_cache_clear(mrb_state *mrb);
#else
#define mrb_const_cache_clear(mrb) ((void)0)
#endif
/**
* Check if mrb_open() failed
+15 -3
View File
@@ -1423,6 +1423,18 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
* Raises:
* E_TYPE_ERROR: If `mod` is not a class or module.
*/
#ifndef MRB_NO_CONST_CACHE
void
mrb_const_cache_clear(mrb_state *mrb)
{
struct mrb_const_cache_entry *cc = mrb->const_cache;
for (int i=0; i<MRB_CONST_CACHE_SIZE; cc++,i++) {
cc->irep = NULL;
}
}
#endif
MRB_API void
mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
{
@@ -1432,7 +1444,7 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
}
mrb_obj_iv_set(mrb, mrb_obj_ptr(mod), sym, v);
#ifndef MRB_NO_CONST_CACHE
mrb->const_generation++;
mrb_const_cache_clear(mrb);
#endif
if (!mrb->bootstrapping) {
@@ -1461,7 +1473,7 @@ mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym)
mod_const_check(mrb, mod);
mrb_iv_remove(mrb, mod, sym);
#ifndef MRB_NO_CONST_CACHE
mrb->const_generation++;
mrb_const_cache_clear(mrb);
#endif
}
@@ -1481,7 +1493,7 @@ mrb_define_const_id(mrb_state *mrb, struct RClass *mod, mrb_sym name, mrb_value
{
mrb_obj_iv_set(mrb, (struct RObject*)mod, name, v);
#ifndef MRB_NO_CONST_CACHE
mrb->const_generation++;
mrb_const_cache_clear(mrb);
#endif
}
+1 -2
View File
@@ -2032,7 +2032,7 @@ RETRY_TRY_BLOCK:
mrb_sym sym = irep->syms[b];
uint32_t h = mrb_int_hash_func(mrb, ((intptr_t)irep) ^ sym) & (MRB_CONST_CACHE_SIZE-1);
struct mrb_const_cache_entry *cc = &mrb->const_cache[h];
if (cc->irep == irep && cc->sym == sym && cc->generation == mrb->const_generation) {
if (cc->irep == irep && cc->sym == sym) {
regs[a] = cc->value;
NEXT;
}
@@ -2044,7 +2044,6 @@ RETRY_TRY_BLOCK:
#ifndef MRB_NO_CONST_CACHE
cc->irep = irep;
cc->sym = sym;
cc->generation = mrb->const_generation;
cc->value = v;
#endif
}