Use set_table to track const caches

Now that we have a `set_table` implementation, we can
use it to track const caches and save some memory.

We could even save some more memory if `numtable` didn't
store a copy of the `hash` and instead recomputed it every
time, but this is a quick win.
This commit is contained in:
Jean Boussier 2025-04-26 07:56:54 +02:00
parent e4f85bfc31
commit c0417bd094
Notes: git 2025-04-26 10:10:56 +00:00
6 changed files with 22 additions and 10 deletions

View File

@ -8903,6 +8903,7 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h
iseq.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
iseq.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
iseq.$(OBJEXT): $(top_srcdir)/internal/serial.h
iseq.$(OBJEXT): $(top_srcdir)/internal/set_table.h
iseq.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
iseq.$(OBJEXT): $(top_srcdir)/internal/string.h
iseq.$(OBJEXT): $(top_srcdir)/internal/symbol.h
@ -19549,6 +19550,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/re.h
vm.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
vm.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
vm.$(OBJEXT): $(top_srcdir)/internal/serial.h
vm.$(OBJEXT): $(top_srcdir)/internal/set_table.h
vm.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
vm.$(OBJEXT): $(top_srcdir)/internal/string.h
vm.$(OBJEXT): $(top_srcdir)/internal/struct.h

View File

@ -35,6 +35,8 @@ typedef int set_update_callback_func(st_data_t *key, st_data_t arg, int existing
size_t rb_set_table_size(const struct set_table *tbl);
#define set_init_table_with_size rb_set_init_table_with_size
set_table *rb_set_init_table_with_size(set_table *tab, const struct st_hash_type *, st_index_t);
#define set_init_numtable rb_set_init_numtable
set_table *rb_set_init_numtable(void);
#define set_delete rb_set_delete
int rb_set_delete(set_table *, st_data_t *); /* returns 0:notfound 1:deleted */
#define set_insert rb_set_insert

7
iseq.c
View File

@ -31,6 +31,7 @@
#include "internal/io.h"
#include "internal/ruby_parser.h"
#include "internal/sanitizers.h"
#include "internal/set_table.h"
#include "internal/symbol.h"
#include "internal/thread.h"
#include "internal/variable.h"
@ -110,14 +111,14 @@ remove_from_constant_cache(ID id, IC ic)
st_data_t ic_data = (st_data_t)ic;
if (rb_id_table_lookup(vm->constant_cache, id, &lookup_result)) {
st_table *ics = (st_table *)lookup_result;
st_delete(ics, &ic_data, NULL);
set_table *ics = (set_table *)lookup_result;
set_delete(ics, &ic_data);
if (ics->num_entries == 0 &&
// See comment in vm_track_constant_cache on why we need this check
id != vm->inserting_constant_cache_id) {
rb_id_table_delete(vm->constant_cache, id);
st_free_table(ics);
set_free_table(ics);
}
}
}

6
st.c
View File

@ -2459,6 +2459,12 @@ set_init_table_with_size(set_table *tab, const struct st_hash_type *type, st_ind
return tab;
}
set_table *
set_init_numtable(void)
{
return set_init_table_with_size(NULL, &type_numhash, 0);
}
size_t
set_table_size(const struct set_table *tbl)
{

View File

@ -26,6 +26,7 @@
#include "internal/proc.h"
#include "internal/random.h"
#include "internal/variable.h"
#include "internal/set_table.h"
#include "internal/struct.h"
#include "variable.h"
@ -6332,13 +6333,13 @@ vm_track_constant_cache(ID id, void *ic)
rb_vm_t *vm = GET_VM();
struct rb_id_table *const_cache = vm->constant_cache;
VALUE lookup_result;
st_table *ics;
set_table *ics;
if (rb_id_table_lookup(const_cache, id, &lookup_result)) {
ics = (st_table *)lookup_result;
ics = (set_table *)lookup_result;
}
else {
ics = st_init_numtable();
ics = set_init_numtable();
rb_id_table_insert(const_cache, id, (VALUE)ics);
}
@ -6356,7 +6357,7 @@ vm_track_constant_cache(ID id, void *ic)
*/
vm->inserting_constant_cache_id = id;
st_insert(ics, (st_data_t) ic, (st_data_t) Qtrue);
set_insert(ics, (st_data_t)ic);
vm->inserting_constant_cache_id = (ID)0;
}

View File

@ -125,7 +125,7 @@ vm_cme_invalidate(rb_callable_method_entry_t *cme)
}
static int
rb_clear_constant_cache_for_id_i(st_data_t ic, st_data_t idx, st_data_t arg)
rb_clear_constant_cache_for_id_i(st_data_t ic, st_data_t arg)
{
((IC) ic)->entry = NULL;
return ST_CONTINUE;
@ -141,8 +141,8 @@ rb_clear_constant_cache_for_id(ID id)
rb_vm_t *vm = GET_VM();
if (rb_id_table_lookup(vm->constant_cache, id, &lookup_result)) {
st_table *ics = (st_table *)lookup_result;
st_foreach(ics, rb_clear_constant_cache_for_id_i, (st_data_t) NULL);
set_table *ics = (set_table *)lookup_result;
set_foreach(ics, rb_clear_constant_cache_for_id_i, (st_data_t) NULL);
ruby_vm_constant_cache_invalidations += ics->num_entries;
}