summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gc.c8
-rw-r--r--vm.c6
-rw-r--r--vm_core.h1
-rw-r--r--vm_method.c38
4 files changed, 22 insertions, 31 deletions
diff --git a/gc.c b/gc.c
index 5fd46defb4..c4cac9bd07 100644
--- a/gc.c
+++ b/gc.c
@@ -6379,9 +6379,7 @@ mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
if (def->body.iseq.iseqptr) gc_mark(objspace, (VALUE)def->body.iseq.iseqptr);
gc_mark(objspace, (VALUE)def->body.iseq.cref);
if (def->iseq_overload && me->defined_class) { // cme
- const rb_callable_method_entry_t *monly_cme = rb_vm_lookup_overloaded_cme((const rb_callable_method_entry_t *)me);
- if (monly_cme) {
- gc_mark(objspace, (VALUE)monly_cme);
+ if (rb_vm_lookup_overloaded_cme((const rb_callable_method_entry_t *)me)) {
gc_mark_and_pin(objspace, (VALUE)me);
}
}
@@ -10113,9 +10111,6 @@ gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t * objspace,
extern rb_symbols_t ruby_global_symbols;
#define global_symbols ruby_global_symbols
-
-st_table *rb_vm_overloaded_cme_table(void);
-
static void
gc_update_references(rb_objspace_t *objspace)
{
@@ -10151,7 +10146,6 @@ gc_update_references(rb_objspace_t *objspace)
gc_update_table_refs(objspace, objspace->id_to_obj_tbl);
gc_update_table_refs(objspace, global_symbols.str_sym);
gc_update_table_refs(objspace, finalizer_table);
- gc_update_table_refs(objspace, rb_vm_overloaded_cme_table());
}
static VALUE
diff --git a/vm.c b/vm.c
index 0d423cd979..287fe2547d 100644
--- a/vm.c
+++ b/vm.c
@@ -2540,6 +2540,8 @@ rb_vm_update_references(void *ptr)
vm->top_self = rb_gc_location(vm->top_self);
vm->orig_progname = rb_gc_location(vm->orig_progname);
+ rb_gc_update_tbl_refs(vm->overloaded_cme_table);
+
if (vm->coverages) {
vm->coverages = rb_gc_location(vm->coverages);
vm->me2counter = rb_gc_location(vm->me2counter);
@@ -2637,9 +2639,10 @@ rb_vm_mark(void *ptr)
rb_mark_tbl(vm->loading_table);
}
- rb_gc_mark_values(RUBY_NSIG, vm->trap_list.cmd);
+ rb_gc_mark_values(RUBY_NSIG, vm->trap_list.cmd);
rb_id_table_foreach_values(vm->negative_cme_table, vm_mark_negative_cme, NULL);
+ rb_mark_tbl_no_pin(vm->overloaded_cme_table);
for (i=0; i<VM_GLOBAL_CC_CACHE_TABLE_SIZE; i++) {
const struct rb_callcache *cc = vm->global_cc_cache_table[i];
@@ -3801,6 +3804,7 @@ Init_BareVM(void)
vm->objspace = rb_objspace_alloc();
ruby_current_vm_ptr = vm;
vm->negative_cme_table = rb_id_table_create(16);
+ vm->overloaded_cme_table = st_init_numtable();
Init_native_thread(th);
th->vm = vm;
diff --git a/vm_core.h b/vm_core.h
index 6bbce23078..11866b85e5 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -714,6 +714,7 @@ typedef struct rb_vm_struct {
int builtin_inline_index;
struct rb_id_table *negative_cme_table;
+ st_table *overloaded_cme_table; // cme -> overloaded_cme
#ifndef VM_GLOBAL_CC_CACHE_TABLE_SIZE
#define VM_GLOBAL_CC_CACHE_TABLE_SIZE 1023
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