src/class.c: add new function mrb_vm_find_method

The function skips `cp` dereference, and improve performance of method
calls slightly.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2023-01-20 18:34:36 +09:00
parent 6b0efd43da
commit 079244c36a
3 changed files with 13 additions and 7 deletions
+1
View File
@@ -22,6 +22,7 @@ mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
mrb_value mrb_mod_to_s(mrb_state *, mrb_value);
void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid);
mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
mrb_method_t mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid);
#endif
/* debug */
+8 -3
View File
@@ -1765,11 +1765,10 @@ mc_clear_by_id(mrb_state *mrb, mrb_sym id)
}
#endif
MRB_API mrb_method_t
mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
mrb_method_t
mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid)
{
mrb_method_t m;
struct RClass *c = *cp;
#ifndef MRB_NO_METHOD_CACHE
struct RClass *oc = c;
int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
@@ -1814,6 +1813,12 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
return m; /* no method */
}
MRB_API mrb_method_t
mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
{
return mrb_vm_find_method(mrb, *cp, cp, mid);
}
MRB_API mrb_method_t
mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
{
+4 -4
View File
@@ -562,7 +562,7 @@ prepare_missing(mrb_state *mrb, mrb_callinfo *ci, mrb_value recv, mrb_sym mid, m
if (mid != missing) {
ci->u.target_class = mrb_class(mrb, recv);
}
m = mrb_method_search_vm(mrb, &ci->u.target_class, missing);
m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, missing);
if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */
mrb_stack_extend(mrb, 4);
@@ -662,7 +662,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
ci = cipush(mrb, n, CINFO_DIRECT, NULL, NULL, BLK_PTR(blk), 0, 0);
funcall_args_capture(mrb, 0, argc, argv, blk, ci);
ci->u.target_class = mrb_class(mrb, self);
m = mrb_method_search_vm(mrb, &ci->u.target_class, mid);
m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, mid);
if (MRB_METHOD_UNDEF_P(m)) {
m = prepare_missing(mrb, ci, self, mid, mrb_nil_value(), FALSE);
}
@@ -816,7 +816,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
}
c = mrb_class(mrb, self);
m = mrb_method_search_vm(mrb, &c, name);
m = mrb_vm_find_method(mrb, c, &c, name);
if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */
goto funcall;
}
@@ -1769,7 +1769,7 @@ RETRY_TRY_BLOCK:
ci = cipush(mrb, a, CINFO_DIRECT, NULL, NULL, BLK_PTR(blk), 0, c);
recv = regs[0];
ci->u.target_class = (insn == OP_SUPER) ? CI_TARGET_CLASS(ci - 1)->super : mrb_class(mrb, recv);
m = mrb_method_search_vm(mrb, &ci->u.target_class, mid);
m = mrb_vm_find_method(mrb, ci->u.target_class, &ci->u.target_class, mid);
if (MRB_METHOD_UNDEF_P(m)) {
m = prepare_missing(mrb, ci, recv, mid, blk, (insn == OP_SUPER));
}