summaryrefslogtreecommitdiff
path: root/yjit_codegen.c
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2021-09-13 19:21:26 -0700
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:40 -0400
commitcb9bc13fcb2f78513338aa463aaf7544ebbfbfba (patch)
tree557d1ac12264b371f4f33591fc827ee91ff9fbad /yjit_codegen.c
parentfd10634b1abb3deeb50a1f09a41404af24cd25d7 (diff)
Check for comptime integers in opt_plus and opt_minus
Diffstat (limited to 'yjit_codegen.c')
-rw-r--r--yjit_codegen.c108
1 files changed, 68 insertions, 40 deletions
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 6bcf5c3fb5..b2cd49f69c 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -2264,63 +2264,91 @@ gen_opt_or(jitstate_t* jit, ctx_t* ctx)
static codegen_status_t
gen_opt_minus(jitstate_t* jit, ctx_t* ctx)
{
- // Create a size-exit to fall back to the interpreter
- // Note: we generate the side-exit before popping operands from the stack
- uint8_t* side_exit = yjit_side_exit(jit, ctx);
-
- if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_MINUS)) {
- return YJIT_CANT_COMPILE;
+ // Defer compilation so we can specialize on a runtime `self`
+ if (!jit_at_current_insn(jit)) {
+ defer_compilation(jit->block, jit->insn_idx, ctx);
+ return YJIT_END_BLOCK;
}
- // Check that both operands are fixnums
- guard_two_fixnums(ctx, side_exit);
+ VALUE comptime_a = jit_peek_at_stack(jit, ctx, 1);
+ VALUE comptime_b = jit_peek_at_stack(jit, ctx, 0);
- // Get the operands and destination from the stack
- x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
- x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
+ if (FIXNUM_P(comptime_a) && FIXNUM_P(comptime_b)) {
+ // Create a size-exit to fall back to the interpreter
+ // Note: we generate the side-exit before popping operands from the stack
+ uint8_t* side_exit = yjit_side_exit(jit, ctx);
- // Subtract arg0 - arg1 and test for overflow
- mov(cb, REG0, arg0);
- sub(cb, REG0, arg1);
- jo_ptr(cb, side_exit);
- add(cb, REG0, imm_opnd(1));
+ if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_MINUS)) {
+ return YJIT_CANT_COMPILE;
+ }
- // Push the output on the stack
- x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
- mov(cb, dst, REG0);
+ // Check that both operands are fixnums
+ guard_two_fixnums(ctx, side_exit);
- 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);
+
+ // Subtract arg0 - arg1 and test for overflow
+ mov(cb, REG0, arg0);
+ sub(cb, REG0, arg1);
+ jo_ptr(cb, side_exit);
+ add(cb, REG0, imm_opnd(1));
+
+ // 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
gen_opt_plus(jitstate_t* jit, ctx_t* ctx)
{
- // Create a size-exit to fall back to the interpreter
- // Note: we generate the side-exit before popping operands from the stack
- uint8_t* side_exit = yjit_side_exit(jit, ctx);
-
- if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_PLUS)) {
- return YJIT_CANT_COMPILE;
+ // Defer compilation so we can specialize on a runtime `self`
+ if (!jit_at_current_insn(jit)) {
+ defer_compilation(jit->block, jit->insn_idx, ctx);
+ return YJIT_END_BLOCK;
}
- // Check that both operands are fixnums
- guard_two_fixnums(ctx, side_exit);
+ VALUE comptime_a = jit_peek_at_stack(jit, ctx, 1);
+ VALUE comptime_b = jit_peek_at_stack(jit, ctx, 0);
- // Get the operands and destination from the stack
- x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
- x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
+ if (FIXNUM_P(comptime_a) && FIXNUM_P(comptime_b)) {
+ // Create a size-exit to fall back to the interpreter
+ // Note: we generate the side-exit before popping operands from the stack
+ uint8_t* side_exit = yjit_side_exit(jit, ctx);
- // Add arg0 + arg1 and test for overflow
- mov(cb, REG0, arg0);
- sub(cb, REG0, imm_opnd(1));
- add(cb, REG0, arg1);
- jo_ptr(cb, side_exit);
+ if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_PLUS)) {
+ return YJIT_CANT_COMPILE;
+ }
- // Push the output on the stack
- x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
- mov(cb, dst, REG0);
+ // Check that both operands are fixnums
+ guard_two_fixnums(ctx, side_exit);
- 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);
+
+ // Add arg0 + arg1 and test for overflow
+ mov(cb, REG0, arg0);
+ sub(cb, REG0, imm_opnd(1));
+ add(cb, REG0, arg1);
+ jo_ptr(cb, side_exit);
+
+ // 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