sync callable_method_entry()

callable_method_entry() read/write method table structures so that
this function should be synchronized between Ractors.
This commit is contained in:
Koichi Sasada 2020-09-10 16:51:24 +09:00
parent 475c8701d7
commit ea78960ee5
Notes: git 2020-09-10 18:44:34 +09:00

View File

@ -1013,6 +1013,8 @@ complemented_callable_method_entry(VALUE klass, ID id)
static const rb_callable_method_entry_t * static const rb_callable_method_entry_t *
cached_callable_method_entry(VALUE klass, ID mid) cached_callable_method_entry(VALUE klass, ID mid)
{ {
ASSERT_vm_locking();
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass); struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs; struct rb_class_cc_entries *ccs;
@ -1035,6 +1037,8 @@ cached_callable_method_entry(VALUE klass, ID mid)
static void static void
cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_t *cme) 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_id_table *cc_tbl = RCLASS_CC_TBL(klass);
struct rb_class_cc_entries *ccs; 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 * static const rb_callable_method_entry_t *
callable_method_entry(VALUE klass, ID mid, VALUE *defined_class_ptr) 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;
const rb_callable_method_entry_t *cme = cached_callable_method_entry(klass, mid);
if (cme) { VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS));
if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class; RB_VM_LOCK_ENTER();
} {
else { cme = cached_callable_method_entry(klass, mid);
VALUE defined_class;
rb_method_entry_t *me = search_method_protect(klass, mid, &defined_class); if (cme) {
if (defined_class_ptr) *defined_class_ptr = defined_class; if (defined_class_ptr != NULL) *defined_class_ptr = cme->defined_class;
cme = prepare_callable_method_entry(defined_class, mid, me, TRUE); }
if (cme) cache_callable_method_entry(klass, mid, cme); 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; return cme;
} }