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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy