<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/internal/class.h, 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>merge revision(s) e626da82eae3d437b84d4f9ead0164d436b08e1a, f3af5ae7e6c1c096bbfe46d69de825a02b1696cf: [Backport #20311]</title>
<updated>2024-07-07T07:44:06+00:00</updated>
<author>
<name>nagachika</name>
<email>nagachika@ruby-lang.org</email>
</author>
<published>2024-07-07T05:47:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=bd5df1693c89d389471d145fc19b487c708912b1'/>
<id>bd5df1693c89d389471d145fc19b487c708912b1</id>
<content type='text'>
	Don't pin named structs defined in Ruby

	[Bug #20311]

	`rb_define_class_under` assumes it's called from C and that the
	reference might be held in a C global variable, so it adds the
	class to the VM root.

	In the case of `Struct.new('Name')` it's wasteful and make
	the struct immortal.

	Make Struct memory leak test faster

	[Bug #20311]

	It times out on some platform, so we can reduce iterations.
	On my machine it completes in 250ms and RSS grows 8X.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	Don't pin named structs defined in Ruby

	[Bug #20311]

	`rb_define_class_under` assumes it's called from C and that the
	reference might be held in a C global variable, so it adds the
	class to the VM root.

	In the case of `Struct.new('Name')` it's wasteful and make
	the struct immortal.

	Make Struct memory leak test faster

	[Bug #20311]

	It times out on some platform, so we can reduce iterations.
	On my machine it completes in 250ms and RSS grows 8X.
</pre>
</div>
</content>
</entry>
<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>Add variation_count on classes</title>
<updated>2022-12-15T18:06:04+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-12-08T21:48:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a3d552aedd190b0f21a4f6479f0ef1d2ce90189b'/>
<id>a3d552aedd190b0f21a4f6479f0ef1d2ce90189b</id>
<content type='text'>
Count how many "variations" each class creates. A "variation" is a a
unique ordering of instance variables on a particular class. This can
also be thought of as a branch in the shape tree.

For example, the following Foo class will have 2 variations:

```ruby
class Foo ; end

Foo.new.instance_variable_set(:@a, 1) # case 1: creates one variation
Foo.new.instance_variable_set(:@b, 1) # case 2: creates another variation

foo = Foo.new
foo.instance_variable_set(:@a, 1) # does not create a new variation
foo.instance_variable_set(:@b, 1) # does not create a new variation (a continuation of the variation in case 1)
```

We will use this number to limit the amount of shapes that a class can
create and fallback to using a hash iv lookup.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Count how many "variations" each class creates. A "variation" is a a
unique ordering of instance variables on a particular class. This can
also be thought of as a branch in the shape tree.

For example, the following Foo class will have 2 variations:

```ruby
class Foo ; end

Foo.new.instance_variable_set(:@a, 1) # case 1: creates one variation
Foo.new.instance_variable_set(:@b, 1) # case 2: creates another variation

foo = Foo.new
foo.instance_variable_set(:@a, 1) # does not create a new variation
foo.instance_variable_set(:@b, 1) # does not create a new variation (a continuation of the variation in case 1)
```

We will use this number to limit the amount of shapes that a class can
create and fallback to using a hash iv lookup.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</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='https://git.ruby-lang.org/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>
<entry>
<title>Implement object shapes for T_CLASS and T_MODULE (#6637)</title>
<updated>2022-10-31T21:05:37+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-10-31T21:05:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=02f15542245222ee392e68fb244b3b8c4a12ad82'/>
<id>02f15542245222ee392e68fb244b3b8c4a12ad82</id>
<content type='text'>
* Avoid RCLASS_IV_TBL in marshal.c
* Avoid RCLASS_IV_TBL for class names
* Avoid RCLASS_IV_TBL for autoload
* Avoid RCLASS_IV_TBL for class variables
* Avoid copying RCLASS_IV_TBL onto ICLASSes
* Use object shapes for Class and Module IVs</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Avoid RCLASS_IV_TBL in marshal.c
* Avoid RCLASS_IV_TBL for class names
* Avoid RCLASS_IV_TBL for autoload
* Avoid RCLASS_IV_TBL for class variables
* Avoid copying RCLASS_IV_TBL onto ICLASSes
* Use object shapes for Class and Module IVs</pre>
</div>
</content>
</entry>
<entry>
<title>Remove iv_index_tbl_entry</title>
<updated>2022-10-24T17:54:01+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2022-10-21T21:31:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b652dbf63b963f92abddf15ed4f2fed0787e1969'/>
<id>b652dbf63b963f92abddf15ed4f2fed0787e1969</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove unused class serial</title>
<updated>2022-10-21T21:56:48+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-10-21T16:58:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=13bd617ea6fdf72467c593639cf33312a06c330c'/>
<id>13bd617ea6fdf72467c593639cf33312a06c330c</id>
<content type='text'>
Before object shapes, we were using class serial to invalidate
inline caches. Now that we use shape_id for inline cache keys,
the class serial is unnecessary.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Before object shapes, we were using class serial to invalidate
inline caches. Now that we use shape_id for inline cache keys,
the class serial is unnecessary.

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Revert "This commit implements the Object Shapes technique in CRuby.""</title>
<updated>2022-10-11T15:40:56+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-10-03T15:14:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ad63b668e22e21c352b852f3119ae98a7acf99f1'/>
<id>ad63b668e22e21c352b852f3119ae98a7acf99f1</id>
<content type='text'>
This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "This commit implements the Object Shapes technique in CRuby."</title>
<updated>2022-09-30T23:01:50+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2022-09-30T23:01:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=9a6803c90b817f70389cae10d60b50ad752da48f'/>
<id>9a6803c90b817f70389cae10d60b50ad752da48f</id>
<content type='text'>
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
</pre>
</div>
</content>
</entry>
<entry>
<title>This commit implements the Object Shapes technique in CRuby.</title>
<updated>2022-09-28T15:26:21+00:00</updated>
<author>
<name>Jemma Issroff</name>
<email>jemmaissroff@gmail.com</email>
</author>
<published>2022-09-23T17:54:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d594a5a8bd0756f65c078fcf5ce0098250cba141'/>
<id>d594a5a8bd0756f65c078fcf5ce0098250cba141</id>
<content type='text'>
Object Shapes is used for accessing instance variables and representing the
"frozenness" of objects.  Object instances have a "shape" and the shape
represents some attributes of the object (currently which instance variables are
set and the "frozenness").  Shapes form a tree data structure, and when a new
instance variable is set on an object, that object "transitions" to a new shape
in the shape tree.  Each shape has an ID that is used for caching. The shape
structure is independent of class, so objects of different types can have the
same shape.

For example:

```ruby
class Foo
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

class Bar
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
```

Both `foo` and `bar` instances have the same shape because they both set
instance variables of the same name in the same order.

This technique can help to improve inline cache hits as well as generate more
efficient machine code in JIT compilers.

This commit also adds some methods for debugging shapes on objects.  See
`RubyVM::Shape` for more details.

For more context on Object Shapes, see [Feature: #18776]

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
Co-Authored-By: Eileen M. Uchitelle &lt;eileencodes@gmail.com&gt;
Co-Authored-By: John Hawthorn &lt;john@hawthorn.email&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Object Shapes is used for accessing instance variables and representing the
"frozenness" of objects.  Object instances have a "shape" and the shape
represents some attributes of the object (currently which instance variables are
set and the "frozenness").  Shapes form a tree data structure, and when a new
instance variable is set on an object, that object "transitions" to a new shape
in the shape tree.  Each shape has an ID that is used for caching. The shape
structure is independent of class, so objects of different types can have the
same shape.

For example:

```ruby
class Foo
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

class Bar
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
```

Both `foo` and `bar` instances have the same shape because they both set
instance variables of the same name in the same order.

This technique can help to improve inline cache hits as well as generate more
efficient machine code in JIT compilers.

This commit also adds some methods for debugging shapes on objects.  See
`RubyVM::Shape` for more details.

For more context on Object Shapes, see [Feature: #18776]

Co-Authored-By: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
Co-Authored-By: Eileen M. Uchitelle &lt;eileencodes@gmail.com&gt;
Co-Authored-By: John Hawthorn &lt;john@hawthorn.email&gt;
</pre>
</div>
</content>
</entry>
</feed>
