summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2020-04-14 23:24:50 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2020-04-14 23:32:13 -0700
commit8355a998839f17ff214a89062821a0a4287f6a54 (patch)
tree987e49edc61b9ae3a4793e200bdb99a745cd52e7 /vm_insnhelper.c
parent2c12d111cb6efb110caa72b0e5314d3affbefb6e (diff)
Invalidate fastpath when calling attr_writer by super
We started to use fastpath on invokesuper when a method is not refinements since 5c27681813, but we shouldn't have used fastpath for attr_writer either. `cc->aux_.attr_index` is for an actual receiver class, while we store its superclass in `cc->klass` and therefore there's no way to properly invalidate attr_writer's inline cache when it's called by super. [Bug #16785] I suspect the same bug also exists in attr_reader. I'll address that in another commit.
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index a4edd9a797..c4a8dfaf61 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3231,9 +3231,18 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c
const struct rb_callcache *cc = vm_cc_new(klass, cme, vm_call_super_method);
RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc);
}
- else if (cached_cme->def->type == VM_METHOD_TYPE_REFINED) {
- // vm_call_refined (search_refined_method) assumes cc->call is vm_call_super_method on invokesuper.
- vm_cc_call_set(cd->cc, vm_call_super_method);
+ else {
+ switch (cached_cme->def->type) {
+ // vm_call_refined (search_refined_method) assumes cc->call is vm_call_super_method on invokesuper
+ case VM_METHOD_TYPE_REFINED:
+ // cc->klass is superclass of a class of receiver. Checking cc->klass is not enough to invalidate IVC for the receiver class.
+ case VM_METHOD_TYPE_ATTRSET:
+ // TODO: case VM_METHOD_TYPE_IVAR:
+ vm_cc_call_set(cd->cc, vm_call_super_method); // invalidate fastpath
+ break;
+ default:
+ break; // use fastpath
+ }
}
}
}