Skip to content
  • 卜部昌平's avatar
    eb92159d
    Revert https://github.com/ruby/ruby/pull/2486 · eb92159d
    卜部昌平 authored
    This reverts commits: 10d6a3ac 8ba48c1b fba8627d dd883de5
    6c6a25fe 167e6b48 7cb96d41 32079792 595b3c4f 1521f7cf
    c11c5e69 cf336082 3632a812 f56506be 86427a32 .
    
    The reason for the revert is that we observe ABA problem around
    inline method cache.  When a cache misshits, we search for a
    method entry.  And if the entry is identical to what was cached
    before, we reuse the cache.  But the commits we are reverting here
    introduced situations where a method entry is freed, then the
    identical memory region is used for another method entry.  An
    inline method cache cannot detect that ABA.
    
    Here is a code that reproduce such situation:
    
    ```ruby
    require 'prime'
    
    class << Integer
      alias org_sqrt sqrt
      def sqrt(n)
        raise
      end
    
      GC.stress = true
      Prime.each(7*37){} rescue nil # <- Here we populate CC
      class << Object.new; end
    
      # These adjacent remove-then-alias maneuver
      # frees a method entry, then immediately
      # reuses it for another.
      remove_method :sqrt
      alias sqrt org_sqrt
    end
    
    Prime.each(7*37).to_a # <- SEGV
    ```
    eb92159d
    Revert https://github.com/ruby/ruby/pull/2486
    卜部昌平 authored
    This reverts commits: 10d6a3ac 8ba48c1b fba8627d dd883de5
    6c6a25fe 167e6b48 7cb96d41 32079792 595b3c4f 1521f7cf
    c11c5e69 cf336082 3632a812 f56506be 86427a32 .
    
    The reason for the revert is that we observe ABA problem around
    inline method cache.  When a cache misshits, we search for a
    method entry.  And if the entry is identical to what was cached
    before, we reuse the cache.  But the commits we are reverting here
    introduced situations where a method entry is freed, then the
    identical memory region is used for another method entry.  An
    inline method cache cannot detect that ABA.
    
    Here is a code that reproduce such situation:
    
    ```ruby
    require 'prime'
    
    class << Integer
      alias org_sqrt sqrt
      def sqrt(n)
        raise
      end
    
      GC.stress = true
      Prime.each(7*37){} rescue nil # <- Here we populate CC
      class << Object.new; end
    
      # These adjacent remove-then-alias maneuver
      # frees a method entry, then immediately
      # reuses it for another.
      remove_method :sqrt
      alias sqrt org_sqrt
    end
    
    Prime.each(7*37).to_a # <- SEGV
    ```
Loading