summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2021-12-21 14:06:02 +0900
committerKoichi Sasada <ko1@atdot.net>2021-12-21 15:21:30 +0900
commitad450c9fe51c51626dd07f6e766f47d839cae3ba (patch)
treef61545a929b263b3df661cd02b8affca12f12637 /vm_method.c
parent3c7e95966d6b9efd201170eb59b0e4a3c4eb6134 (diff)
make `overloaded_cme_table` truly weak key map
`overloaded_cme_table` keeps cme -> monly_cme pairs to manage corresponding `monly_cme` for `cme`. The lifetime of the `monly_cme` should be longer than `monly_cme`, but the previous patch losts the reference to the living `monly_cme`. Now `overloaded_cme_table` values are always root (keys are only weak reference), it means `monly_cme` does not freed until corresponding `cme` is invalidated. To make managing easy, move `overloaded_cme_table` to `rb_vm_t`.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5316
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c38
1 files changed, 15 insertions, 23 deletions
diff --git a/vm_method.c b/vm_method.c
index f71145576a..b8197e14ca 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -150,7 +150,7 @@ static rb_method_entry_t *rb_method_entry_alloc(ID called_id, VALUE owner, VALUE
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me);
static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id);
static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme);
-static void delete_overloaded_cme(const rb_callable_method_entry_t *cme);
+
static void
clear_method_cache_by_id_in_class(VALUE klass, ID mid)
@@ -216,7 +216,6 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
rb_callable_method_entry_t *monly_cme = (rb_callable_method_entry_t *)lookup_overloaded_cme(cme);
if (monly_cme) {
vm_cme_invalidate(monly_cme);
- delete_overloaded_cme(monly_cme);
}
}
}
@@ -393,6 +392,8 @@ rb_method_definition_release(rb_method_definition_t *def, int complemented)
}
}
+static void delete_overloaded_cme(const rb_callable_method_entry_t *cme);
+
void
rb_free_method_entry(const rb_method_entry_t *me)
{
@@ -922,12 +923,12 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
}
static rb_method_entry_t *rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def);
-static st_table *overloaded_cme_table;
-st_table *
-rb_vm_overloaded_cme_table(void)
+static st_table *
+overloaded_cme_table(void)
{
- return overloaded_cme_table;
+ VM_ASSERT(GET_VM()->overloaded_cme_table != NULL);
+ return GET_VM()->overloaded_cme_table;
}
#if VM_CHECK_MODE > 0
@@ -943,7 +944,7 @@ void
rb_vm_dump_overloaded_cme_table(void)
{
fprintf(stderr, "== rb_vm_dump_overloaded_cme_table\n");
- st_foreach(overloaded_cme_table, vm_dump_overloaded_cme_table, 0);
+ st_foreach(overloaded_cme_table(), vm_dump_overloaded_cme_table, 0);
}
#endif
@@ -956,10 +957,7 @@ lookup_overloaded_cme_i(st_data_t *key, st_data_t *value, st_data_t data, int ex
const rb_callable_method_entry_t **ptr = (const rb_callable_method_entry_t **)data;
if (rb_objspace_garbage_object_p((VALUE)cme) ||
- rb_objspace_garbage_object_p((VALUE)monly_cme) ||
- METHOD_ENTRY_INVALIDATED(cme) ||
- METHOD_ENTRY_INVALIDATED(monly_cme)) {
-
+ rb_objspace_garbage_object_p((VALUE)monly_cme)) {
*ptr = NULL;
return ST_DELETE;
}
@@ -977,14 +975,8 @@ lookup_overloaded_cme(const rb_callable_method_entry_t *cme)
ASSERT_vm_locking();
const rb_callable_method_entry_t *monly_cme = NULL;
- st_update(overloaded_cme_table, (st_data_t)cme, lookup_overloaded_cme_i, (st_data_t)&monly_cme);
-
- if (monly_cme) {
- return monly_cme;
- }
- else {
- return NULL;
- }
+ st_update(overloaded_cme_table(), (st_data_t)cme, lookup_overloaded_cme_i, (st_data_t)&monly_cme);
+ return monly_cme;
}
// used by gc.c
@@ -998,7 +990,7 @@ static void
delete_overloaded_cme(const rb_callable_method_entry_t *cme)
{
ASSERT_vm_locking();
- st_delete(overloaded_cme_table, (st_data_t *)&cme, NULL);
+ st_delete(overloaded_cme_table(), (st_data_t *)&cme, NULL);
}
static const rb_callable_method_entry_t *
@@ -1006,7 +998,7 @@ get_overloaded_cme(const rb_callable_method_entry_t *cme)
{
const rb_callable_method_entry_t *monly_cme = lookup_overloaded_cme(cme);
- if (monly_cme) {
+ if (monly_cme && !METHOD_ENTRY_INVALIDATED(monly_cme)) {
return monly_cme;
}
else {
@@ -1021,7 +1013,7 @@ get_overloaded_cme(const rb_callable_method_entry_t *cme)
def);
ASSERT_vm_locking();
- st_insert(overloaded_cme_table, (st_data_t)cme, (st_data_t)me);
+ st_insert(overloaded_cme_table(), (st_data_t)cme, (st_data_t)me);
METHOD_ENTRY_VISI_SET(me, METHOD_ENTRY_VISI(cme));
return (rb_callable_method_entry_t *)me;
@@ -2828,7 +2820,7 @@ obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
void
Init_Method(void)
{
- overloaded_cme_table = st_init_numtable();
+ //
}
void