diff options
Diffstat (limited to 'iseq.c')
-rw-r--r-- | iseq.c | 29 |
1 files changed, 29 insertions, 0 deletions
@@ -3407,6 +3407,32 @@ rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events) } } +bool rb_vm_call_ivar_attrset_p(const vm_call_handler ch); +void rb_vm_cc_general(const struct rb_callcache *cc); + +static int +clear_attr_ccs_i(void *vstart, void *vend, size_t stride, void *data) +{ + VALUE v = (VALUE)vstart; + for (; v != (VALUE)vend; v += stride) { + void *ptr = asan_poisoned_object_p(v); + asan_unpoison_object(v, false); + + if (imemo_type_p(v, imemo_callcache) && rb_vm_call_ivar_attrset_p(((const struct rb_callcache *)v)->call_)) { + rb_vm_cc_general((struct rb_callcache *)v); + } + + asan_poison_object_if(ptr, v); + } + return 0; +} + +void +rb_clear_attr_ccs(void) +{ + rb_objspace_each_objects(clear_attr_ccs_i, NULL); +} + static int trace_set_i(void *vstart, void *vend, size_t stride, void *data) { @@ -3420,6 +3446,9 @@ trace_set_i(void *vstart, void *vend, size_t stride, void *data) if (rb_obj_is_iseq(v)) { rb_iseq_trace_set(rb_iseq_check((rb_iseq_t *)v), turnon_events); } + else if (imemo_type_p(v, imemo_callcache) && rb_vm_call_ivar_attrset_p(((const struct rb_callcache *)v)->call_)) { + rb_vm_cc_general((struct rb_callcache *)v); + } asan_poison_object_if(ptr, v); } |