<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/internal/class.h, branch v3_4_9</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Rename size_pool -&gt; heap</title>
<updated>2024-10-03T20:20:09+00:00</updated>
<author>
<name>Matt Valentine-House</name>
<email>matt@eightbitraptor.com</email>
</author>
<published>2024-10-03T12:53:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8e7df4b7c674cf408fa570b9593811167bbff04a'/>
<id>8e7df4b7c674cf408fa570b9593811167bbff04a</id>
<content type='text'>
Now that we've inlined the eden_heap into the size_pool, we should
rename the size_pool to heap. So that Ruby contains multiple heaps, with
different sized objects.

The term heap as a collection of memory pages is more in memory
management nomenclature, whereas size_pool was a name chosen out of
necessity during the development of the Variable Width Allocation
features of Ruby.

The concept of size pools was introduced in order to facilitate
different sized objects (other than the default 40 bytes). They wrapped
the eden heap and the tomb heap, and some related state, and provided a
reasonably simple way of duplicating all related concerns, to provide
multiple pools that all shared the same structure but held different
objects.

Since then various changes have happend in Ruby's memory layout:

* The concept of tomb heaps has been replaced by a global free pages list,
  with each page having it's slot size reconfigured at the point when it
  is resurrected
* the eden heap has been inlined into the size pool itself, so that now
  the size pool directly controls the free_pages list, the sweeping
  page, the compaction cursor and the other state that was previously
  being managed by the eden heap.

Now that there is no need for a heap wrapper, we should refer to the
collection of pages containing Ruby objects as a heap again rather than
a size pool
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now that we've inlined the eden_heap into the size_pool, we should
rename the size_pool to heap. So that Ruby contains multiple heaps, with
different sized objects.

The term heap as a collection of memory pages is more in memory
management nomenclature, whereas size_pool was a name chosen out of
necessity during the development of the Variable Width Allocation
features of Ruby.

The concept of size pools was introduced in order to facilitate
different sized objects (other than the default 40 bytes). They wrapped
the eden heap and the tomb heap, and some related state, and provided a
reasonably simple way of duplicating all related concerns, to provide
multiple pools that all shared the same structure but held different
objects.

Since then various changes have happend in Ruby's memory layout:

* The concept of tomb heaps has been replaced by a global free pages list,
  with each page having it's slot size reconfigured at the point when it
  is resurrected
* the eden heap has been inlined into the size pool itself, so that now
  the size pool directly controls the free_pages list, the sweeping
  page, the compaction cursor and the other state that was previously
  being managed by the eden heap.

Now that there is no need for a heap wrapper, we should refer to the
collection of pages containing Ruby objects as a heap again rather than
a size pool
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactor VM root modules</title>
<updated>2024-03-06T20:33:43+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>byroot@ruby-lang.org</email>
</author>
<published>2024-03-03T09:46:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d4f3dcf4dff80ded472ba3061e62c6c676ffab8c'/>
<id>d4f3dcf4dff80ded472ba3061e62c6c676ffab8c</id>
<content type='text'>
This `st_table` is used to both mark and pin classes
defined from the C API. But `vm-&gt;mark_object_ary` already
does both much more efficiently.

Currently a Ruby process starts with 252 rooted classes,
which uses `7224B` in an `st_table` or `2016B` in an `RArray`.

So a baseline of 5kB saved, but since `mark_object_ary` is
preallocated with `1024` slots but only use `405` of them,
it's a net `7kB` save.

`vm-&gt;mark_object_ary` is also being refactored.

Prior to this changes, `mark_object_ary` was a regular `RArray`, but
since this allows for references to be moved, it was marked a second
time from `rb_vm_mark()` to pin these objects.

This has the detrimental effect of marking these references on every
minors even though it's a mostly append only list.

But using a custom TypedData we can save from having to mark
all the references on minor GC runs.

Addtionally, immediate values are now ignored and not appended
to `vm-&gt;mark_object_ary` as it's just wasted space.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This `st_table` is used to both mark and pin classes
defined from the C API. But `vm-&gt;mark_object_ary` already
does both much more efficiently.

Currently a Ruby process starts with 252 rooted classes,
which uses `7224B` in an `st_table` or `2016B` in an `RArray`.

So a baseline of 5kB saved, but since `mark_object_ary` is
preallocated with `1024` slots but only use `405` of them,
it's a net `7kB` save.

`vm-&gt;mark_object_ary` is also being refactored.

Prior to this changes, `mark_object_ary` was a regular `RArray`, but
since this allows for references to be moved, it was marked a second
time from `rb_vm_mark()` to pin these objects.

This has the detrimental effect of marking these references on every
minors even though it's a mostly append only list.

But using a custom TypedData we can save from having to mark
all the references on minor GC runs.

Addtionally, immediate values are now ignored and not appended
to `vm-&gt;mark_object_ary` as it's just wasted space.
</pre>
</div>
</content>
</entry>
<entry>
<title>Move FL_SINGLETON to FL_USER1</title>
<updated>2024-03-06T18:11:41+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>byroot@ruby-lang.org</email>
</author>
<published>2024-03-06T16:04:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b4a69351ec7d6f0a5e34e3bb586053814be352c0'/>
<id>b4a69351ec7d6f0a5e34e3bb586053814be352c0</id>
<content type='text'>
This frees FL_USER0 on both T_MODULE and T_CLASS.

Note: prior to this, FL_SINGLETON was never set on T_MODULE,
so checking for `FL_SINGLETON` without first checking that
`FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This frees FL_USER0 on both T_MODULE and T_CLASS.

Note: prior to this, FL_SINGLETON was never set on T_MODULE,
so checking for `FL_SINGLETON` without first checking that
`FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
</pre>
</div>
</content>
</entry>
<entry>
<title>Don't pin named structs defined in Ruby</title>
<updated>2024-03-01T07:23:38+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>byroot@ruby-lang.org</email>
</author>
<published>2024-02-29T12:17:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e626da82eae3d437b84d4f9ead0164d436b08e1a'/>
<id>e626da82eae3d437b84d4f9ead0164d436b08e1a</id>
<content type='text'>
[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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[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.
</pre>
</div>
</content>
</entry>
<entry>
<title>De-dup identical callinfo objects</title>
<updated>2024-02-21T02:55:00+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2024-02-12T05:43:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1c97abaabae6844c861705fd07f532292dcffa74'/>
<id>1c97abaabae6844c861705fd07f532292dcffa74</id>
<content type='text'>
Previously every call to vm_ci_new (when the CI was not packable) would
result in a different callinfo being returned this meant that every
kwarg callsite had its own CI.

When calling, different CIs result in different CCs. These CIs and CCs
both end up persisted on the T_CLASS inside cc_tbl. So in an eval loop
this resulted in a memory leak of both types of object. This also likely
resulted in extra memory used, and extra time searching, in non-eval
cases.

For simplicity in this commit I always allocate a CI object inside
rb_vm_ci_lookup, but ideally we would lazily allocate it only when
needed. I hope to do that as a follow up in the future.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously every call to vm_ci_new (when the CI was not packable) would
result in a different callinfo being returned this meant that every
kwarg callsite had its own CI.

When calling, different CIs result in different CCs. These CIs and CCs
both end up persisted on the T_CLASS inside cc_tbl. So in an eval loop
this resulted in a memory leak of both types of object. This also likely
resulted in extra memory used, and extra time searching, in non-eval
cases.

For simplicity in this commit I always allocate a CI object inside
rb_vm_ci_lookup, but ideally we would lazily allocate it only when
needed. I hope to do that as a follow up in the future.
</pre>
</div>
</content>
</entry>
<entry>
<title>Set m_tbl right after allocation</title>
<updated>2023-12-19T21:09:36+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2023-12-19T19:38:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=28a6e4ea9d9379a654a8f7c4b37fa33aa3ccd0b7'/>
<id>28a6e4ea9d9379a654a8f7c4b37fa33aa3ccd0b7</id>
<content type='text'>
We should set the m_tbl right after allocation before anything that can
trigger GC to avoid clone_p from becoming old and needing to fire write
barriers.

Co-authored-by: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We should set the m_tbl right after allocation before anything that can
trigger GC to avoid clone_p from becoming old and needing to fire write
barriers.

Co-authored-by: Aaron Patterson &lt;tenderlove@ruby-lang.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Don't try compacting ivars on Classes that are "too complex"</title>
<updated>2023-11-21T00:09:48+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2023-10-25T23:52:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6fce8c79807e69cfe475b5291e892567c869fbcc'/>
<id>6fce8c79807e69cfe475b5291e892567c869fbcc</id>
<content type='text'>
Too complex classes use a hash table to store ivs, and should always pin
their IVs.  We shouldn't touch those classes in compaction.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Too complex classes use a hash table to store ivs, and should always pin
their IVs.  We shouldn't touch those classes in compaction.
</pre>
</div>
</content>
</entry>
<entry>
<title>Avoid the pointer hack in RCLASS_EXT</title>
<updated>2023-10-15T06:35:45+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2023-10-15T05:53:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=591336a0f278bf963d01b6e9810cfc86a5b50620'/>
<id>591336a0f278bf963d01b6e9810cfc86a5b50620</id>
<content type='text'>
... because GCC 13 warns it.

```
In file included from class.c:24:
In function ‘RCLASS_SET_ALLOCATOR’,
    inlined from ‘class_alloc’ at class.c:251:5,
    inlined from ‘rb_module_s_alloc’ at class.c:1045:17:
internal/class.h:159:43: warning: array subscript 0 is outside array bounds of ‘rb_classext_t[0]’ {aka ‘struct rb_classext_struct[]’} [-Warray-bounds=]
  159 |     RCLASS_EXT(klass)-&gt;as.class.allocator = allocator;
      |                                           ^
```
https://rubyci.s3.amazonaws.com/arch/ruby-master/log/20231015T030003Z.log.html.gz
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
... because GCC 13 warns it.

```
In file included from class.c:24:
In function ‘RCLASS_SET_ALLOCATOR’,
    inlined from ‘class_alloc’ at class.c:251:5,
    inlined from ‘rb_module_s_alloc’ at class.c:1045:17:
internal/class.h:159:43: warning: array subscript 0 is outside array bounds of ‘rb_classext_t[0]’ {aka ‘struct rb_classext_struct[]’} [-Warray-bounds=]
  159 |     RCLASS_EXT(klass)-&gt;as.class.allocator = allocator;
      |                                           ^
```
https://rubyci.s3.amazonaws.com/arch/ruby-master/log/20231015T030003Z.log.html.gz
</pre>
</div>
</content>
</entry>
<entry>
<title>Stop exposing FrozenCore in headers</title>
<updated>2023-09-19T05:08:05+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2023-09-19T04:56:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4634405f7c7a7e0b5490ed3de35c12aad9c91bf5'/>
<id>4634405f7c7a7e0b5490ed3de35c12aad9c91bf5</id>
<content type='text'>
Revert commit "Directly allocate FrozenCore as an ICLASS",
813a5f4fc46a24ca1695d23c159250b9e1080ac7.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Revert commit "Directly allocate FrozenCore as an ICLASS",
813a5f4fc46a24ca1695d23c159250b9e1080ac7.
</pre>
</div>
</content>
</entry>
<entry>
<title>Prefer `0` over `NULL` as function pointers</title>
<updated>2023-06-22T18:15:55+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2023-06-22T18:15:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b934976024ef4e1694ec47158d94bce0f6d003b7'/>
<id>b934976024ef4e1694ec47158d94bce0f6d003b7</id>
<content type='text'>
SunC warns use of `NULL`, pointer to data as function pointers.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
SunC warns use of `NULL`, pointer to data as function pointers.</pre>
</div>
</content>
</entry>
</feed>
