From ea78960ee5cb78c6aaaaa7091b85066a011c51e9 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 10 Sep 2020 16:51:24 +0900 Subject: [PATCH] sync callable_method_entry() callable_method_entry() read/write method table structures so that this function should be synchronized between Ractors. --- vm_method.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/vm_method.c b/vm_method.c index 58516b9ddd..0428ae6380 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1013,6 +1013,8 @@ complemented_callable_method_entry(VALUE klass, ID id) static const rb_callable_method_entry_t * cached_callable_method_entry(VALUE klass, ID mid) { + ASSERT_vm_locking(); + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); struct rb_class_cc_entries *ccs; @@ -1035,6 +1037,8 @@ cached_callable_method_entry(VALUE klass, ID mid) static void cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_t *cme) { + ASSERT_vm_locking(); + struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); struct rb_class_cc_entries *ccs; @@ -1054,19 +1058,25 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_ static const rb_callable_method_entry_t * callable_method_entry(VALUE klass, ID mid, VALUE *defined_class_ptr) { - VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS)); - const rb_callable_method_entry_t *cme = cached_callable_method_entry(klass, mid); + const rb_callable_method_entry_t *cme; - if (cme) { - if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class; - } - else { - VALUE defined_class; - rb_method_entry_t *me = search_method_protect(klass, mid, &defined_class); - if (defined_class_ptr) *defined_class_ptr = defined_class; - cme = prepare_callable_method_entry(defined_class, mid, me, TRUE); - if (cme) cache_callable_method_entry(klass, mid, cme); + VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS)); + RB_VM_LOCK_ENTER(); + { + cme = cached_callable_method_entry(klass, mid); + + if (cme) { + if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class; + } + else { + VALUE defined_class; + rb_method_entry_t *me = search_method_protect(klass, mid, &defined_class); + if (defined_class_ptr) *defined_class_ptr = defined_class; + cme = prepare_callable_method_entry(defined_class, mid, me, TRUE); + if (cme) cache_callable_method_entry(klass, mid, cme); + } } + RB_VM_LOCK_LEAVE(); return cme; }