Skip to content

Commit

Permalink
Merge pull request ruby#113 from jhawthorn/special_const_guards
Browse files Browse the repository at this point in the history
Support jit_guard_known_klass on Symbols, Integer, and Floats
  • Loading branch information
maximecb committed Jun 30, 2021
2 parents 3aa3411 + 2a8bb83 commit 8a245aa
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 7 deletions.
71 changes: 71 additions & 0 deletions bootstraptest/test_yjit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1295,3 +1295,74 @@ def foo = [:B, super]
ins.singleton_class.define_method(:bar, B.instance_method(:foo))
ins.bar
}

# Call to fixnum
assert_equal '[true, false]', %q{
def is_odd(obj)
obj.odd?
end
is_odd(1)
is_odd(1)
[is_odd(123), is_odd(456)]
}

# Call to bignum
assert_equal '[true, false]', %q{
def is_odd(obj)
obj.odd?
end
bignum = 99999999999999999999
is_odd(bignum)
is_odd(bignum)
[is_odd(bignum), is_odd(bignum+1)]
}

# Call to fixnum and bignum
assert_equal '[true, false, true, false]', %q{
def is_odd(obj)
obj.odd?
end
bignum = 99999999999999999999
is_odd(bignum)
is_odd(bignum)
is_odd(123)
is_odd(123)
[is_odd(123), is_odd(456), is_odd(bignum), is_odd(bignum+1)]
}

# Call to static and dynamic symbol
assert_equal 'bar', %q{
def to_string(obj)
obj.to_s
end
to_string(:foo)
to_string(:foo)
to_string((-"bar").to_sym)
to_string((-"bar").to_sym)
}

# Call to flonum and heap float
assert_equal '[nil, nil, nil, 1]', %q{
def is_inf(obj)
obj.infinite?
end
is_inf(0.0)
is_inf(0.0)
is_inf(1e256)
is_inf(1e256)
[
is_inf(0.0),
is_inf(1.0),
is_inf(1e256),
is_inf(1.0/0.0)
]
}
38 changes: 31 additions & 7 deletions yjit_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -2248,13 +2248,37 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t *ctx, VALUE known_klass, insn_opnd_
ctx_set_opnd_type(ctx, insn_opnd, TYPE_FALSE);
}
}
else if (known_klass == rb_cInteger ||
known_klass == rb_cSymbol ||
known_klass == rb_cFloat) {
// Can't guard for for these classes because they can have both
// immediate (special const) instances and instances on the heap. Can
// remove this by adding appropriate dynamic checks.
return false;
else if (known_klass == rb_cInteger && FIXNUM_P(sample_instance)) {
// We will guard fixnum and bignum as though they were separate classes
// BIGNUM can be handled by the general else case below
if (val_type.type != ETYPE_FIXNUM || !val_type.is_imm) {
ADD_COMMENT(cb, "guard object is fixnum");
test(cb, REG0, imm_opnd(RUBY_FIXNUM_FLAG));
jit_chain_guard(JCC_JZ, jit, ctx, max_chain_depth, side_exit);
ctx_set_opnd_type(ctx, insn_opnd, TYPE_FIXNUM);
}
}
else if (known_klass == rb_cSymbol && STATIC_SYM_P(sample_instance)) {
// We will guard STATIC vs DYNAMIC as though they were separate classes
// DYNAMIC symbols can be handled by the general else case below
if (val_type.type != ETYPE_SYMBOL || !val_type.is_imm) {
ADD_COMMENT(cb, "guard object is static symbol");
STATIC_ASSERT(special_shift_is_8, RUBY_SPECIAL_SHIFT == 8);
cmp(cb, REG0_8, imm_opnd(RUBY_SYMBOL_FLAG));
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
ctx_set_opnd_type(ctx, insn_opnd, TYPE_STATIC_SYMBOL);
}
}
else if (known_klass == rb_cFloat && FLONUM_P(sample_instance)) {
if (val_type.type != ETYPE_FLONUM || !val_type.is_imm) {
// We will guard flonum vs heap float as though they were separate classes
ADD_COMMENT(cb, "guard object is flonum");
mov(cb, REG1, REG0);
and(cb, REG1, imm_opnd(RUBY_FLONUM_MASK));
cmp(cb, REG1, imm_opnd(RUBY_FLONUM_FLAG));
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
ctx_set_opnd_type(ctx, insn_opnd, TYPE_FLONUM);
}
}
else if (FL_TEST(known_klass, FL_SINGLETON) && sample_instance == rb_attr_get(known_klass, id__attached__)) {
// Singleton classes are attached to one specific object, so we can
Expand Down
3 changes: 3 additions & 0 deletions yjit_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum yjit_type_enum
ETYPE_TRUE,
ETYPE_FALSE,
ETYPE_FIXNUM,
ETYPE_FLONUM,
ETYPE_ARRAY,
ETYPE_HASH,
ETYPE_SYMBOL,
Expand Down Expand Up @@ -69,6 +70,8 @@ STATIC_ASSERT(val_type_size, sizeof(val_type_t) == 1);
#define TYPE_TRUE ( (val_type_t){ .is_imm = 1, .type = ETYPE_TRUE } )
#define TYPE_FALSE ( (val_type_t){ .is_imm = 1, .type = ETYPE_FALSE } )
#define TYPE_FIXNUM ( (val_type_t){ .is_imm = 1, .type = ETYPE_FIXNUM } )
#define TYPE_FLONUM ( (val_type_t){ .is_imm = 1, .type = ETYPE_FLONUM } )
#define TYPE_STATIC_SYMBOL ( (val_type_t){ .is_imm = 1, .type = ETYPE_SYMBOL } )
#define TYPE_ARRAY ( (val_type_t){ .is_heap = 1, .type = ETYPE_ARRAY } )
#define TYPE_HASH ( (val_type_t){ .is_heap = 1, .type = ETYPE_HASH } )
#define TYPE_STRING ( (val_type_t){ .is_heap = 1, .type = ETYPE_STRING } )
Expand Down

0 comments on commit 8a245aa

Please sign in to comment.