aboutsummaryrefslogtreecommitdiffstats
path: root/vm_method.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-03-11 02:45:49 +0900
committerKoichi Sasada <ko1@atdot.net>2020-03-11 02:50:44 +0900
commit2943ff9d4441485a18773aa745bab7f47767dde2 (patch)
treeaf02635e8f3629930d572fb22f1517952c4672e1 /vm_method.c
parentec78b8b62a84fd57eb93d7b5de5b83ea517ad7c4 (diff)
downloadruby-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.c21
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);
}