Skip to content

Commit bc789ca

Browse files
byrootetiennebarrie
andcommitted
Convert rb_class_cc_entries.entries in a flexible array member
`rb_class_cc_entries` is little more than a `len` and `capa`. Hence embedding the entries doesn't cost much extra copying and saves a bit of memory and some pointer chasing. Co-Authored-By: Étienne Barrié <[email protected]>
1 parent c6dd3ce commit bc789ca

File tree

3 files changed

+31
-36
lines changed

3 files changed

+31
-36
lines changed

vm_callinfo.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,15 @@ struct rb_class_cc_entries {
585585
unsigned int argc;
586586
unsigned int flag;
587587
const struct rb_callcache *cc;
588-
} *entries;
588+
} entries[FLEX_ARY_LEN];
589589
};
590590

591+
static inline size_t
592+
vm_ccs_alloc_size(size_t capa)
593+
{
594+
return offsetof(struct rb_class_cc_entries, entries) + (sizeof(struct rb_class_cc_entries_entry) * capa);
595+
}
596+
591597
#if VM_CHECK_MODE > 0
592598

593599
const rb_callable_method_entry_t *rb_vm_lookup_overloaded_cme(const rb_callable_method_entry_t *cme);

vm_insnhelper.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,37 +1981,37 @@ static VALUE vm_mtbl_dump(VALUE klass, ID target_mid);
19811981
static struct rb_class_cc_entries *
19821982
vm_ccs_create(VALUE klass, VALUE cc_tbl, ID mid, const rb_callable_method_entry_t *cme)
19831983
{
1984-
struct rb_class_cc_entries *ccs = ALLOC(struct rb_class_cc_entries);
1984+
int initial_capa = 2;
1985+
struct rb_class_cc_entries *ccs = ruby_xmalloc(vm_ccs_alloc_size(initial_capa));
19851986
#if VM_CHECK_MODE > 0
19861987
ccs->debug_sig = ~(VALUE)ccs;
19871988
#endif
1988-
ccs->capa = 0;
1989+
ccs->capa = initial_capa;
19891990
ccs->len = 0;
19901991
ccs->cme = cme;
19911992
METHOD_ENTRY_CACHED_SET((rb_callable_method_entry_t *)cme);
1992-
ccs->entries = NULL;
19931993

19941994
rb_managed_id_table_insert(cc_tbl, mid, (VALUE)ccs);
19951995
RB_OBJ_WRITTEN(cc_tbl, Qundef, cme);
19961996
return ccs;
19971997
}
19981998

19991999
static void
2000-
vm_ccs_push(VALUE cc_tbl, struct rb_class_cc_entries *ccs, const struct rb_callinfo *ci, const struct rb_callcache *cc)
2000+
vm_ccs_push(VALUE cc_tbl, ID mid, struct rb_class_cc_entries *ccs, const struct rb_callinfo *ci, const struct rb_callcache *cc)
20012001
{
20022002
if (! vm_cc_markable(cc)) {
20032003
return;
20042004
}
20052005

20062006
if (UNLIKELY(ccs->len == ccs->capa)) {
2007-
if (ccs->capa == 0) {
2008-
ccs->capa = 1;
2009-
ccs->entries = ALLOC_N(struct rb_class_cc_entries_entry, ccs->capa);
2010-
}
2011-
else {
2012-
ccs->capa *= 2;
2013-
REALLOC_N(ccs->entries, struct rb_class_cc_entries_entry, ccs->capa);
2014-
}
2007+
RUBY_ASSERT(ccs->capa > 0);
2008+
ccs->capa *= 2;
2009+
ccs = ruby_xrealloc(ccs, vm_ccs_alloc_size(ccs->capa));
2010+
#if VM_CHECK_MODE > 0
2011+
ccs->debug_sig = ~(VALUE)ccs;
2012+
#endif
2013+
// GC?
2014+
rb_managed_id_table_insert(cc_tbl, mid, (VALUE)ccs);
20152015
}
20162016
VM_ASSERT(ccs->len < ccs->capa);
20172017

@@ -2143,7 +2143,7 @@ vm_populate_cc(VALUE klass, const struct rb_callinfo * const ci, ID mid)
21432143
cme = rb_check_overloaded_cme(cme, ci);
21442144

21452145
const struct rb_callcache *cc = vm_cc_new(klass, cme, vm_call_general, cc_type_normal);
2146-
vm_ccs_push(cc_tbl, ccs, ci, cc);
2146+
vm_ccs_push(cc_tbl, mid, ccs, ci, cc);
21472147

21482148
VM_ASSERT(vm_cc_cme(cc) != NULL);
21492149
VM_ASSERT(cme->called_id == mid);

vm_method.c

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,6 @@ static inline rb_method_entry_t *lookup_method_table(VALUE klass, ID id);
2222
#define ruby_running (GET_VM()->running)
2323
/* int ruby_running = 0; */
2424

25-
static void
26-
vm_ccs_free(struct rb_class_cc_entries *ccs)
27-
{
28-
if (ccs->entries) {
29-
ruby_xfree(ccs->entries);
30-
}
31-
ruby_xfree(ccs);
32-
}
33-
3425
static enum rb_id_table_iterator_result
3526
mark_cc_entry_i(VALUE ccs_ptr, void *data)
3627
{
@@ -39,7 +30,7 @@ mark_cc_entry_i(VALUE ccs_ptr, void *data)
3930
VM_ASSERT(vm_ccs_p(ccs));
4031

4132
if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
42-
vm_ccs_free(ccs);
33+
ruby_xfree(ccs);
4334
return ID_TABLE_DELETE;
4435
}
4536
else {
@@ -69,7 +60,7 @@ cc_table_free_i(VALUE ccs_ptr, void *data)
6960
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
7061
VM_ASSERT(vm_ccs_p(ccs));
7162

72-
vm_ccs_free(ccs);
63+
ruby_xfree(ccs);
7364

7465
return ID_TABLE_CONTINUE;
7566
}
@@ -146,13 +137,13 @@ static enum rb_id_table_iterator_result
146137
vm_cc_table_dup_i(ID key, VALUE old_ccs_ptr, void *data)
147138
{
148139
struct rb_class_cc_entries *old_ccs = (struct rb_class_cc_entries *)old_ccs_ptr;
149-
struct rb_class_cc_entries *new_ccs = ALLOC(struct rb_class_cc_entries);
150-
MEMCPY(new_ccs, old_ccs, struct rb_class_cc_entries, 1);
140+
size_t memsize = vm_ccs_alloc_size(old_ccs->capa);
141+
struct rb_class_cc_entries *new_ccs = ruby_xmalloc(memsize);
142+
memcpy(new_ccs, old_ccs, memsize);
143+
151144
#if VM_CHECK_MODE > 0
152145
new_ccs->debug_sig = ~(VALUE)new_ccs;
153146
#endif
154-
new_ccs->entries = ALLOC_N(struct rb_class_cc_entries_entry, new_ccs->capa);
155-
MEMCPY(new_ccs->entries, old_ccs->entries, struct rb_class_cc_entries_entry, new_ccs->capa);
156147

157148
VALUE new_table = (VALUE)data;
158149
rb_managed_id_table_insert(new_table, key, (VALUE)new_ccs);
@@ -173,12 +164,10 @@ rb_vm_cc_table_dup(VALUE old_table)
173164
static void
174165
vm_ccs_invalidate(struct rb_class_cc_entries *ccs)
175166
{
176-
if (ccs->entries) {
177-
for (int i=0; i<ccs->len; i++) {
178-
const struct rb_callcache *cc = ccs->entries[i].cc;
179-
VM_ASSERT(!vm_cc_super_p(cc) && !vm_cc_refinement_p(cc));
180-
vm_cc_invalidate(cc);
181-
}
167+
for (int i=0; i<ccs->len; i++) {
168+
const struct rb_callcache *cc = ccs->entries[i].cc;
169+
VM_ASSERT(!vm_cc_super_p(cc) && !vm_cc_refinement_p(cc));
170+
vm_cc_invalidate(cc);
182171
}
183172
}
184173

@@ -187,7 +176,7 @@ rb_vm_ccs_invalidate_and_free(struct rb_class_cc_entries *ccs)
187176
{
188177
RB_DEBUG_COUNTER_INC(ccs_free);
189178
vm_ccs_invalidate(ccs);
190-
vm_ccs_free(ccs);
179+
ruby_xfree(ccs);
191180
}
192181

193182
void

0 commit comments

Comments
 (0)