From b5c039125fe375f91b9795a5e1b29febaa12d072 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Wed, 5 Jan 2022 00:47:10 -0800 Subject: [PATCH] YJIT: Save SP later in cfunc call Saving SP later allows us to avoid storing SP in an intermediate register and allows using the ctx_stack_opnd helpers. --- yjit_codegen.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/yjit_codegen.c b/yjit_codegen.c index 25fcfca083..c9a4404550 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -3383,23 +3383,13 @@ gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const call_ptr(cb, REG0, (void *)&check_cfunc_dispatch); } - // Copy SP into RAX because REG_SP will get overwritten - lea(cb, RAX, ctx_sp_opnd(ctx, 0)); - - // Pop the C function arguments from the stack (in the caller) - ctx_stack_pop(ctx, argc + 1); - - // Write interpreter SP into CFP. - // Needed in case the callee yields to the block. - jit_save_sp(jit, ctx); - // Non-variadic method if (cfunc->argc >= 0) { // Copy the arguments from the stack to the C argument registers // self is the 0th argument and is at index argc from the stack top for (int32_t i = 0; i < argc + 1; ++i) { - x86opnd_t stack_opnd = mem_opnd(64, RAX, -(argc + 1 - i) * SIZEOF_VALUE); + x86opnd_t stack_opnd = ctx_stack_opnd(ctx, argc - i); x86opnd_t c_arg_reg = C_ARG_REGS[i]; mov(cb, c_arg_reg, stack_opnd); } @@ -3409,10 +3399,17 @@ gen_send_cfunc(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const // The method gets a pointer to the first argument // rb_f_puts(int argc, VALUE *argv, VALUE recv) mov(cb, C_ARG_REGS[0], imm_opnd(argc)); - lea(cb, C_ARG_REGS[1], mem_opnd(64, RAX, -(argc) * SIZEOF_VALUE)); - mov(cb, C_ARG_REGS[2], mem_opnd(64, RAX, -(argc + 1) * SIZEOF_VALUE)); + lea(cb, C_ARG_REGS[1], ctx_stack_opnd(ctx, argc - 1)); + mov(cb, C_ARG_REGS[2], ctx_stack_opnd(ctx, argc)); } + // Pop the C function arguments from the stack (in the caller) + ctx_stack_pop(ctx, argc + 1); + + // Write interpreter SP into CFP. + // Needed in case the callee yields to the block. + jit_save_sp(jit, ctx); + // Call the C function // VALUE ret = (cfunc->func)(recv, argv[0], argv[1]); // cfunc comes from compile-time cme->def, which we assume to be stable.