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`.
This commit is contained in:
parent
84aba25031
commit
b2255153cf
Notes:
git
2021-11-17 22:22:04 +09:00
16
vm.c
16
vm.c
@ -439,6 +439,16 @@ static const struct rb_callcache vm_empty_cc = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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);
|
static void thread_free(void *ptr);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -4176,6 +4186,12 @@ rb_vm_empty_cc(void)
|
|||||||
return &vm_empty_cc;
|
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 */
|
#endif /* #ifndef MJIT_HEADER */
|
||||||
|
|
||||||
#include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */
|
#include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */
|
||||||
|
@ -382,6 +382,7 @@ vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *c
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const struct rb_callcache *rb_vm_empty_cc(void);
|
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()
|
#define vm_cc_empty() rb_vm_empty_cc()
|
||||||
|
|
||||||
/* callcache: mutate */
|
/* callcache: mutate */
|
||||||
|
@ -38,6 +38,7 @@ extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
|
|||||||
|
|
||||||
#ifndef MJIT_HEADER
|
#ifndef MJIT_HEADER
|
||||||
static const struct rb_callcache vm_empty_cc;
|
static const struct rb_callcache vm_empty_cc;
|
||||||
|
static const struct rb_callcache vm_empty_cc_for_super;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* control stack frame */
|
/* control stack frame */
|
||||||
@ -3711,6 +3712,11 @@ vm_call_super_method(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, st
|
|||||||
{
|
{
|
||||||
RB_DEBUG_COUNTER_INC(ccf_super_method);
|
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. */
|
/* this check is required to distinguish with other functions. */
|
||||||
VM_ASSERT(vm_cc_call(calling->cc) == vm_call_super_method);
|
VM_ASSERT(vm_cc_call(calling->cc) == vm_call_super_method);
|
||||||
return vm_call_method(ec, reg_cfp, calling);
|
return vm_call_method(ec, reg_cfp, calling);
|
||||||
@ -3737,6 +3743,16 @@ vm_super_outside(void)
|
|||||||
rb_raise(rb_eNoMethodError, "super called outside of method");
|
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 *
|
static const struct rb_callcache *
|
||||||
vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *cd, VALUE recv)
|
vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *cd, VALUE recv)
|
||||||
{
|
{
|
||||||
@ -3800,20 +3816,19 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c
|
|||||||
|
|
||||||
// define_method can cache for different method id
|
// define_method can cache for different method id
|
||||||
if (cached_cme == NULL) {
|
if (cached_cme == NULL) {
|
||||||
// temporary CC. revisit it
|
// empty_cc_for_super is not markable object
|
||||||
static const struct rb_callcache *empty_cc_for_super = NULL;
|
cd->cc = empty_cc_for_super();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else if (cached_cme->called_id != mid) {
|
else if (cached_cme->called_id != mid) {
|
||||||
const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
|
const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
|
||||||
|
if (cme) {
|
||||||
cc = vm_cc_new(klass, cme, vm_call_super_method);
|
cc = vm_cc_new(klass, cme, vm_call_super_method);
|
||||||
RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc);
|
RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
cd->cc = cc = empty_cc_for_super();
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
switch (cached_cme->def->type) {
|
switch (cached_cme->def->type) {
|
||||||
// vm_call_refined (search_refined_method) assumes cc->call is vm_call_super_method on invokesuper
|
// vm_call_refined (search_refined_method) assumes cc->call is vm_call_super_method on invokesuper
|
||||||
@ -3829,6 +3844,8 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VM_ASSERT((vm_cc_cme(cc), true));
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user