зеркало из https://github.com/github/ruby.git
Check for comptime fixnums in opt_and and opt_or
This commit is contained in:
Родитель
cb9bc13fcb
Коммит
f1b7568f5a
100
yjit_codegen.c
100
yjit_codegen.c
|
@ -2206,59 +2206,87 @@ gen_opt_aset(jitstate_t *jit, ctx_t *ctx)
|
||||||
static codegen_status_t
|
static codegen_status_t
|
||||||
gen_opt_and(jitstate_t* jit, ctx_t* ctx)
|
gen_opt_and(jitstate_t* jit, ctx_t* ctx)
|
||||||
{
|
{
|
||||||
// Create a size-exit to fall back to the interpreter
|
// Defer compilation so we can specialize on a runtime `self`
|
||||||
// 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_AND)) {
|
|
||||||
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 and destination 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);
|
||||||
|
|
||||||
// Do the bitwise and arg0 & arg1
|
if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_AND)) {
|
||||||
mov(cb, REG0, arg0);
|
return YJIT_CANT_COMPILE;
|
||||||
and(cb, REG0, arg1);
|
}
|
||||||
|
|
||||||
// Push the output on the stack
|
// Check that both operands are fixnums
|
||||||
x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
|
guard_two_fixnums(ctx, side_exit);
|
||||||
mov(cb, dst, REG0);
|
|
||||||
|
|
||||||
return YJIT_KEEP_COMPILING;
|
// Get the operands and destination from the stack
|
||||||
|
x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
|
||||||
|
x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
|
||||||
|
|
||||||
|
// Do the bitwise and arg0 & arg1
|
||||||
|
mov(cb, REG0, arg0);
|
||||||
|
and(cb, REG0, arg1);
|
||||||
|
|
||||||
|
// Push the output on the stack
|
||||||
|
x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
|
||||||
|
mov(cb, dst, REG0);
|
||||||
|
|
||||||
|
return YJIT_KEEP_COMPILING;
|
||||||
|
} else {
|
||||||
|
// Delegate to send, call the method on the recv
|
||||||
|
return gen_opt_send_without_block(jit, ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static codegen_status_t
|
static codegen_status_t
|
||||||
gen_opt_or(jitstate_t* jit, ctx_t* ctx)
|
gen_opt_or(jitstate_t* jit, ctx_t* ctx)
|
||||||
{
|
{
|
||||||
// Create a size-exit to fall back to the interpreter
|
// Defer compilation so we can specialize on a runtime `self`
|
||||||
// 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_OR)) {
|
|
||||||
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 and destination 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);
|
||||||
|
|
||||||
// Do the bitwise or arg0 | arg1
|
if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_OR)) {
|
||||||
mov(cb, REG0, arg0);
|
return YJIT_CANT_COMPILE;
|
||||||
or(cb, REG0, arg1);
|
}
|
||||||
|
|
||||||
// Push the output on the stack
|
// Check that both operands are fixnums
|
||||||
x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
|
guard_two_fixnums(ctx, side_exit);
|
||||||
mov(cb, dst, REG0);
|
|
||||||
|
|
||||||
return YJIT_KEEP_COMPILING;
|
// Get the operands and destination from the stack
|
||||||
|
x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
|
||||||
|
x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
|
||||||
|
|
||||||
|
// Do the bitwise or arg0 | arg1
|
||||||
|
mov(cb, REG0, arg0);
|
||||||
|
or(cb, REG0, arg1);
|
||||||
|
|
||||||
|
// Push the output on the stack
|
||||||
|
x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
|
||||||
|
mov(cb, dst, REG0);
|
||||||
|
|
||||||
|
return YJIT_KEEP_COMPILING;
|
||||||
|
} else {
|
||||||
|
// Delegate to send, call the method on the recv
|
||||||
|
return gen_opt_send_without_block(jit, ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static codegen_status_t
|
static codegen_status_t
|
||||||
|
|
Загрузка…
Ссылка в новой задаче