зеркало из https://github.com/github/ruby.git
YJIT: Avoid identity-based known-class guards for IO objects (#7911)
`IO#reopen` is very special in that it is able to change the class and singleton class of IO instances. In its presence, it is not correct to assume that IO instances has a stable class/singleton class and guard by comparing identity.
This commit is contained in:
Родитель
7577c101ed
Коммит
2b54c135ff
|
@ -1277,6 +1277,18 @@ class TestYJIT < Test::Unit::TestCase
|
|||
RUBY
|
||||
end
|
||||
|
||||
def test_io_reopen_clobbering_singleton_class
|
||||
assert_compiles(<<~RUBY, result: [:ok, :ok])
|
||||
def $stderr.to_i = :i
|
||||
|
||||
def test = $stderr.to_i
|
||||
|
||||
[test, test]
|
||||
$stderr.reopen($stderr.dup)
|
||||
[test, test].map { :ok unless _1 == :i }
|
||||
RUBY
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def code_gc_helpers
|
||||
|
|
|
@ -165,6 +165,7 @@ fn main() {
|
|||
.allowlist_var("rb_cTrueClass")
|
||||
.allowlist_var("rb_cFalseClass")
|
||||
.allowlist_var("rb_cInteger")
|
||||
.allowlist_var("rb_cIO")
|
||||
.allowlist_var("rb_cSymbol")
|
||||
.allowlist_var("rb_cFloat")
|
||||
.allowlist_var("rb_cString")
|
||||
|
|
|
@ -3871,6 +3871,7 @@ fn jit_guard_known_klass(
|
|||
} else if unsafe {
|
||||
FL_TEST(known_klass, VALUE(RUBY_FL_SINGLETON as usize)) != VALUE(0)
|
||||
&& sample_instance == rb_class_attached_object(known_klass)
|
||||
&& !rb_obj_is_kind_of(sample_instance, rb_cIO).test()
|
||||
} {
|
||||
// Singleton classes are attached to one specific object, so we can
|
||||
// avoid one memory access (and potentially the is_heap check) by
|
||||
|
@ -3882,6 +3883,8 @@ fn jit_guard_known_klass(
|
|||
// that its singleton class is empty, so we can't avoid the memory
|
||||
// access. As an example, `Object.new.singleton_class` is an object in
|
||||
// this situation.
|
||||
// Also, guarding by identity is incorrect for IO objects because
|
||||
// IO#reopen can be used to change the class and singleton class of IO objects!
|
||||
asm.comment("guard known object with singleton class");
|
||||
asm.cmp(obj_opnd, sample_instance.into());
|
||||
jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter);
|
||||
|
|
|
@ -1083,6 +1083,7 @@ extern "C" {
|
|||
pub static mut rb_cFalseClass: VALUE;
|
||||
pub static mut rb_cFloat: VALUE;
|
||||
pub static mut rb_cHash: VALUE;
|
||||
pub static mut rb_cIO: VALUE;
|
||||
pub static mut rb_cInteger: VALUE;
|
||||
pub static mut rb_cModule: VALUE;
|
||||
pub static mut rb_cNilClass: VALUE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче