<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/method.h, branch v3_3_11</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Remove written-but-never-read `me-&gt;def.body.refined.owner`</title>
<updated>2023-11-29T01:41:40+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2023-11-29T01:41:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=fcabe2df39b892458cb1f67437852c4acbb245a6'/>
<id>fcabe2df39b892458cb1f67437852c4acbb245a6</id>
<content type='text'>
This also removes aliasing rule violations; the anonymous structs were
distinct types from `rb_method_refined_t`.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This also removes aliasing rule violations; the anonymous structs were
distinct types from `rb_method_refined_t`.</pre>
</div>
</content>
</entry>
<entry>
<title>Try to fix compilation on m68k</title>
<updated>2023-09-22T20:14:09+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2023-09-22T20:14:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2ceb5363f9b15cffd3901220463a1175a32b89f7'/>
<id>2ceb5363f9b15cffd3901220463a1175a32b89f7</id>
<content type='text'>
Compilation is failing on m68k-linux with:

```
./include/ruby/internal/static_assert.h:51:46: error: static assertion failed: "sizeof_method_def: offsetof(rb_method_definition_t, body)==8"
   51 | # define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
      |                                              ^~~~~~~~~~~~~~
./include/ruby/internal/static_assert.h:70:5: note: in expansion of macro 'RBIMPL_STATIC_ASSERT0'
   70 |     RBIMPL_STATIC_ASSERT0(expr, # name ": " # expr)
      |     ^~~~~~~~~~~~~~~~~~~~~
./internal/static_assert.h:13:24: note: in expansion of macro 'RBIMPL_STATIC_ASSERT'
   13 | # define STATIC_ASSERT RBIMPL_STATIC_ASSERT
      |                        ^~~~~~~~~~~~~~~~~~~~
./method.h:203:1: note: in expansion of macro 'STATIC_ASSERT'
  203 | STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body)==8);
      | ^~~~~~~~~~~~~
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Compilation is failing on m68k-linux with:

```
./include/ruby/internal/static_assert.h:51:46: error: static assertion failed: "sizeof_method_def: offsetof(rb_method_definition_t, body)==8"
   51 | # define RBIMPL_STATIC_ASSERT0 __extension__ _Static_assert
      |                                              ^~~~~~~~~~~~~~
./include/ruby/internal/static_assert.h:70:5: note: in expansion of macro 'RBIMPL_STATIC_ASSERT0'
   70 |     RBIMPL_STATIC_ASSERT0(expr, # name ": " # expr)
      |     ^~~~~~~~~~~~~~~~~~~~~
./internal/static_assert.h:13:24: note: in expansion of macro 'RBIMPL_STATIC_ASSERT'
   13 | # define STATIC_ASSERT RBIMPL_STATIC_ASSERT
      |                        ^~~~~~~~~~~~~~~~~~~~
./method.h:203:1: note: in expansion of macro 'STATIC_ASSERT'
  203 | STATIC_ASSERT(sizeof_method_def, offsetof(rb_method_definition_t, body)==8);
      | ^~~~~~~~~~~~~
```
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #19896]</title>
<updated>2023-09-22T13:44:58+00:00</updated>
<author>
<name>Adam Hess</name>
<email>adamhess1991@gmail.com</email>
</author>
<published>2023-09-20T16:26:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8b236e0c66da8f92e9fc33de66cfbc8e4b0c0763'/>
<id>8b236e0c66da8f92e9fc33de66cfbc8e4b0c0763</id>
<content type='text'>
fix memory leak in vm_method

This introduces a unified reference_count to clarify who is referencing a method.
This also allows us to treat the refinement method as the def owner since it counts itself as a reference

Co-authored-by: Peter Zhu &lt;peter@peterzhu.ca&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fix memory leak in vm_method

This introduces a unified reference_count to clarify who is referencing a method.
This also allows us to treat the refinement method as the def owner since it counts itself as a reference

Co-authored-by: Peter Zhu &lt;peter@peterzhu.ca&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix memory leak in complemented method entries</title>
<updated>2023-09-20T14:19:24+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2023-09-20T00:48:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=96c5a4be7b0d72502001734770af0f4a735c544c'/>
<id>96c5a4be7b0d72502001734770af0f4a735c544c</id>
<content type='text'>
[Bug #19894]

When a copy of a complemented method entry is created, there are two
issues:

1. IMEMO_FL_USER3 is not copied, so the complemented status is not
   copied over.
2. In rb_method_entry_clone we increment both alias_count and
   complemented_count. However, when we free the method entry in
   rb_method_definition_release, we only decrement one of the two
   counters, resulting in the rb_method_definition_t being leaked.

Co-authored-by: Adam Hess &lt;adamhess1991@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #19894]

When a copy of a complemented method entry is created, there are two
issues:

1. IMEMO_FL_USER3 is not copied, so the complemented status is not
   copied over.
2. In rb_method_entry_clone we increment both alias_count and
   complemented_count. However, when we free the method entry in
   rb_method_definition_release, we only decrement one of the two
   counters, resulting in the rb_method_definition_t being leaked.

Co-authored-by: Adam Hess &lt;adamhess1991@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>use inline cache for refinements</title>
<updated>2023-07-31T08:13:43+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2023-07-31T07:17:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cfd7729ce7a31c8b6ec5dd0e99c67b2932de4732'/>
<id>cfd7729ce7a31c8b6ec5dd0e99c67b2932de4732</id>
<content type='text'>
From Ruby 3.0, refined method invocations are slow because
resolved methods are not cached by inline cache because of
conservertive strategy. However, `using` clears all caches
so that it seems safe to cache resolved method entries.

This patch caches resolved method entries in inline cache
and clear all of inline method caches when `using` is called.

fix [Bug #18572]

```ruby
 # without refinements

class C
  def foo = :C
end

N = 1_000_000

obj = C.new
require 'benchmark'
Benchmark.bm{|x|
  x.report{N.times{
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
  }}
}

_END__
              user     system      total        real
master    0.362859   0.002544   0.365403 (  0.365424)
modified  0.357251   0.000000   0.357251 (  0.357258)
```

```ruby
 # with refinment but without using

class C
  def foo = :C
end

module R
  refine C do
    def foo = :R
  end
end

N = 1_000_000

obj = C.new
require 'benchmark'
Benchmark.bm{|x|
  x.report{N.times{
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
  }}
}
__END__
               user     system      total        real
master     0.957182   0.000000   0.957182 (  0.957212)
modified   0.359228   0.000000   0.359228 (  0.359238)
```

```ruby
 # with using

class C
  def foo = :C
end

module R
  refine C do
    def foo = :R
  end
end

N = 1_000_000

using R

obj = C.new
require 'benchmark'
Benchmark.bm{|x|
  x.report{N.times{
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
  }}
}
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
From Ruby 3.0, refined method invocations are slow because
resolved methods are not cached by inline cache because of
conservertive strategy. However, `using` clears all caches
so that it seems safe to cache resolved method entries.

This patch caches resolved method entries in inline cache
and clear all of inline method caches when `using` is called.

fix [Bug #18572]

```ruby
 # without refinements

class C
  def foo = :C
end

N = 1_000_000

obj = C.new
require 'benchmark'
Benchmark.bm{|x|
  x.report{N.times{
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
  }}
}

_END__
              user     system      total        real
master    0.362859   0.002544   0.365403 (  0.365424)
modified  0.357251   0.000000   0.357251 (  0.357258)
```

```ruby
 # with refinment but without using

class C
  def foo = :C
end

module R
  refine C do
    def foo = :R
  end
end

N = 1_000_000

obj = C.new
require 'benchmark'
Benchmark.bm{|x|
  x.report{N.times{
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
  }}
}
__END__
               user     system      total        real
master     0.957182   0.000000   0.957182 (  0.957212)
modified   0.359228   0.000000   0.359228 (  0.359238)
```

```ruby
 # with using

class C
  def foo = :C
end

module R
  refine C do
    def foo = :R
  end
end

N = 1_000_000

using R

obj = C.new
require 'benchmark'
Benchmark.bm{|x|
  x.report{N.times{
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
    obj.foo; obj.foo; obj.foo; obj.foo; obj.foo;
  }}
}
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Implement specialized respond_to? (#6363)</title>
<updated>2022-09-14T20:15:55+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-09-14T20:15:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f98d6d3f389e8e46775c5895ddc1a3eec4544533'/>
<id>f98d6d3f389e8e46775c5895ddc1a3eec4544533</id>
<content type='text'>
* Add rb_callable_method_entry_or_negative

* YJIT: Implement specialized respond_to?

This implements a specialized respond_to? in YJIT.

* Update yjit/src/codegen.rs

Co-authored-by: Maxime Chevalier-Boisvert &lt;maximechevalierb@gmail.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Add rb_callable_method_entry_or_negative

* YJIT: Implement specialized respond_to?

This implements a specialized respond_to? in YJIT.

* Update yjit/src/codegen.rs

Co-authored-by: Maxime Chevalier-Boisvert &lt;maximechevalierb@gmail.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>Allow method caching of protected FCALLs</title>
<updated>2022-06-22T01:33:51+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-03-11T19:48:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=9312f4bf62224cc0a11175cb6f9b7d0dd840a491'/>
<id>9312f4bf62224cc0a11175cb6f9b7d0dd840a491</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix memory leak at the same named alias [Bug #18516]</title>
<updated>2022-01-27T06:46:08+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2022-01-26T15:28:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e89d80702bd98a8276243a7fcaa2a158b3bfb659'/>
<id>e89d80702bd98a8276243a7fcaa2a158b3bfb659</id>
<content type='text'>
When aliasing a method to the same name method, set a separate bit
flag on that method definition, instead of the reference count
increment.  Although this kind of alias has no actual effect at
runtime, is used as the hack to suppress the method re-definition
warning.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When aliasing a method to the same name method, set a separate bit
flag on that method definition, instead of the reference count
increment.  Although this kind of alias has no actual effect at
runtime, is used as the hack to suppress the method re-definition
warning.
</pre>
</div>
</content>
</entry>
<entry>
<title>`mandatory_only_cme` should not be in `def`</title>
<updated>2021-12-21T02:03:09+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2021-12-20T21:03:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=df48db987da2bd623d29d06419f2fbc8b7ecb38a'/>
<id>df48db987da2bd623d29d06419f2fbc8b7ecb38a</id>
<content type='text'>
`def` (`rb_method_definition_t`) is shared by multiple callable
method entries (cme, `rb_callable_method_entry_t`).

There are two issues:

* old -&gt; young reference: `cme1-&gt;def-&gt;mandatory_only_cme = monly_cme`
  if `cme1` is young and `monly_cme` is young, there is no problem.
  Howevr, another old `cme2` can refer `def`, in this case, old `cme2`
  points young `monly_cme` and it violates gengc assumption.
* cme can have different `defined_class` but `monly_cme` only has
  one `defined_class`. It does not make sense and `monly_cme`
  should be created for a cme (not `def`).

To solve these issues, this patch allocates `monly_cme` per `cme`.
`cme` does not have another room to store a pointer to the `monly_cme`,
so this patch introduces `overloaded_cme_table`, which is weak key map
`[cme] -&gt; [monly_cme]`.

`def::body::iseqptr::monly_cme` is deleted.

The first issue is reported by Alan Wu.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`def` (`rb_method_definition_t`) is shared by multiple callable
method entries (cme, `rb_callable_method_entry_t`).

There are two issues:

* old -&gt; young reference: `cme1-&gt;def-&gt;mandatory_only_cme = monly_cme`
  if `cme1` is young and `monly_cme` is young, there is no problem.
  Howevr, another old `cme2` can refer `def`, in this case, old `cme2`
  points young `monly_cme` and it violates gengc assumption.
* cme can have different `defined_class` but `monly_cme` only has
  one `defined_class`. It does not make sense and `monly_cme`
  should be created for a cme (not `def`).

To solve these issues, this patch allocates `monly_cme` per `cme`.
`cme` does not have another room to store a pointer to the `monly_cme`,
so this patch introduces `overloaded_cme_table`, which is weak key map
`[cme] -&gt; [monly_cme]`.

`def::body::iseqptr::monly_cme` is deleted.

The first issue is reported by Alan Wu.
</pre>
</div>
</content>
</entry>
<entry>
<title>Lazily create singletons on instance_{exec,eval} (#5146)</title>
<updated>2021-12-02T23:53:39+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2021-12-02T23:53:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=733500e9d02b11ff60fbbdb8daa43c2e9cfbd750'/>
<id>733500e9d02b11ff60fbbdb8daa43c2e9cfbd750</id>
<content type='text'>
* Lazily create singletons on instance_{exec,eval}

Previously when instance_exec or instance_eval was called on an object,
that object would be given a singleton class so that method
definitions inside the block would be added to the object rather than
its class.

This commit aims to improve performance by delaying the creation of the
singleton class unless/until one is needed for method definition. Most
of the time instance_eval is used without any method definition.

This was implemented by adding a flag to the cref indicating that it
represents a singleton of the object rather than a class itself. In this
case CREF_CLASS returns the object's existing class, but in cases that
we are defining a method (either via definemethod or
VM_SPECIAL_OBJECT_CBASE which is used for undef and alias).

This also happens to fix what I believe is a bug. Previously
instance_eval behaved differently with regards to constant access for
true/false/nil than for all other objects. I don't think this was
intentional.

    String::Foo = "foo"
    "".instance_eval("Foo")   # =&gt; "foo"
    Integer::Foo = "foo"
    123.instance_eval("Foo")  # =&gt; "foo"
    TrueClass::Foo = "foo"
    true.instance_eval("Foo") # NameError: uninitialized constant Foo

This also slightly changes the error message when trying to define a method
through instance_eval on an object which can't have a singleton class.

Before:

    $ ruby -e '123.instance_eval { def foo; end }'
    -e:1:in `block in &lt;main&gt;': no class/module to add method (TypeError)

After:

    $ ./ruby -e '123.instance_eval { def foo; end }'
    -e:1:in `block in &lt;main&gt;': can't define singleton (TypeError)

IMO this error is a small improvement on the original and better matches
the (both old and new) message when definging a method using `def self.`

    $ ruby -e '123.instance_eval{ def self.foo; end }'
    -e:1:in `block in &lt;main&gt;': can't define singleton (TypeError)

Co-authored-by: Matthew Draper &lt;matthew@trebex.net&gt;

* Remove "under" argument from yield_under

* Move CREF_SINGLETON_SET into vm_cref_new

* Simplify vm_get_const_base

* Fix leaf VM_SPECIAL_OBJECT_CONST_BASE

Co-authored-by: Matthew Draper &lt;matthew@trebex.net&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Lazily create singletons on instance_{exec,eval}

Previously when instance_exec or instance_eval was called on an object,
that object would be given a singleton class so that method
definitions inside the block would be added to the object rather than
its class.

This commit aims to improve performance by delaying the creation of the
singleton class unless/until one is needed for method definition. Most
of the time instance_eval is used without any method definition.

This was implemented by adding a flag to the cref indicating that it
represents a singleton of the object rather than a class itself. In this
case CREF_CLASS returns the object's existing class, but in cases that
we are defining a method (either via definemethod or
VM_SPECIAL_OBJECT_CBASE which is used for undef and alias).

This also happens to fix what I believe is a bug. Previously
instance_eval behaved differently with regards to constant access for
true/false/nil than for all other objects. I don't think this was
intentional.

    String::Foo = "foo"
    "".instance_eval("Foo")   # =&gt; "foo"
    Integer::Foo = "foo"
    123.instance_eval("Foo")  # =&gt; "foo"
    TrueClass::Foo = "foo"
    true.instance_eval("Foo") # NameError: uninitialized constant Foo

This also slightly changes the error message when trying to define a method
through instance_eval on an object which can't have a singleton class.

Before:

    $ ruby -e '123.instance_eval { def foo; end }'
    -e:1:in `block in &lt;main&gt;': no class/module to add method (TypeError)

After:

    $ ./ruby -e '123.instance_eval { def foo; end }'
    -e:1:in `block in &lt;main&gt;': can't define singleton (TypeError)

IMO this error is a small improvement on the original and better matches
the (both old and new) message when definging a method using `def self.`

    $ ruby -e '123.instance_eval{ def self.foo; end }'
    -e:1:in `block in &lt;main&gt;': can't define singleton (TypeError)

Co-authored-by: Matthew Draper &lt;matthew@trebex.net&gt;

* Remove "under" argument from yield_under

* Move CREF_SINGLETON_SET into vm_cref_new

* Simplify vm_get_const_base

* Fix leaf VM_SPECIAL_OBJECT_CONST_BASE

Co-authored-by: Matthew Draper &lt;matthew@trebex.net&gt;</pre>
</div>
</content>
</entry>
</feed>
