Pop stack operands in opt_aref
This commit is contained in:
parent
a391684159
commit
0f53c216d2
@ -636,6 +636,78 @@ gen_opt_ge(jitstate_t* jit, ctx_t* ctx)
|
||||
return gen_fixnum_cmp(jit, ctx, cmovge);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Bail if the inline cache has been filled. Currently, certain types
|
||||
// (including arrays) don't use the inline cache, so if the inline cache
|
||||
// has an entry, then this must be used by some other type.
|
||||
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_pop(ctx, 1);
|
||||
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_pop(ctx, 1);
|
||||
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;
|
||||
}
|
||||
|
||||
static bool
|
||||
gen_opt_and(jitstate_t* jit, ctx_t* ctx)
|
||||
{
|
||||
@ -1192,7 +1264,7 @@ gen_opt_swb_iseq(jitstate_t* jit, ctx_t* ctx, struct rb_call_data * cd, const rb
|
||||
lea(cb, REG0, ctx_sp_opnd(ctx, sizeof(VALUE) * (3 + num_locals)));
|
||||
|
||||
// Initialize local variables to Qnil
|
||||
for (int i=0; i < num_locals; i++) {
|
||||
for (int i = 0; i < num_locals; i++) {
|
||||
mov(cb, mem_opnd(64, REG0, sizeof(VALUE) * (i - num_locals - 3)), imm_opnd(Qnil));
|
||||
}
|
||||
|
||||
@ -1390,6 +1462,7 @@ ujit_init_codegen(void)
|
||||
ujit_reg_op(BIN(opt_lt), gen_opt_lt, false);
|
||||
ujit_reg_op(BIN(opt_le), gen_opt_le, false);
|
||||
ujit_reg_op(BIN(opt_ge), gen_opt_ge, false);
|
||||
ujit_reg_op(BIN(opt_aref), gen_opt_aref, false);
|
||||
ujit_reg_op(BIN(opt_and), gen_opt_and, false);
|
||||
ujit_reg_op(BIN(opt_minus), gen_opt_minus, false);
|
||||
ujit_reg_op(BIN(opt_plus), gen_opt_plus, false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user