summaryrefslogtreecommitdiff
path: root/yjit_codegen.c
diff options
context:
space:
mode:
authorJohn Hawthorn <[email protected]>2021-08-26 11:45:05 -0700
committerAlan Wu <[email protected]>2021-10-20 18:19:39 -0400
commit812597676ba2b1e3c41c50e9da624441e0c40a6b (patch)
tree42faa784fca02f8efab59803c89cc3c5847efc0e /yjit_codegen.c
parent54db64f7a59f1f14b280a80491336a128f792b42 (diff)
Avoid immediate side exits in checktype
Previously checktype only supported heap objects, however it's not uncommon to receive an immediate, for example when string interpolating a Symbol or Integer.
Diffstat (limited to 'yjit_codegen.c')
-rw-r--r--yjit_codegen.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/yjit_codegen.c b/yjit_codegen.c
index db0694523e..0e2bbf2fa3 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -1758,9 +1758,6 @@ gen_defined(jitstate_t* jit, ctx_t* ctx)
static codegen_status_t
gen_checktype(jitstate_t* jit, ctx_t* ctx)
{
- // TODO: could we specialize on the type we detect
- uint8_t* side_exit = yjit_side_exit(jit, ctx);
-
enum ruby_value_type type_val = (enum ruby_value_type)jit_get_arg(jit, 0);
// Only three types are emitted by compile.c
if (type_val == T_STRING || type_val == T_ARRAY || type_val == T_HASH) {
@@ -1785,16 +1782,17 @@ gen_checktype(jitstate_t* jit, ctx_t* ctx)
}
mov(cb, REG0, val);
+ mov(cb, REG1, imm_opnd(Qfalse));
+
+ uint32_t ret = cb_new_label(cb, "ret");
if (!val_type.is_heap) {
// if (SPECIAL_CONST_P(val)) {
- // Bail if receiver is not a heap object
+ // Return Qfalse via REG1 if not on heap
test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK));
- jnz_ptr(cb, side_exit);
- cmp(cb, REG0, imm_opnd(Qfalse));
- je_ptr(cb, side_exit);
+ jnz_label(cb, ret);
cmp(cb, REG0, imm_opnd(Qnil));
- je_ptr(cb, side_exit);
+ jbe_label(cb, ret);
}
// Check type on object
@@ -1802,11 +1800,13 @@ gen_checktype(jitstate_t* jit, ctx_t* ctx)
and(cb, REG0, imm_opnd(RUBY_T_MASK));
cmp(cb, REG0, imm_opnd(type_val));
mov(cb, REG0, imm_opnd(Qtrue));
- mov(cb, REG1, imm_opnd(Qfalse));
- cmovne(cb, REG0, REG1);
+ // REG1 contains Qfalse from above
+ cmove(cb, REG1, REG0);
+ cb_write_label(cb, ret);
stack_ret = ctx_stack_push(ctx, TYPE_IMM);
- mov(cb, stack_ret, REG0);
+ mov(cb, stack_ret, REG1);
+ cb_link_labels(cb);
return YJIT_KEEP_COMPILING;
} else {