From 0964593e5d7cee2f6a72911813dc72a6152f4ec9 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 21 May 2025 08:41:13 +0200 Subject: [PATCH] Shrink `sym_proc_cache` by half There is no need to store the symbol and the proc given the proc has a reference to the symbol. This makes the cache half as small, now fitting in an object slot, but also make it easier to allow that cache to be used by ractors, assuming we'd make `Symbol#to_proc` return a shareable proc. --- proc.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/proc.c b/proc.c index c6568fe1a6..3b8ccebb22 100644 --- a/proc.c +++ b/proc.c @@ -1515,6 +1515,7 @@ rb_hash_proc(st_index_t hash, VALUE prc) return hash; } +static VALUE sym_proc_cache = Qfalse; /* * call-seq: @@ -1533,32 +1534,32 @@ rb_hash_proc(st_index_t hash, VALUE prc) VALUE rb_sym_to_proc(VALUE sym) { - static VALUE sym_proc_cache = Qfalse; enum {SYM_PROC_CACHE_SIZE = 67}; - VALUE proc; - long index; - ID id; - - id = SYM2ID(sym); if (rb_ractor_main_p()) { - index = (id % SYM_PROC_CACHE_SIZE) << 1; if (!sym_proc_cache) { - sym_proc_cache = rb_ary_hidden_new(SYM_PROC_CACHE_SIZE * 2); - rb_vm_register_global_object(sym_proc_cache); - rb_ary_store(sym_proc_cache, SYM_PROC_CACHE_SIZE*2 - 1, Qnil); + sym_proc_cache = rb_ary_hidden_new(SYM_PROC_CACHE_SIZE); + rb_ary_store(sym_proc_cache, SYM_PROC_CACHE_SIZE - 1, Qnil); } - if (RARRAY_AREF(sym_proc_cache, index) == sym) { - return RARRAY_AREF(sym_proc_cache, index + 1); - } - else { - proc = sym_proc_new(rb_cProc, ID2SYM(id)); - RARRAY_ASET(sym_proc_cache, index, sym); - RARRAY_ASET(sym_proc_cache, index + 1, proc); - return proc; + + ID id = SYM2ID(sym); + long index = (id % SYM_PROC_CACHE_SIZE); + VALUE procval = RARRAY_AREF(sym_proc_cache, index); + if (RTEST(procval)) { + rb_proc_t *proc; + GetProcPtr(procval, proc); + + if (proc->block.as.symbol == sym) { + return procval; + } } + + procval = sym_proc_new(rb_cProc, sym); + RARRAY_ASET(sym_proc_cache, index, procval); + + return RB_GC_GUARD(procval); } else { - return sym_proc_new(rb_cProc, ID2SYM(id)); + return sym_proc_new(rb_cProc, sym); } } @@ -4575,6 +4576,8 @@ Init_Proc(void) void Init_Binding(void) { + rb_gc_register_address(&sym_proc_cache); + rb_cBinding = rb_define_class("Binding", rb_cObject); rb_undef_alloc_func(rb_cBinding); rb_undef_method(CLASS_OF(rb_cBinding), "new");