<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/ruby.git/object.c, branch ruby_3_2</title>
<subtitle>github.com: ruby/ruby.git
</subtitle>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/'/>
<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='http://91.123.203.49/cgit/delta/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>Use rb_inspect instead of +PRIsVALUE for Object.inspect</title>
<updated>2022-12-09T13:11:00+00:00</updated>
<author>
<name>Matt Valentine-House</name>
<email>matt@eightbitraptor.com</email>
</author>
<published>2022-12-07T16:01:37+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=181d4bee5e03a30596e78b2d7aa0396887a53881'/>
<id>181d4bee5e03a30596e78b2d7aa0396887a53881</id>
<content type='text'>
In order to preserve the values when TrueClass, FalseClass or NilClass
are stored in ivars
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In order to preserve the values when TrueClass, FalseClass or NilClass
are stored in ivars
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove dead code in rb_obj_copy_ivar</title>
<updated>2022-11-22T21:49:46+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2022-11-14T16:22:00+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=003f8ea80983d9a2c1d5352c448ad2991fb73ad7'/>
<id>003f8ea80983d9a2c1d5352c448ad2991fb73ad7</id>
<content type='text'>
The removed code is a duplicate of the code above.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The removed code is a duplicate of the code above.
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactor obj_ivar_set and vm_setivar</title>
<updated>2022-11-21T14:58:53+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2022-11-15T15:52:39+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=648927d71bde5df02a0490f5f45bb7fcde913376'/>
<id>648927d71bde5df02a0490f5f45bb7fcde913376</id>
<content type='text'>
obj_ivar_set and vm_setivar_slowpath is essentially doing the same thing,
but the code is duplicated and not quite implemented in the same way,
which could cause bugs. This commit refactors vm_setivar_slowpath to use
obj_ivar_set.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
obj_ivar_set and vm_setivar_slowpath is essentially doing the same thing,
but the code is duplicated and not quite implemented in the same way,
which could cause bugs. This commit refactors vm_setivar_slowpath to use
obj_ivar_set.
</pre>
</div>
</content>
</entry>
<entry>
<title>Update assertion</title>
<updated>2022-11-18T21:58:13+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2022-11-18T21:58:13+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=2185f0ca772c1e8c318198b54e3a694b55945bbb'/>
<id>2185f0ca772c1e8c318198b54e3a694b55945bbb</id>
<content type='text'>
New T_OBJECT objects will have a T_OBJECT shape
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
New T_OBJECT objects will have a T_OBJECT shape
</pre>
</div>
</content>
</entry>
<entry>
<title>Differentiate T_OBJECT shapes from other objects</title>
<updated>2022-11-18T16:31:56+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2022-11-17T23:57:11+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=10788166e7e568fdcd0b748e8d5dab442dcdc7ef'/>
<id>10788166e7e568fdcd0b748e8d5dab442dcdc7ef</id>
<content type='text'>
We would like to differentiate types of objects via their shape.  This
commit adds a special T_OBJECT shape when we allocate an instance of
T_OBJECT.  This allows us to avoid testing whether an object is an
instance of a T_OBJECT or not, we can just check the shape.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We would like to differentiate types of objects via their shape.  This
commit adds a special T_OBJECT shape when we allocate an instance of
T_OBJECT.  This allows us to avoid testing whether an object is an
instance of a T_OBJECT or not, we can just check the shape.
</pre>
</div>
</content>
</entry>
<entry>
<title>Using UNDEF_P macro</title>
<updated>2022-11-16T09:58:33+00:00</updated>
<author>
<name>S-H-GAMELINKS</name>
<email>gamelinks007@gmail.com</email>
</author>
<published>2022-11-15T04:24:08+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=1f4f6c9832d83e7ebd65ccf4e95cef358b3512c6'/>
<id>1f4f6c9832d83e7ebd65ccf4e95cef358b3512c6</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Extract `rb_shape_get_parent` helper</title>
<updated>2022-11-10T18:02:50+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-11-10T16:36:24+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=7ee1cacb84e6b19908ac0e692601447597d40605'/>
<id>7ee1cacb84e6b19908ac0e692601447597d40605</id>
<content type='text'>
Extract an `rb_shape_get_parent` method instead of continually calling
`rb_shape_get_shape_by_id(shape-&gt;parent_id)`
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Extract an `rb_shape_get_parent` method instead of continually calling
`rb_shape_get_shape_by_id(shape-&gt;parent_id)`
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove numiv from RObject</title>
<updated>2022-11-10T15:11:34+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-11-08T19:09:43+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=c726c48a3dacd9ca1cb0d96fee98890cb74b37d3'/>
<id>c726c48a3dacd9ca1cb0d96fee98890cb74b37d3</id>
<content type='text'>
Since object shapes store the capacity of an object, we no longer
need the numiv field on RObjects. This gives us one extra slot which
we can use to give embedded objects one more instance variable (for a
total of 3 ivs). This commit removes the concept of numiv from RObject.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Since object shapes store the capacity of an object, we no longer
need the numiv field on RObjects. This gives us one extra slot which
we can use to give embedded objects one more instance variable (for a
total of 3 ivs). This commit removes the concept of numiv from RObject.
</pre>
</div>
</content>
</entry>
<entry>
<title>Transition shape when object's capacity changes</title>
<updated>2022-11-10T15:11:34+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-11-08T20:35:31+00:00</published>
<link rel='alternate' type='text/html' href='http://91.123.203.49/cgit/delta/ruby.git/commit/?id=5246f4027ec574e77809845e1b1f7822cc2a5cef'/>
<id>5246f4027ec574e77809845e1b1f7822cc2a5cef</id>
<content type='text'>
This commit adds a `capacity` field to shapes, and adds shape
transitions whenever an object's capacity changes. Objects which are
allocated out of a bigger size pool will also make a transition from the
root shape to the shape with the correct capacity for their size pool
when they are allocated.

This commit will allow us to remove numiv from objects completely, and
will also mean we can guarantee that if two objects share shapes, their
IVs are in the same positions (an embedded and extended object cannot
share shapes). This will enable us to implement ivar sets in YJIT using
object shapes.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit adds a `capacity` field to shapes, and adds shape
transitions whenever an object's capacity changes. Objects which are
allocated out of a bigger size pool will also make a transition from the
root shape to the shape with the correct capacity for their size pool
when they are allocated.

This commit will allow us to remove numiv from objects completely, and
will also mean we can guarantee that if two objects share shapes, their
IVs are in the same positions (an embedded and extended object cannot
share shapes). This will enable us to implement ivar sets in YJIT using
object shapes.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
