diff options
author | Koichi Sasada <ko1@atdot.net> | 2020-03-11 02:45:49 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2020-03-11 02:50:44 +0900 |
commit | 2943ff9d4441485a18773aa745bab7f47767dde2 (patch) | |
tree | af02635e8f3629930d572fb22f1517952c4672e1 /vm_method.c | |
parent | ec78b8b62a84fd57eb93d7b5de5b83ea517ad7c4 (diff) | |
download | ruby-2943ff9d4441485a18773aa745bab7f47767dde2.tar.gz |
fix bug on method cache invalidation.
To invalidate cached method entry, existing method entry (ment)
is marked as invalidated and replace with copied ment. However,
complemented method entry (method entries in Module) should not
be set to Module's m_tbl.
[Bug #16669]
Diffstat (limited to 'vm_method.c')
-rw-r--r-- | vm_method.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/vm_method.c b/vm_method.c index d1afb88e40..cce28462cc 100644 --- a/vm_method.c +++ b/vm_method.c @@ -166,15 +166,20 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid) // invalidate cme if found to invalidate the inline method cache. if (METHOD_ENTRY_CACHED(cme)) { - // invalidate cc by invalidating cc->cme - VALUE owner = cme->owner; - rb_callable_method_entry_t *new_cme = - (rb_callable_method_entry_t *)rb_method_entry_clone((const rb_method_entry_t *)cme); - struct rb_id_table *mtbl = RCLASS_M_TBL(RCLASS_ORIGIN(owner)); - rb_id_table_insert(mtbl, mid, (VALUE)new_cme); - RB_OBJ_WRITTEN(owner, cme, new_cme); + if (METHOD_ENTRY_COMPLEMENTED(cme)) { + // do nothing + } + else { + // invalidate cc by invalidating cc->cme + VALUE owner = cme->owner; + VM_ASSERT(BUILTIN_TYPE(owner) == T_CLASS); + rb_callable_method_entry_t *new_cme = + (rb_callable_method_entry_t *)rb_method_entry_clone((const rb_method_entry_t *)cme); + struct rb_id_table *mtbl = RCLASS_M_TBL(RCLASS_ORIGIN(owner)); + rb_id_table_insert(mtbl, mid, (VALUE)new_cme); + RB_OBJ_WRITTEN(owner, cme, new_cme); + } vm_me_invalidate_cache((rb_callable_method_entry_t *)cme); - RB_DEBUG_COUNTER_INC(cc_invalidate_tree_cme); } |