1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Fixed two issues with MicroJIT CFUNC calls

This commit is contained in:
Maxime Chevalier-Boisvert 2020-10-20 16:55:49 -04:00 committed by Alan Wu
parent 35c0768473
commit 37e4350e80

View file

@ -611,13 +611,6 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
print_str(cb, "calling CFUNC:"); print_str(cb, "calling CFUNC:");
print_str(cb, rb_id2name(mid)); print_str(cb, rb_id2name(mid));
// Allocate a new CFP (ec->cfp--)
sub(
cb,
member_opnd(REG_EC, rb_execution_context_t, cfp),
imm_opnd(sizeof(rb_control_frame_t))
);
// Increment the stack pointer by 3 (in the callee) // Increment the stack pointer by 3 (in the callee)
// sp += 3 // sp += 3
lea(cb, REG0, ctx_sp_opnd(ctx)); lea(cb, REG0, ctx_sp_opnd(ctx));
@ -625,23 +618,30 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
// TODO // TODO
/* /*
// Write method entry at sp[-2] // Write method entry at sp[-3]
// sp[-2] = me; // sp[-2] = me;
mov(cb, REG1, const_ptr_opnd(cd)); mov(cb, REG1, const_ptr_opnd(cd));
x86opnd_t ptr_to_cc = member_opnd(REG1, struct rb_call_data, cc); x86opnd_t ptr_to_cc = member_opnd(REG1, struct rb_call_data, cc);
mov(cb, REG1, ptr_to_cc); mov(cb, REG1, ptr_to_cc);
x86opnd_t ptr_to_cme_ = mem_opnd(64, REG1, offsetof(struct rb_callcache, cme_)); x86opnd_t ptr_to_cme_ = mem_opnd(64, REG1, offsetof(struct rb_callcache, cme_));
mov(cb, mem_opnd(64, REG0, 8 * -2), ptr_to_cme_); mov(cb, mem_opnd(64, REG0, 8 * -3), ptr_to_cme_);
*/ */
// Write block handler at sp[-1] // Write block handler at sp[-2]
// sp[-1] = block_handler; // sp[-1] = block_handler;
mov(cb, mem_opnd(64, REG0, 8 * -1), imm_opnd(VM_BLOCK_HANDLER_NONE)); mov(cb, mem_opnd(64, REG0, 8 * -2), imm_opnd(VM_BLOCK_HANDLER_NONE));
// Write env flags at sp[0] // Write env flags at sp[-1]
// sp[0] = frame_type; // sp[0] = frame_type;
uint64_t frame_type = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL; uint64_t frame_type = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
mov(cb, mem_opnd(64, REG0, 0), imm_opnd(frame_type)); mov(cb, mem_opnd(64, REG0, 8 * -1), imm_opnd(frame_type));
// Allocate a new CFP (ec->cfp--)
sub(
cb,
member_opnd(REG_EC, rb_execution_context_t, cfp),
imm_opnd(sizeof(rb_control_frame_t))
);
// Setup the new frame // Setup the new frame
// *cfp = (const struct rb_control_frame_struct) { // *cfp = (const struct rb_control_frame_struct) {
@ -653,7 +653,7 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
// .block_code = 0, // .block_code = 0,
// .__bp__ = sp, // .__bp__ = sp,
// }; // };
lea(cb, REG1, member_opnd(REG_EC, rb_execution_context_t, cfp)); mov(cb, REG1, member_opnd(REG_EC, rb_execution_context_t, cfp));
mov(cb, member_opnd(REG1, rb_control_frame_t, pc), imm_opnd(0)); mov(cb, member_opnd(REG1, rb_control_frame_t, pc), imm_opnd(0));
mov(cb, member_opnd(REG1, rb_control_frame_t, sp), REG0); mov(cb, member_opnd(REG1, rb_control_frame_t, sp), REG0);
mov(cb, member_opnd(REG1, rb_control_frame_t, iseq), imm_opnd(0)); mov(cb, member_opnd(REG1, rb_control_frame_t, iseq), imm_opnd(0));
@ -671,7 +671,7 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
// Maintain 16-byte RSP alignment // Maintain 16-byte RSP alignment
if (argc % 2 == 0) if (argc % 2 == 0)
push(cb, RAX); sub(cb, RSP, imm_opnd(8));
// Copy SP into RAX because REG_SP will get overwritten // Copy SP into RAX because REG_SP will get overwritten
lea(cb, RAX, ctx_sp_opnd(ctx)); lea(cb, RAX, ctx_sp_opnd(ctx));
@ -680,7 +680,7 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
for (int32_t i = argc; i >= 0; --i) for (int32_t i = argc; i >= 0; --i)
{ {
// Recv is at index argc // Recv is at index argc
x86opnd_t stack_opnd = mem_opnd(64, RAX, (i+1) * 8); x86opnd_t stack_opnd = mem_opnd(64, RAX, -(i+1) * 8);
x86opnd_t c_arg_reg = C_ARG_REGS[i]; x86opnd_t c_arg_reg = C_ARG_REGS[i];
mov(cb, c_arg_reg, stack_opnd); mov(cb, c_arg_reg, stack_opnd);
} }
@ -697,19 +697,19 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx)
print_str(cb, "after C call"); print_str(cb, "after C call");
// Push the return value on the Ruby stack
x86opnd_t stack_ret = ctx_stack_push(ctx, 1);
mov(cb, stack_ret, RAX);
// Maintain 16-byte RSP alignment // Maintain 16-byte RSP alignment
if (argc % 2 == 0) if (argc % 2 == 0)
pop(cb, RAX); add(cb, RSP, imm_opnd(8));
// Restore MicroJIT registers // Restore MicroJIT registers
pop(cb, REG_SP); pop(cb, REG_SP);
pop(cb, REG_EC); pop(cb, REG_EC);
pop(cb, REG_CFP); pop(cb, REG_CFP);
// Push the return value on the Ruby stack
x86opnd_t stack_ret = ctx_stack_push(ctx, 1);
mov(cb, stack_ret, RAX);
// TODO: later // TODO: later
// RUBY_VM_CHECK_INTS(ec); // RUBY_VM_CHECK_INTS(ec);