summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vm_insnhelper.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 20e26723fc..b62ab170d3 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1795,9 +1795,10 @@ vm_search_method_slowpath0(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
return cc;
}
-ALWAYS_INLINE(static const struct rb_callcache *vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass));
-
-static inline const struct rb_callcache *
+#ifndef MJIT_HEADER
+ALWAYS_INLINE(static inline const struct rb_callcache *vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass));
+#endif
+static const struct rb_callcache *
vm_search_method_fastpath(VALUE cd_owner, struct rb_call_data *cd, VALUE klass)
{
const struct rb_callcache *cc = cd->cc;
@@ -4427,20 +4428,46 @@ vm_invokeblock_i(struct rb_execution_context_struct *ec,
}
}
+#ifdef MJIT_HEADER
+static const struct rb_callcache *
+vm_search_method_wrap(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
+{
+ return vm_search_method((VALUE)reg_cfp->iseq, cd, recv);
+}
+
+static const struct rb_callcache *
+vm_search_invokeblock(const struct rb_control_frame_struct *reg_cfp, struct rb_call_data *cd, VALUE recv)
+{
+ return rb_vm_empty_cc();
+}
+
+# define mexp_search_method vm_search_method_wrap
+# define mexp_search_super vm_search_super_method
+# define mexp_search_invokeblock vm_search_invokeblock
+#else
enum method_explorer_type {
mexp_search_method,
mexp_search_invokeblock,
mexp_search_super,
};
+#endif
-static inline VALUE
+static
+#ifndef MJIT_HEADER
+inline
+#endif
+VALUE
vm_sendish(
struct rb_execution_context_struct *ec,
struct rb_control_frame_struct *reg_cfp,
struct rb_call_data *cd,
VALUE block_handler,
- enum method_explorer_type method_explorer)
-{
+#ifdef MJIT_HEADER
+ const struct rb_callcache *(*method_explorer)(const struct rb_control_frame_struct *cfp, struct rb_call_data *cd, VALUE recv)
+#else
+ enum method_explorer_type method_explorer
+#endif
+) {
VALUE val;
const struct rb_callinfo *ci = cd->ci;
const struct rb_callcache *cc;
@@ -4454,6 +4481,11 @@ vm_sendish(
.ci = ci,
};
+// The enum-based branch and inlining are faster in VM, but function pointers without inlining are faster in JIT.
+#ifdef MJIT_HEADER
+ calling.cc = cc = method_explorer(GET_CFP(), cd, recv);
+ val = vm_cc_call(cc)(ec, GET_CFP(), &calling);
+#else
switch (method_explorer) {
case mexp_search_method:
calling.cc = cc = vm_search_method_fastpath((VALUE)reg_cfp->iseq, cd, CLASS_OF(recv));
@@ -4468,6 +4500,7 @@ vm_sendish(
val = vm_invokeblock_i(ec, GET_CFP(), &calling);
break;
}
+#endif
if (val != Qundef) {
return val; /* CFUNC normal return */