ruby-changes:69781
From: Koichi <ko1@a...>
Date: Wed, 17 Nov 2021 22:22:01 +0900 (JST)
Subject: [ruby-changes:69781] b2255153cf (master): `vm_empty_cc_for_super`
https://git.ruby-lang.org/ruby.git/commit/?id=b2255153cf From b2255153cf2fe9d7b851c59cc09b358c0630e0a2 Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Tue, 16 Nov 2021 17:57:49 +0900 Subject: `vm_empty_cc_for_super` Same as `vm_empty_cc`, introduce a global variable which has `.call_ = vm_call_super_method`. Use it if the `cme == NULL` on `vm_search_super_method`. --- vm.c | 16 ++++++++++++++++ vm_callinfo.h | 1 + vm_insnhelper.c | 37 +++++++++++++++++++++++++++---------- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/vm.c b/vm.c index f13e07cef3d..a868355bbe5 100644 --- a/vm.c +++ b/vm.c @@ -439,6 +439,16 @@ static const struct rb_callcache vm_empty_cc = { https://github.com/ruby/ruby/blob/trunk/vm.c#L439 } }; +static const struct rb_callcache vm_empty_cc_for_super = { + .flags = T_IMEMO | (imemo_callcache << FL_USHIFT) | VM_CALLCACHE_UNMARKABLE, + .klass = Qfalse, + .cme_ = NULL, + .call_ = vm_call_super_method, + .aux_ = { + .v = Qfalse, + } +}; + static void thread_free(void *ptr); void @@ -4176,6 +4186,12 @@ rb_vm_empty_cc(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L4186 return &vm_empty_cc; } +MJIT_FUNC_EXPORTED const struct rb_callcache * +rb_vm_empty_cc_for_super(void) +{ + return &vm_empty_cc_for_super; +} + #endif /* #ifndef MJIT_HEADER */ #include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */ diff --git a/vm_callinfo.h b/vm_callinfo.h index fa35c98d174..2641ee79c52 100644 --- a/vm_callinfo.h +++ b/vm_callinfo.h @@ -382,6 +382,7 @@ vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *c https://github.com/ruby/ruby/blob/trunk/vm_callinfo.h#L382 } extern const struct rb_callcache *rb_vm_empty_cc(void); +extern const struct rb_callcache *rb_vm_empty_cc_for_super(void); #define vm_cc_empty() rb_vm_empty_cc() /* callcache: mutate */ diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 5e5554cb675..ff02f141410 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -38,6 +38,7 @@ extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L38 #ifndef MJIT_HEADER static const struct rb_callcache vm_empty_cc; +static const struct rb_callcache vm_empty_cc_for_super; #endif /* control stack frame */ @@ -3711,6 +3712,11 @@ vm_call_super_method(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, st https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3712 { RB_DEBUG_COUNTER_INC(ccf_super_method); + // This line is introduced to make different from `vm_call_general` because some compilers (VC we found) + // can merge the function and the address of the function becomes same. + // The address of `vm_call_super_method` is used in `search_refined_method`, so it should be different. + if (ec == NULL) rb_bug("unreachable"); + /* this check is required to distinguish with other functions. */ VM_ASSERT(vm_cc_call(calling->cc) == vm_call_super_method); return vm_call_method(ec, reg_cfp, calling); @@ -3737,6 +3743,16 @@ vm_super_outside(void) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3743 rb_raise(rb_eNoMethodError, "super called outside of method"); } +static const struct rb_callcache * +empty_cc_for_super(void) +{ +#ifdef MJIT_HEADER + return rb_vm_empty_cc_for_super(); +#else + return &vm_empty_cc_for_super; +#endif +} + static const struct rb_callcache * vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *cd, VALUE recv) { @@ -3800,19 +3816,18 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3816 // define_method can cache for different method id if (cached_cme == NULL) { - // temporary CC. revisit it - static const struct rb_callcache *empty_cc_for_super = NULL; - if (empty_cc_for_super == NULL) { - empty_cc_for_super = vm_cc_new(0, NULL, vm_call_super_method); - FL_SET_RAW((VALUE)empty_cc_for_super, VM_CALLCACHE_UNMARKABLE); - rb_gc_register_mark_object((VALUE)empty_cc_for_super); - } - RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc = empty_cc_for_super); + // empty_cc_for_super is not markable object + cd->cc = empty_cc_for_super(); } else if (cached_cme->called_id != mid) { const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid); - cc = vm_cc_new(klass, cme, vm_call_super_method); - RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc); + if (cme) { + cc = vm_cc_new(klass, cme, vm_call_super_method); + RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc); + } + else { + cd->cc = cc = empty_cc_for_super(); + } } else { switch (cached_cme->def->type) { @@ -3829,6 +3844,8 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3844 } } + VM_ASSERT((vm_cc_cme(cc), true)); + return cc; } -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/