summaryrefslogtreecommitdiff
path: root/tool/ruby_vm/views/_mjit_compile_send.erb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/ruby_vm/views/_mjit_compile_send.erb')
-rw-r--r--tool/ruby_vm/views/_mjit_compile_send.erb53
1 files changed, 32 insertions, 21 deletions
diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb
index 0e033a4ebe..255648bc2d 100644
--- a/tool/ruby_vm/views/_mjit_compile_send.erb
+++ b/tool/ruby_vm/views/_mjit_compile_send.erb
@@ -15,15 +15,18 @@
% # compiler: Use captured cc to avoid race condition
const struct rb_callcache *captured_cc = captured_cc_entries(status)[call_data_index(cd, body)];
%
- const rb_iseq_t *iseq;
+% # compiler: Inline send insn where some supported fastpath is used.
+ const rb_iseq_t *iseq = NULL;
const CALL_INFO ci = cd->ci;
- if (!status->compile_info->disable_send_cache && has_valid_method_type(captured_cc)
- // CC_SET_FASTPATH in vm_callee_setup_arg
- && !(vm_ci_flag(ci) & VM_CALL_TAILCALL) // inlining non-tailcall path
- && vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_ISEQ
- && fastpath_applied_iseq_p(ci, captured_cc, iseq = def_iseq_ptr(vm_cc_cme(captured_cc)->def))) {
-
- int param_size = iseq->body->param.size;
+ if (!status->compile_info->disable_send_cache && has_valid_method_type(captured_cc) && (
+% # `CC_SET_FASTPATH(cc, vm_call_cfunc, TRUE)` in `vm_call_method_each_type`
+ vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC
+% # `CC_SET_FASTPATH(cc, vm_call_iseq_setup_func(...), vm_call_iseq_optimizable_p(...))` in `vm_callee_setup_arg`,
+% # and support only non-VM_CALL_TAILCALL path inside it
+ || (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_ISEQ
+ && fastpath_applied_iseq_p(ci, captured_cc, iseq = def_iseq_ptr(vm_cc_cme(captured_cc)->def))
+ && !(vm_ci_flag(ci) & VM_CALL_TAILCALL))
+ )) {
int sp_inc = (int)sp_inc_of_sendish(ci);
fprintf(f, "{\n");
@@ -40,7 +43,7 @@
<%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%>
% # JIT: If ISeq is inlinable, call the inlined method without pushing a frame.
- if (status->inlined_iseqs != NULL && status->inlined_iseqs[pos] == iseq->body) {
+ if (iseq && status->inlined_iseqs != NULL && iseq->body == status->inlined_iseqs[pos]) {
fprintf(f, " {\n");
fprintf(f, " VALUE orig_self = reg_cfp->self;\n");
fprintf(f, " reg_cfp->self = stack[%d];\n", b->stack_size + sp_inc - 1);
@@ -49,7 +52,7 @@
fprintf(f, " }\n");
}
else {
-% # JIT: Forked `vm_sendish` to inline various things
+% # JIT: Forked `vm_sendish` (except method_explorer = vm_search_method_wrap) to inline various things
fprintf(f, " {\n");
fprintf(f, " VALUE val;\n");
fprintf(f, " struct rb_calling_info calling;\n");
@@ -58,20 +61,28 @@
% else
fprintf(f, " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n");
% end
- fprintf(f, " calling.argc = %d;\n", vm_ci_argc(ci));
+ fprintf(f, " calling.kw_splat = %d;\n", IS_ARGS_KW_SPLAT(ci) > 0);
fprintf(f, " calling.recv = stack[%d];\n", b->stack_size + sp_inc - 1);
+ fprintf(f, " calling.argc = %d;\n", vm_ci_argc(ci));
-% # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
- fprintf(f, " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, cc_cme, 0, %d, %d);\n", param_size, iseq->body->local_table_size);
- if (iseq->body->catch_except_p) {
- fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n");
- fprintf(f, " val = vm_exec(ec, TRUE);\n");
+ if (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC) {
+% # TODO: optimize this more
+ fprintf(f, " CALL_DATA cd = (CALL_DATA)0x%"PRIxVALUE";\n", operands[0]);
+ fprintf(f, " val = vm_call_cfunc(ec, reg_cfp, &calling, cd);\n");
}
- else {
- fprintf(f, " if ((val = mjit_exec(ec)) == Qundef) {\n");
- fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n"); // This is vm_call0_body's code after vm_call_iseq_setup
- fprintf(f, " val = vm_exec(ec, FALSE);\n");
- fprintf(f, " }\n");
+ else { // VM_METHOD_TYPE_ISEQ
+% # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
+ fprintf(f, " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, cc_cme, 0, %d, %d);\n", iseq->body->param.size, iseq->body->local_table_size);
+ if (iseq->body->catch_except_p) {
+ fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n");
+ fprintf(f, " val = vm_exec(ec, TRUE);\n");
+ }
+ else {
+ fprintf(f, " if ((val = mjit_exec(ec)) == Qundef) {\n");
+ fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n"); // This is vm_call0_body's code after vm_call_iseq_setup
+ fprintf(f, " val = vm_exec(ec, FALSE);\n");
+ fprintf(f, " }\n");
+ }
}
fprintf(f, " stack[%d] = val;\n", b->stack_size + sp_inc - 1);
fprintf(f, " }\n");