8000 Merge pull request #91 from jhawthorn/singleton_typecheck · eileencodes/ruby@6698e43 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6698e43

Browse files
authored
Merge pull request ruby#91 from jhawthorn/singleton_typecheck
Simplify known class check for singleton classes
2 parents f3bb506 + 455a51f commit 6698e43

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

bootstraptest/test_yjit.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,3 +1153,34 @@ def foo(foo, bar)
11531153
foo(5,2)
11541154
foo(5,2)
11551155
}
1156+
1157+
# Call to object with singleton
1158+
assert_equal '123', %q{
1159+
obj = Object.new
1160+
def obj.foo
1161+
123
1162+
end
1163+
1164+
def foo(obj)
1165+
obj.foo()
1166+
end
1167+
1168+
foo(obj)
1169+
foo(obj)
1170+
}
1171+
1172+
# Call to singleton class
1173+
assert_equal '123', %q{
1174+
class Foo
1175+
def self.foo
1176+
123
1177+
end
1178+
end
1179+
1180+
def foo(obj)
1181+
obj.foo()
1182+
end
1183+
1184+
foo(Foo)
1185+
foo(Foo)
1186+
}

yjit_codegen.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,7 @@ static bool
21702170
jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_t insn_opnd, const int max_chain_depth, uint8_t *side_exit)
21712171
{
21722172
val_type_t val_type = ctx_get_opnd_type(ctx, insn_opnd);
2173+
bool singleton_klass = FL_TEST(known_klass, FL_SINGLETON);
21732174

21742175
if (known_klass == rb_cNilClass) {
21752176
if (val_type.type != ETYPE_NIL) {
@@ -2188,7 +2189,6 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_
21882189

21892190
ctx_set_opnd_type(ctx, insn_opnd, TYPE_TRUE);
21902191
}
2191-
21922192
}
21932193
else if (known_klass == rb_cFalseClass) {
21942194
if (val_type.type != ETYPE_FALSE) {
@@ -2200,15 +2200,26 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_
22002200
ctx_set_opnd_type(ctx, insn_opnd, TYPE_FALSE);
22012201
}
22022202
}
2203-
else {
2204-
// Can't guard for for these classes because some of they are sometimes immediate (special const).
2205-
// Can remove this by adding appropriate dynamic checks.
2206-
if (known_klass == rb_cInteger ||
2203+
else if (known_klass == rb_cInteger ||
22072204
known_klass == rb_cSymbol ||
22082205
known_klass == rb_cFloat) {
2209-
return false;
2210-
}
2211-
2206+
// Can't guard for for these classes because some of they are sometimes
2207+
// immediate (special const). Can remove this by adding appropriate
2208+
// dynamic checks.
2209+
return false;
2210+
}
2211+
else if (singleton_klass) {
2212+
// Singleton classes are attached to one specific object, so we can
2213+
// avoid one memory access (and potentially the is_heap check) by
2214+
// looking for the expected object directly.
2215+
ADD_COMMENT(cb, "guard known object with singleton class");
2216+
VALUE known_obj = rb_attr_get(known_klass, id__attached__);
2217+
// TODO: jit_mov_gc_ptr keeps a strong reference, which leaks the object.
2218+
jit_mov_gc_ptr(jit, cb, REG1, known_obj);
2219+
cmp(cb, REG0, REG1);
2220+
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
2221+
}
2222+
else {
22122223
// Check that the receiver is a heap object
22132224
// Note: if we get here, the class doesn't have immediate instances.
22142225
if (!val_type.is_heap) {
@@ -2232,7 +2243,6 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_
22322243
jit_chain_guard(JCC_JNE, jit, ctx, max_chain_depth, side_exit);
22332244
}
22342245

2235-
// Pointer to the klass field of the receiver &(recv->klass)
22362246
return true;
22372247
}
22382248

0 commit comments

Comments
 (0)
0