Project

General

Profile

Actions

Bug #20522

closed

YJIT can panic if shape transition in `gen_setinstancevariable` emits a performance warning

Added by byroot (Jean Boussier) 6 months ago. Updated 6 months ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.3.2 (2024-05-30 revision e5a195edf6) [arm64-darwin23]
[ruby-core:118170]

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).

Actions #2

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 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
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0