Skip to content

Commit

Permalink
Implement opt_aref
Browse files Browse the repository at this point in the history
This patch implements opt_aref, but only when the receiver is an array
and when the parameter is a single fixnum.  Any other types exit.
  • Loading branch information
tenderlove committed Feb 4, 2021
1 parent a73b9cd commit 0fc92a1
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions ujit_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,76 @@ gen_opt_plus(jitstate_t* jit, ctx_t* ctx)
return true;
}

static bool
gen_opt_aref(jitstate_t* jit, ctx_t* ctx)
{
struct rb_call_data * cd = (struct rb_call_data *)jit_get_arg(jit, 0);
int32_t argc = (int32_t)vm_ci_argc(cd->ci);

// Only JIT one arg calls like `ary[6]`
if (argc != 1) {
return false;
}

const rb_callable_method_entry_t *cme = vm_cc_cme(cd->cc);

if (cme) {
return false;
}

// Create a size-exit to fall back to the interpreter
uint8_t* side_exit = ujit_side_exit(jit, ctx);

x86opnd_t recv = ctx_stack_opnd(ctx, argc);

mov(cb, REG0, recv);

// if (SPECIAL_CONST_P(recv)) {
// Bail if it's not a heap object
test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK));
jnz_ptr(cb, side_exit);
cmp(cb, REG0, imm_opnd(Qfalse));
je_ptr(cb, side_exit);
cmp(cb, REG0, imm_opnd(Qnil));
je_ptr(cb, side_exit);

// Bail if recv is *not* an array
x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass));
mov(cb, REG0, klass_opnd);
mov(cb, REG1, const_ptr_opnd((void *)rb_cArray));
cmp(cb, REG0, REG1);
jne_ptr(cb, side_exit);

// Bail if arg0 is *not* an FIXNUM
x86opnd_t operand = ctx_stack_opnd(ctx, 0);
mov(cb, REG1, operand);
test(cb, REG1, imm_opnd(RUBY_FIXNUM_FLAG));
jz_ptr(cb, side_exit);

// Save MicroJIT registers
push(cb, REG_CFP);
push(cb, REG_EC);
push(cb, REG_SP);
// Maintain 16-byte RSP alignment
sub(cb, RSP, imm_opnd(8));

mov(cb, RDI, recv);
sar(cb, REG1, imm_opnd(1)); // Convert fixnum to int
mov(cb, RSI, REG1);
call_ptr(cb, REG0, (void *)rb_ary_entry_internal);

// Restore registers
add(cb, RSP, imm_opnd(8));
pop(cb, REG_SP);
pop(cb, REG_EC);
pop(cb, REG_CFP);

x86opnd_t stack_ret = ctx_stack_push(ctx, T_NONE);
mov(cb, stack_ret, RAX);

return true;
}

void
gen_branchif_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t shape)
{
Expand Down Expand Up @@ -1398,4 +1468,5 @@ ujit_init_codegen(void)
ujit_reg_op(BIN(jump), gen_jump, true);
ujit_reg_op(BIN(opt_send_without_block), gen_opt_send_without_block, true);
ujit_reg_op(BIN(leave), gen_leave, true);
ujit_reg_op(BIN(opt_aref), gen_opt_aref, false);
}

0 comments on commit 0fc92a1

Please sign in to comment.