diff options
author | Jean Boussier <[email protected]> | 2025-05-21 08:41:13 +0200 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2025-05-21 09:29:27 +0200 |
commit | 0964593e5d7cee2f6a72911813dc72a6152f4ec9 (patch) | |
tree | 3f565bb054d369a954b7817698ee6b0a51ccc404 /proc.c | |
parent | c980cab1552e2319ef40020a06a09dd7a0582ed0 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13390
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 41 |
1 files changed, 22 insertions, 19 deletions
@@ -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); - } - if (RARRAY_AREF(sym_proc_cache, index) == sym) { - return RARRAY_AREF(sym_proc_cache, index + 1); + sym_proc_cache = rb_ary_hidden_new(SYM_PROC_CACHE_SIZE); + rb_ary_store(sym_proc_cache, SYM_PROC_CACHE_SIZE - 1, Qnil); } - 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"); |