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

Also available in: Atom PDF

Like0
Like0Like0Like0Like0