<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/ruby.git/method.h, branch ruby_3_2</title>
<subtitle>github.com: ruby/ruby.git
</subtitle>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/ruby.git/'/>
<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='http://trove.baserock.org/cgit/delta/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='http://trove.baserock.org/cgit/delta/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='http://trove.baserock.org/cgit/delta/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='http://trove.baserock.org/cgit/delta/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='http://trove.baserock.org/cgit/delta/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>
<entry>
<title>optimize `Struct` getter/setter</title>
<updated>2021-11-18T23:32:39+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2021-11-18T02:01:31+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/ruby.git/commit/?id=82ea2870188d66aa75a99f03b4e7fdd1750aa196'/>
<id>82ea2870188d66aa75a99f03b4e7fdd1750aa196</id>
<content type='text'>
Introduce new optimized method type
`OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Introduce new optimized method type
`OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
</pre>
</div>
</content>
</entry>
<entry>
<title>`rb_method_optimized_t` for further extension</title>
<updated>2021-11-18T23:32:39+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2021-11-17T15:43:40+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/ruby.git/commit/?id=be71c95b88019a1ca7a030a757ce343b743d8aff'/>
<id>be71c95b88019a1ca7a030a757ce343b743d8aff</id>
<content type='text'>
Now `rb_method_optimized_t optimized` field is added to represent
optimized method type.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now `rb_method_optimized_t optimized` field is added to represent
optimized method type.
</pre>
</div>
</content>
</entry>
<entry>
<title>`Primitive.mandatory_only?` for fast path</title>
<updated>2021-11-15T06:58:56+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2021-11-12T17:12:20+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/ruby.git/commit/?id=b1b73936c15fd490159a9b30ab50b8d5dfea1264'/>
<id>b1b73936c15fd490159a9b30ab50b8d5dfea1264</id>
<content type='text'>
Compare with the C methods, A built-in methods written in Ruby is
slower if only mandatory parameters are given because it needs to
check the argumens and fill default values for optional and keyword
parameters (C methods can check the number of parameters with `argc`,
so there are no overhead). Passing mandatory arguments are common
(optional arguments are exceptional, in many cases) so it is important
to provide the fast path for such common cases.

`Primitive.mandatory_only?` is a special builtin function used with
`if` expression like that:

```ruby
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    if Primitive.mandatory_only?
      Primitive.time_s_at1(time)
    else
      Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
    end
  end
```

and it makes two ISeq,

```
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
  end

  def self.at(time)
    Primitive.time_s_at1(time)
  end
```

and (2) is pointed by (1). Note that `Primitive.mandatory_only?`
should be used only in a condition of an `if` statement and the
`if` statement should be equal to the methdo body (you can not
put any expression before and after the `if` statement).

A method entry with `mandatory_only?` (`Time.at` on the above case)
is marked as `iseq_overload`. When the method will be dispatch only
with mandatory arguments (`Time.at(0)` for example), make another
method entry with ISeq (2) as mandatory only method entry and it
will be cached in an inline method cache.

The idea is similar discussed in https://bugs.ruby-lang.org/issues/16254
but it only checks mandatory parameters or more, because many cases
only mandatory parameters are given. If we find other cases (optional
or keyword parameters are used frequently and it hurts performance),
we can extend the feature.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Compare with the C methods, A built-in methods written in Ruby is
slower if only mandatory parameters are given because it needs to
check the argumens and fill default values for optional and keyword
parameters (C methods can check the number of parameters with `argc`,
so there are no overhead). Passing mandatory arguments are common
(optional arguments are exceptional, in many cases) so it is important
to provide the fast path for such common cases.

`Primitive.mandatory_only?` is a special builtin function used with
`if` expression like that:

```ruby
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    if Primitive.mandatory_only?
      Primitive.time_s_at1(time)
    else
      Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
    end
  end
```

and it makes two ISeq,

```
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
  end

  def self.at(time)
    Primitive.time_s_at1(time)
  end
```

and (2) is pointed by (1). Note that `Primitive.mandatory_only?`
should be used only in a condition of an `if` statement and the
`if` statement should be equal to the methdo body (you can not
put any expression before and after the `if` statement).

A method entry with `mandatory_only?` (`Time.at` on the above case)
is marked as `iseq_overload`. When the method will be dispatch only
with mandatory arguments (`Time.at(0)` for example), make another
method entry with ISeq (2) as mandatory only method entry and it
will be cached in an inline method cache.

The idea is similar discussed in https://bugs.ruby-lang.org/issues/16254
but it only checks mandatory parameters or more, because many cases
only mandatory parameters are given. If we find other cases (optional
or keyword parameters are used frequently and it hurts performance),
we can extend the feature.
</pre>
</div>
</content>
</entry>
<entry>
<title>prohibi method call by defined_method in other racotrs</title>
<updated>2020-09-25T11:37:38+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2020-09-25T09:31:04+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/ruby.git/commit/?id=caaa36b4e6d0d59f0aa21049c063b140aa5aae4f'/>
<id>caaa36b4e6d0d59f0aa21049c063b140aa5aae4f</id>
<content type='text'>
We can not call a non-isolated Proc in multiple ractors.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We can not call a non-isolated Proc in multiple ractors.
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove write barrier exemption for T_ICLASS</title>
<updated>2020-08-17T21:17:47+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2020-08-10T22:19:17+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/ruby.git/commit/?id=264e4cd04fbcdcb739a1ff9a84e19afe66005cb2'/>
<id>264e4cd04fbcdcb739a1ff9a84e19afe66005cb2</id>
<content type='text'>
Before this commit, iclasses were "shady", or not protected by write
barriers. Because of that, the GC needs to spend more time marking these
objects than otherwise.

Applications that make heavy use of modules should see reduction in GC
time as they have a significant number of live iclasses on the heap.

 - Put logic for iclass method table ownership into a function
 - Remove calls to WB_UNPROTECT and insert write barriers for iclasses

This commit relies on the following invariant: for any non oirigin
iclass `I`, `RCLASS_M_TBL(I) == RCLASS_M_TBL(RBasic(I)-&gt;klass)`. This
invariant did not hold prior to 98286e9 for classes and modules that
have prepended modules.

[Feature #16984]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Before this commit, iclasses were "shady", or not protected by write
barriers. Because of that, the GC needs to spend more time marking these
objects than otherwise.

Applications that make heavy use of modules should see reduction in GC
time as they have a significant number of live iclasses on the heap.

 - Put logic for iclass method table ownership into a function
 - Remove calls to WB_UNPROTECT and insert write barriers for iclasses

This commit relies on the following invariant: for any non oirigin
iclass `I`, `RCLASS_M_TBL(I) == RCLASS_M_TBL(RBasic(I)-&gt;klass)`. This
invariant did not hold prior to 98286e9 for classes and modules that
have prepended modules.

[Feature #16984]
</pre>
</div>
</content>
</entry>
</feed>
