diff --git a/insns.def b/insns.def index d06368466e..3b65942e5a 100644 --- a/insns.def +++ b/insns.def @@ -693,7 +693,7 @@ defineclass class_iseq->body->iseq_encoded, GET_SP(), class_iseq->body->local_table_size, class_iseq->body->stack_max); - EXEC_EC_CFP(); + EXEC_EC_CFP(TRUE); } /**********************************************************/ @@ -820,7 +820,7 @@ invokeblock val = vm_invoke_block(ec, GET_CFP(), &calling, ci, block_handler); if (val == Qundef) { - EXEC_EC_CFP(); + EXEC_EC_CFP(TRUE); } } @@ -1344,7 +1344,7 @@ opt_call_c_function THROW_EXCEPTION(err); } - EXEC_EC_CFP(); + EXEC_EC_CFP(TRUE); } /* BLT */ diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb index fc84813c5a..8df74a9d83 100644 --- a/tool/ruby_vm/views/_mjit_compile_send.erb +++ b/tool/ruby_vm/views/_mjit_compile_send.erb @@ -54,7 +54,7 @@ (VALUE)iseq, (VALUE)cc->me, (VALUE)iseq->body->iseq_encoded, param_size, iseq->body->local_table_size - param_size, iseq->body->stack_max); fprintf(f, " if ((v = 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, " v = vm_exec(ec);\n"); + fprintf(f, " v = vm_exec(ec, FALSE);\n"); fprintf(f, " }\n"); fprintf(f, " stack[%d] = v;\n", b->stack_size - argc - 1); fprintf(f, " }\n"); diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb index a23537e4bc..b6788a6593 100644 --- a/tool/ruby_vm/views/mjit_compile.inc.erb +++ b/tool/ruby_vm/views/mjit_compile.inc.erb @@ -37,7 +37,7 @@ % # PUSH(): refers to `SET_SV()`, `INC_SP()` % # GET_SELF(): refers to `reg_cfp->self` % # GET_LEP(): refers to `VM_EP_LEP(reg_cfp->ep)` -% # EXEC_EC_CFP(): refers to `val = vm_exec(ec)` with frame setup +% # EXEC_EC_CFP(): refers to `val = vm_exec(ec, TRUE)` with frame setup % # CALL_METHOD(): using `GET_CFP()` and `EXEC_EC_CFP()` % # TOPN(): refers to `reg_cfp->sp`, which needs to have correct sp (of course) % # STACK_ADDR_FROM_TOP(): refers to `reg_cfp->sp`, same problem here diff --git a/vm.c b/vm.c index 9f2ac05691..7a189206d7 100644 --- a/vm.c +++ b/vm.c @@ -1006,7 +1006,7 @@ invoke_block(rb_execution_context_t *ec, const rb_iseq_t *iseq, VALUE self, cons ec->cfp->sp + arg_size, iseq->body->local_table_size - arg_size, iseq->body->stack_max); - return vm_exec(ec); + return vm_exec(ec, TRUE); } static VALUE @@ -1027,7 +1027,7 @@ invoke_bmethod(rb_execution_context_t *ec, const rb_iseq_t *iseq, VALUE self, co RUBY_DTRACE_METHOD_ENTRY_HOOK(ec, me->owner, me->def->original_id); EXEC_EVENT_HOOK(ec, RUBY_EVENT_CALL, self, me->def->original_id, me->called_id, me->owner, Qnil); VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH); - ret = vm_exec(ec); + ret = vm_exec(ec, TRUE); EXEC_EVENT_HOOK(ec, RUBY_EVENT_RETURN, self, me->def->original_id, me->called_id, me->owner, ret); RUBY_DTRACE_METHOD_RETURN_HOOK(ec, me->owner, me->def->original_id); return ret; @@ -1788,13 +1788,16 @@ hook_before_rewind(rb_execution_context_t *ec, const rb_control_frame_t *cfp, in VALUE *ep; // ep void *code; // }; + + If mjit_exec is already called before calling vm_exec, `mjit_enable_p` should + be FALSE to avoid calling `mjit_exec` twice. */ MJIT_FUNC_EXPORTED VALUE -vm_exec(rb_execution_context_t *ec) +vm_exec(rb_execution_context_t *ec, int mjit_enable_p) { enum ruby_tag_type state; - VALUE result; + VALUE result = Qundef; VALUE initial = 0; struct vm_throw_data *err; @@ -1802,7 +1805,8 @@ vm_exec(rb_execution_context_t *ec) _tag.retval = Qnil; if ((state = EC_EXEC_TAG()) == TAG_NONE) { - result = mjit_exec(ec); + if (mjit_enable_p) + result = mjit_exec(ec); vm_loop_start: if (result == Qundef) result = vm_exec_core(ec, initial); @@ -2047,7 +2051,7 @@ rb_iseq_eval(const rb_iseq_t *iseq) rb_execution_context_t *ec = GET_EC(); VALUE val; vm_set_top_stack(ec, iseq); - val = vm_exec(ec); + val = vm_exec(ec, TRUE); return val; } @@ -2058,7 +2062,7 @@ rb_iseq_eval_main(const rb_iseq_t *iseq) VALUE val; vm_set_main_stack(ec, iseq); - val = vm_exec(ec); + val = vm_exec(ec, TRUE); return val; } diff --git a/vm_eval.c b/vm_eval.c index ba75fbbda7..2fb339c662 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -20,7 +20,7 @@ static inline VALUE vm_yield_with_cref(rb_execution_context_t *ec, int argc, con static inline VALUE vm_yield(rb_execution_context_t *ec, int argc, const VALUE *argv); static inline VALUE vm_yield_with_block(rb_execution_context_t *ec, int argc, const VALUE *argv, VALUE block_handler); static inline VALUE vm_yield_force_blockarg(rb_execution_context_t *ec, VALUE args); -VALUE vm_exec(rb_execution_context_t *ec); +VALUE vm_exec(rb_execution_context_t *ec, int mjit_enable_p); static void vm_set_eval_stack(rb_execution_context_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, const struct rb_block *base_block); static int vm_collect_local_variables_in_heap(const VALUE *dfp, const struct local_var_list *vars); @@ -126,7 +126,7 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const vm_call_iseq_setup(ec, reg_cfp, calling, ci, cc); VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH); - return vm_exec(ec); /* CHECK_INTS in this function */ + return vm_exec(ec, TRUE); /* CHECK_INTS in this function */ } case VM_METHOD_TYPE_NOTIMPLEMENTED: case VM_METHOD_TYPE_CFUNC: @@ -1327,7 +1327,7 @@ eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int li vm_set_eval_stack(ec, iseq, cref, &block); /* kick */ - return vm_exec(ec); + return vm_exec(ec, TRUE); } static VALUE @@ -1348,7 +1348,7 @@ eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line) } /* kick */ - return vm_exec(ec); + return vm_exec(ec, TRUE); } /* diff --git a/vm_exec.h b/vm_exec.h index 76bdea18ad..beccdc9623 100644 --- a/vm_exec.h +++ b/vm_exec.h @@ -168,12 +168,12 @@ default: \ #endif #ifdef MJIT_HEADER -#define EXEC_EC_CFP() do { \ +#define EXEC_EC_CFP(mjit_enable_p) do { \ VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH); \ - val = vm_exec(ec); \ + val = vm_exec(ec, mjit_enable_p); \ } while (0) #else -#define EXEC_EC_CFP() do { \ +#define EXEC_EC_CFP(mjit_enable_p) do { \ RESTORE_REGS(); \ NEXT_INSN(); \ } while (0) diff --git a/vm_insnhelper.h b/vm_insnhelper.h index aca7a779d0..1aab231498 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -130,7 +130,7 @@ enum vm_regan_acttype { #define CALL_METHOD(calling, ci, cc) do { \ VALUE v = (*(cc)->call)(ec, GET_CFP(), (calling), (ci), (cc)); \ if (v == Qundef && (v = mjit_exec(ec)) == Qundef) { \ - EXEC_EC_CFP(); \ + EXEC_EC_CFP(FALSE); \ } \ else { \ val = v; \