Bug #20522
closedYJIT can panic if shape transition in `gen_setinstancevariable` emits a performance warning
Description
Reproduction script:
Warning[:performance] = true
module StrictWarnings
def warn(msg, category: nil, **)
raise msg
end
end
Warning.singleton_class.prepend(StrictWarnings)
class A
def compiled_method(is_private)
@some_ivar = is_private
end
end
100.times do |i|
klass = Class.new(A)
7.times do |j|
obj = klass.new
obj.instance_variable_set("@base_#{i}", 42)
obj.instance_variable_set("@ivar_#{j}", 42)
end
obj = klass.new
obj.instance_variable_set("@base_#{i}", 42)
begin
obj.compiled_method(true)
rescue
end
end
Context¶
compiled_method
contains a setinstancevariable
instruction, which when compiled by YJIT eagerly create the next shape if it doesn't already exist.
If Warning.warn
is redefined, then Ruby code may be invoked while YJIT is compiling, which is unsafe.
Solution¶
Performance warnings are best effort, so the simplest solution is to not emit warnings when YJIT is compiling. (patch incoming).
Updated by byroot (Jean Boussier) 6 months ago
Updated by byroot (Jean Boussier) 6 months ago
- Status changed from Open to Closed
Applied in changeset git|f7b53a75b648e7156f49c1d5c266e2d85f159fc6.
Do not emit shape transition warnings when YJIT is compiling
[Bug #20522]
If Warning.warn
is redefined in Ruby, emitting a warning would invoke
Ruby code, which can't safely be done when YJIT is compiling.
Updated by byroot (Jean Boussier) 6 months ago
3.3 backport PR: https://github.com/ruby/ruby/pull/10911
Updated by k0kubun (Takashi Kokubun) 6 months ago
- Backport changed from 3.1: DONTNEED, 3.2: DONTNEED, 3.3: REQUIRED to 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONE
ruby_3_3 4f00d98b327e3aa23564aa765488d15bc60c9e79.