<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/yjit/src/cruby_bindings.inc.rs, branch v3_2_11</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Fix cvar caching when class is cloned</title>
<updated>2023-07-01T05:17:30+00:00</updated>
<author>
<name>eileencodes</name>
<email>eileencodes@gmail.com</email>
</author>
<published>2023-02-07T20:46:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8a3d57971c99680d4baec84553247b9c6ee41080'/>
<id>8a3d57971c99680d4baec84553247b9c6ee41080</id>
<content type='text'>
The class variable cache that was added in
https://github.com/ruby/ruby/pull/4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.

This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.

To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.

This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.

We also added a marking function which was missing.

Fixes [Bug #19379]

Co-authored-by: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The class variable cache that was added in
https://github.com/ruby/ruby/pull/4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.

This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.

To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.

This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.

We also added a marking function which was missing.

Fixes [Bug #19379]

Co-authored-by: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 3b83b265f11965582d4b9b439eff8a501792ab68: [Backport #19404]</title>
<updated>2023-02-06T05:00:47+00:00</updated>
<author>
<name>NARUSE, Yui</name>
<email>naruse@airemix.jp</email>
</author>
<published>2023-02-06T05:00:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3a88589399f7f1059be245f766809c49790ad939'/>
<id>3a88589399f7f1059be245f766809c49790ad939</id>
<content type='text'>
	YJIT: Crash with rb_bug() when panicking

	Helps with getting good bug reports in the wild. Intended to be
	backported to the 3.2.x series.
	---
	 yjit/bindgen/src/main.rs       |  3 +++
	 yjit/src/cruby_bindings.inc.rs |  1 +
	 yjit/src/yjit.rs               | 29 +++++++++++++++++++++++++++--
	 3 files changed, 31 insertions(+), 2 deletions(-)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	YJIT: Crash with rb_bug() when panicking

	Helps with getting good bug reports in the wild. Intended to be
	backported to the 3.2.x series.
	---
	 yjit/bindgen/src/main.rs       |  3 +++
	 yjit/src/cruby_bindings.inc.rs |  1 +
	 yjit/src/yjit.rs               | 29 +++++++++++++++++++++++++++--
	 3 files changed, 31 insertions(+), 2 deletions(-)
</pre>
</div>
</content>
</entry>
<entry>
<title>MJIT: Export fewer shape functions (#7007)</title>
<updated>2022-12-23T18:18:57+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2022-12-23T18:18:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1d3bfd804cdba027ab9ec79678692b607c43b798'/>
<id>1d3bfd804cdba027ab9ec79678692b607c43b798</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Use a BOP for Hash#default</title>
<updated>2022-12-17T22:51:49+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-12-15T18:46:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=fbaa5db44a3b0622e2755fd00e0519a603aa9bcb'/>
<id>fbaa5db44a3b0622e2755fd00e0519a603aa9bcb</id>
<content type='text'>
On a hash miss we need to call default if it is redefined in order to
return the default value to be used. Previously we checked this with
rb_method_basic_definition_p, which avoids the method call but requires
a method lookup.

This commit replaces the previous check with BASIC_OP_UNREDEFINED_P and
a new BOP_DEFAULT. We still need to fall back to
rb_method_basic_definition_p when called on a subclasss of hash.

    |                |compare-ruby|built-ruby|
    |:---------------|-----------:|---------:|
    |hash_aref_miss  |       2.692|     3.531|
    |                |           -|     1.31x|

Co-authored-by: Daniel Colson &lt;danieljamescolson@gmail.com&gt;
Co-authored-by: "Ian C. Anderson" &lt;ian@iancanderson.com&gt;
Co-authored-by: Jack McCracken &lt;me@jackmc.xyz&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
On a hash miss we need to call default if it is redefined in order to
return the default value to be used. Previously we checked this with
rb_method_basic_definition_p, which avoids the method call but requires
a method lookup.

This commit replaces the previous check with BASIC_OP_UNREDEFINED_P and
a new BOP_DEFAULT. We still need to fall back to
rb_method_basic_definition_p when called on a subclasss of hash.

    |                |compare-ruby|built-ruby|
    |:---------------|-----------:|---------:|
    |hash_aref_miss  |       2.692|     3.531|
    |                |           -|     1.31x|

Co-authored-by: Daniel Colson &lt;danieljamescolson@gmail.com&gt;
Co-authored-by: "Ian C. Anderson" &lt;ian@iancanderson.com&gt;
Co-authored-by: Jack McCracken &lt;me@jackmc.xyz&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Move definition of SIZE_POOL_COUNT back to gc.h</title>
<updated>2022-12-15T21:33:46+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2022-12-15T18:54:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c505448cdbd4cd1a52ed7108095f6738d29b3419'/>
<id>c505448cdbd4cd1a52ed7108095f6738d29b3419</id>
<content type='text'>
SIZE_POOL_COUNT is a GC macro, it should belong in gc.h and not shape.h.
SIZE_POOL_COUNT doesn't depend on shape.h so we can have shape.h depend
on gc.h.

Co-Authored-By: Matt Valentine-House &lt;matt@eightbitraptor.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
SIZE_POOL_COUNT is a GC macro, it should belong in gc.h and not shape.h.
SIZE_POOL_COUNT doesn't depend on shape.h so we can have shape.h depend
on gc.h.

Co-Authored-By: Matt Valentine-House &lt;matt@eightbitraptor.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Transition complex objects to "too complex" shape</title>
<updated>2022-12-15T18:06:04+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-12-08T22:16:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c1ab6ddc9a6fa228caa5d26b118b54855051279c'/>
<id>c1ab6ddc9a6fa228caa5d26b118b54855051279c</id>
<content type='text'>
When an object becomes "too complex" (in other words it has too many
variations in the shape tree), we transition it to use a "too complex"
shape and use a hash for storing instance variables.

Without this patch, there were rare cases where shape tree growth could
"explode" and cause performance degradation on what would otherwise have
been cached fast paths.

This patch puts a limit on shape tree growth, and gracefully degrades in
the rare case where there could be a factorial growth in the shape tree.

For example:

```ruby
class NG; end

HUGE_NUMBER.times do
  NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1)
end
```

We consider objects to be "too complex" when the object's class has more
than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and
the object introduces a new variation (a new leaf node) associated with
that class.

For example, new variations on instances of the following class would be
considered "too complex" because those instances create more than 8
leaves in the shape tree:

```ruby
class Foo; end
9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) }
```

However, the following class is *not* too complex because it only has
one leaf in the shape tree:

```ruby
class Foo
  def initialize
    @a = @b = @c = @d = @e = @f = @g = @h = @i = nil
  end
end
9.times { Foo.new }
``

This case is rare, so we don't expect this change to impact performance
of most applications, but it needs to be handled.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When an object becomes "too complex" (in other words it has too many
variations in the shape tree), we transition it to use a "too complex"
shape and use a hash for storing instance variables.

Without this patch, there were rare cases where shape tree growth could
"explode" and cause performance degradation on what would otherwise have
been cached fast paths.

This patch puts a limit on shape tree growth, and gracefully degrades in
the rare case where there could be a factorial growth in the shape tree.

For example:

```ruby
class NG; end

HUGE_NUMBER.times do
  NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1)
end
```

We consider objects to be "too complex" when the object's class has more
than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and
the object introduces a new variation (a new leaf node) associated with
that class.

For example, new variations on instances of the following class would be
considered "too complex" because those instances create more than 8
leaves in the shape tree:

```ruby
class Foo; end
9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) }
```

However, the following class is *not* too complex because it only has
one leaf in the shape tree:

```ruby
class Foo
  def initialize
    @a = @b = @c = @d = @e = @f = @g = @h = @i = nil
  end
end
9.times { Foo.new }
``

This case is rare, so we don't expect this change to impact performance
of most applications, but it needs to be handled.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Upgrade bindgen to stabilize and reduce output</title>
<updated>2022-12-08T22:35:18+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2022-12-08T20:03:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e714907d82f486c13fc1ea5e3ad291dabf4e7fbe'/>
<id>e714907d82f486c13fc1ea5e3ad291dabf4e7fbe</id>
<content type='text'>
The new version has an option to merge everything into a big
`extern "C"` block and it's nicer.

More importantly, this upgrade fixes an issue where Ubuntu with Clang 12
and macOS with Clang 14 gave a one line diff for `rb_shape_t`. It was
slightly annoying because we use macOS locally.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The new version has an option to merge everything into a big
`extern "C"` block and it's nicer.

More importantly, this upgrade fixes an issue where Ubuntu with Clang 12
and macOS with Clang 14 gave a one line diff for `rb_shape_t`. It was
slightly annoying because we use macOS locally.
</pre>
</div>
</content>
</entry>
<entry>
<title>Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`. (#6867)</title>
<updated>2022-12-08T05:19:53+00:00</updated>
<author>
<name>Samuel Williams</name>
<email>samuel.williams@oriontransfer.co.nz</email>
</author>
<published>2022-12-08T05:19:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6fd5d2dc003bda5ce0685abd2b975d7ac7079d46'/>
<id>6fd5d2dc003bda5ce0685abd2b975d7ac7079d46</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Set max_iv_count (used for object shapes) based on inline caches</title>
<updated>2022-12-06T21:43:42+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-12-06T19:52:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=40a9964b893fee5680b455d0e905155be3360685'/>
<id>40a9964b893fee5680b455d0e905155be3360685</id>
<content type='text'>
With this change, we're storing the iv name on an inline cache on
setinstancevariable instructions. This allows us to check the inline
cache to count instance variables set in initialize and give us an
estimate of iv capacity for an object.

For the purpose of estimating the number of instance variables required
for an object, we're assuming that all initialize methods will call
`super`.

This change allows us to estimate the number of instance variables
required without disassembling instruction sequences.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With this change, we're storing the iv name on an inline cache on
setinstancevariable instructions. This allows us to check the inline
cache to count instance variables set in initialize and give us an
estimate of iv capacity for an object.

For the purpose of estimating the number of instance variables required
for an object, we're assuming that all initialize methods will call
`super`.

This change allows us to estimate the number of instance variables
required without disassembling instruction sequences.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Introduce BOP_CMP for optimized comparison</title>
<updated>2022-12-06T20:37:23+00:00</updated>
<author>
<name>Daniel Colson</name>
<email>danieljamescolson@gmail.com</email>
</author>
<published>2022-11-23T02:16:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e69b91fae4602b69c5ef45fcf82932adde8b31d8'/>
<id>e69b91fae4602b69c5ef45fcf82932adde8b31d8</id>
<content type='text'>
Prior to this commit the `OPTIMIZED_CMP` macro relied on a method lookup
to determine whether `&lt;=&gt;` was overridden. The result of the lookup was
cached, but only for the duration of the specific method that
initialized the cmp_opt_data cache structure.

With this method lookup, `[x,y].max` is slower than doing `x &gt; y ?
x : y` even though there's an optimized instruction for "new array max".
(John noticed somebody a proposed micro-optimization based on this fact
in https://github.com/mastodon/mastodon/pull/19903.)

```rb
a, b = 1, 2
Benchmark.ips do |bm|
  bm.report('conditional') { a &gt; b ? a : b }
  bm.report('method') { [a, b].max }
  bm.compare!
end
```

Before:

```
Comparison:
         conditional: 22603733.2 i/s
              method: 19820412.7 i/s - 1.14x  (± 0.00) slower
```

This commit replaces the method lookup with a new CMP basic op, which
gives the examples above equivalent performance.

After:

```
Comparison:
              method: 24022466.5 i/s
         conditional: 23851094.2 i/s - same-ish: difference falls within
error
```

Relevant benchmarks show an improvement to Array#max and Array#min when
not using the optimized newarray_max instruction as well. They are
noticeably faster for small arrays with the relevant types, and the same
or maybe a touch faster on larger arrays.

```
$ make benchmark COMPARE_RUBY=&lt;master@5958c305&gt; ITEM=array_min
$ make benchmark COMPARE_RUBY=&lt;master@5958c305&gt; ITEM=array_max
```

The benchmarks added in this commit also look generally improved.

Co-authored-by: John Hawthorn &lt;jhawthorn@github.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Prior to this commit the `OPTIMIZED_CMP` macro relied on a method lookup
to determine whether `&lt;=&gt;` was overridden. The result of the lookup was
cached, but only for the duration of the specific method that
initialized the cmp_opt_data cache structure.

With this method lookup, `[x,y].max` is slower than doing `x &gt; y ?
x : y` even though there's an optimized instruction for "new array max".
(John noticed somebody a proposed micro-optimization based on this fact
in https://github.com/mastodon/mastodon/pull/19903.)

```rb
a, b = 1, 2
Benchmark.ips do |bm|
  bm.report('conditional') { a &gt; b ? a : b }
  bm.report('method') { [a, b].max }
  bm.compare!
end
```

Before:

```
Comparison:
         conditional: 22603733.2 i/s
              method: 19820412.7 i/s - 1.14x  (± 0.00) slower
```

This commit replaces the method lookup with a new CMP basic op, which
gives the examples above equivalent performance.

After:

```
Comparison:
              method: 24022466.5 i/s
         conditional: 23851094.2 i/s - same-ish: difference falls within
error
```

Relevant benchmarks show an improvement to Array#max and Array#min when
not using the optimized newarray_max instruction as well. They are
noticeably faster for small arrays with the relevant types, and the same
or maybe a touch faster on larger arrays.

```
$ make benchmark COMPARE_RUBY=&lt;master@5958c305&gt; ITEM=array_min
$ make benchmark COMPARE_RUBY=&lt;master@5958c305&gt; ITEM=array_max
```

The benchmarks added in this commit also look generally improved.

Co-authored-by: John Hawthorn &lt;jhawthorn@github.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
