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

Check for comptime fixnum in gen_fixnum_cmp

This commit is contained in:
John Hawthorn 2021-09-14 08:58:05 -07:00 committed by Alan Wu
parent f1b7568f5a
commit 7d99e85601

View file

@ -1880,33 +1880,46 @@ typedef void (*cmov_fn)(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
static codegen_status_t static codegen_status_t
gen_fixnum_cmp(jitstate_t* jit, ctx_t* ctx, cmov_fn cmov_op) gen_fixnum_cmp(jitstate_t* jit, ctx_t* ctx, cmov_fn cmov_op)
{ {
// Create a size-exit to fall back to the interpreter // Defer compilation so we can specialize base on a runtime receiver
// Note: we generate the side-exit before popping operands from the stack if (!jit_at_current_insn(jit)) {
uint8_t* side_exit = yjit_side_exit(jit, ctx); defer_compilation(jit->block, jit->insn_idx, ctx);
return YJIT_END_BLOCK;
if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_LT)) {
return YJIT_CANT_COMPILE;
} }
// Check that both operands are fixnums VALUE comptime_a = jit_peek_at_stack(jit, ctx, 1);
guard_two_fixnums(ctx, side_exit); VALUE comptime_b = jit_peek_at_stack(jit, ctx, 0);
// Get the operands from the stack if (FIXNUM_P(comptime_a) && FIXNUM_P(comptime_b)) {
x86opnd_t arg1 = ctx_stack_pop(ctx, 1); // Create a size-exit to fall back to the interpreter
x86opnd_t arg0 = ctx_stack_pop(ctx, 1); // Note: we generate the side-exit before popping operands from the stack
uint8_t* side_exit = yjit_side_exit(jit, ctx);
// Compare the arguments if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_LT)) {
xor(cb, REG0_32, REG0_32); // REG0 = Qfalse return YJIT_CANT_COMPILE;
mov(cb, REG1, arg0); }
cmp(cb, REG1, arg1);
mov(cb, REG1, imm_opnd(Qtrue));
cmov_op(cb, REG0, REG1);
// Push the output on the stack // Check that both operands are fixnums
x86opnd_t dst = ctx_stack_push(ctx, TYPE_UNKNOWN); guard_two_fixnums(ctx, side_exit);
mov(cb, dst, REG0);
return YJIT_KEEP_COMPILING; // Get the operands from the stack
x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
// Compare the arguments
xor(cb, REG0_32, REG0_32); // REG0 = Qfalse
mov(cb, REG1, arg0);
cmp(cb, REG1, arg1);
mov(cb, REG1, imm_opnd(Qtrue));
cmov_op(cb, REG0, REG1);
// Push the output on the stack
x86opnd_t dst = ctx_stack_push(ctx, TYPE_UNKNOWN);
mov(cb, dst, REG0);
return YJIT_KEEP_COMPILING;
} else {
return gen_opt_send_without_block(jit, ctx);
}
} }
static codegen_status_t static codegen_status_t