<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/internal/gc.h, branch v4.0.3</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Handle NEWOBJ tracepoints settings fields</title>
<updated>2025-12-03T07:14:56+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-11-25T14:06:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8c3909935e2ba9f79bf3492772c77c305a0d370b'/>
<id>8c3909935e2ba9f79bf3492772c77c305a0d370b</id>
<content type='text'>
[Bug #21710]

- struct.c: `struct_alloc`

It is possible for a `NEWOBJ` tracepoint call back to write fields
into a newly allocated object before `struct_alloc` had the time
to set the `RSTRUCT_GEN_FIELDS` flags and such.

Hence we can't blindly initialize the `fields_obj` reference to `0`
we first need to check no fields were added yet.

- object.c: `rb_class_allocate_instance`

Similarly, if a `NEWOBJ` tracepoint tries to set fields on the object,
the `shape_id` must already be set, as it's required on T_OBJECT to
know where to write fields.

`NEWOBJ_OF` had to be refactored to accept a `shape_id`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #21710]

- struct.c: `struct_alloc`

It is possible for a `NEWOBJ` tracepoint call back to write fields
into a newly allocated object before `struct_alloc` had the time
to set the `RSTRUCT_GEN_FIELDS` flags and such.

Hence we can't blindly initialize the `fields_obj` reference to `0`
we first need to check no fields were added yet.

- object.c: `rb_class_allocate_instance`

Similarly, if a `NEWOBJ` tracepoint tries to set fields on the object,
the `shape_id` must already be set, as it's required on T_OBJECT to
know where to write fields.

`NEWOBJ_OF` had to be refactored to accept a `shape_id`.
</pre>
</div>
</content>
</entry>
<entry>
<title>use `SET_SHAREABLE`</title>
<updated>2025-10-23T04:08:26+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2025-09-24T20:50:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=bc00c4468e0054ca896d2b83d3020180915f64cf'/>
<id>bc00c4468e0054ca896d2b83d3020180915f64cf</id>
<content type='text'>
to adopt strict shareable rule.

* (basically) shareable objects only refer shareable objects
* (exception) shareable objects can refere unshareable objects
  but should not leak reference to unshareable objects to Ruby world
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
to adopt strict shareable rule.

* (basically) shareable objects only refer shareable objects
* (exception) shareable objects can refere unshareable objects
  but should not leak reference to unshareable objects to Ruby world
</pre>
</div>
</content>
</entry>
<entry>
<title>add SET_SHAREABLE macros</title>
<updated>2025-10-23T04:08:26+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2025-09-23T17:34:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=45907b1b00d09ce2c40f5073ff540d8b63217d96'/>
<id>45907b1b00d09ce2c40f5073ff540d8b63217d96</id>
<content type='text'>
* `RB_OBJ_SET_SHAREABLE(obj)` makes obj shareable.
  All of reachable objects from `obj` should be shareable.
* `RB_OBJ_SET_FROZEN_SHAREABLE(obj)` same as above
  but freeze `obj` before making it shareable.

Also `rb_gc_verify_shareable(obj)` is introduced to check
the `obj` does not violate shareable rule (an shareable object
only refers shareable objects) strictly.

The rule has some exceptions (some shareable objects can refer to
unshareable objects, such as a Ractor object (which is a shareable
object) can refer to the Ractor local objects.
To handle such case, `check_shareable` flag is also introduced.

`STRICT_VERIFY_SHAREABLE` macro is also introduced to verify
the strict shareable rule at `SET_SHAREABLE`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* `RB_OBJ_SET_SHAREABLE(obj)` makes obj shareable.
  All of reachable objects from `obj` should be shareable.
* `RB_OBJ_SET_FROZEN_SHAREABLE(obj)` same as above
  but freeze `obj` before making it shareable.

Also `rb_gc_verify_shareable(obj)` is introduced to check
the `obj` does not violate shareable rule (an shareable object
only refers shareable objects) strictly.

The rule has some exceptions (some shareable objects can refer to
unshareable objects, such as a Ractor object (which is a shareable
object) can refer to the Ractor local objects.
To handle such case, `check_shareable` flag is also introduced.

`STRICT_VERIFY_SHAREABLE` macro is also introduced to verify
the strict shareable rule at `SET_SHAREABLE`.
</pre>
</div>
</content>
</entry>
<entry>
<title>imemo_fields_set: save copying when reassigning a variable</title>
<updated>2025-07-03T07:20:22+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-07-02T11:10:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=517c1067098957a7ad73cd611072f8d769db8139'/>
<id>517c1067098957a7ad73cd611072f8d769db8139</id>
<content type='text'>
If we still fit in the existing imemo/fields object we can
update it atomically, saving a reallocation.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If we still fit in the existing imemo/fields object we can
update it atomically, saving a reallocation.
</pre>
</div>
</content>
</entry>
<entry>
<title>Move `object_id` in object fields.</title>
<updated>2025-05-08T05:58:05+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-04-21T07:16:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f48e45d1e9c4412d5f3ee49241d0b9359651ce7c'/>
<id>f48e45d1e9c4412d5f3ee49241d0b9359651ce7c</id>
<content type='text'>
And get rid of the `obj_to_id_tbl`

It's no longer needed, the `object_id` is now stored inline
in the object alongside instance variables.

We still need the inverse table in case `_id2ref` is invoked, but
we lazily build it by walking the heap if that happens.

The `object_id` concern is also no longer a GC implementation
concern, but a generic implementation.

Co-Authored-By: Matt Valentine-House &lt;matt@eightbitraptor.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
And get rid of the `obj_to_id_tbl`

It's no longer needed, the `object_id` is now stored inline
in the object alongside instance variables.

We still need the inverse table in case `_id2ref` is invoked, but
we lazily build it by walking the heap if that happens.

The `object_id` concern is also no longer a GC implementation
concern, but a generic implementation.

Co-Authored-By: Matt Valentine-House &lt;matt@eightbitraptor.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Ractor: revert to moving object bytes, but size pool aware</title>
<updated>2025-04-04T14:26:29+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-04-04T11:28:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=085cc6e43473f2a3c81311a07c1fc8efa46c118b'/>
<id>085cc6e43473f2a3c81311a07c1fc8efa46c118b</id>
<content type='text'>
Using `rb_obj_clone` introduce other problems, such as `initialize_*`
callbacks invocation in the context of the parent ractor.

So we can revert back to copy the content of the object slots,
but in a way that is aware of size pools.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Using `rb_obj_clone` introduce other problems, such as `initialize_*`
callbacks invocation in the context of the parent ractor.

So we can revert back to copy the content of the object slots,
but in a way that is aware of size pools.
</pre>
</div>
</content>
</entry>
<entry>
<title>Ractor: Fix moving embedded objects</title>
<updated>2025-03-31T10:01:55+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2025-03-27T13:26:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0350290262ea0fbc4e1807901797ee8a6970c2b9'/>
<id>0350290262ea0fbc4e1807901797ee8a6970c2b9</id>
<content type='text'>
[Bug #20271]
[Bug #20267]
[Bug #20255]

`rb_obj_alloc(RBASIC_CLASS(obj))` will always allocate from the basic
40B pool, so if `obj` is larger than `40B`, we'll create a corrupted
object when we later copy the shape_id.

Instead we can use the same logic than ractor copy, which is
to use `rb_obj_clone`, and later ask the GC to free the original
object.

We then must turn it into a `T_OBJECT`, because otherwise
just changing its class to `RactorMoved` leaves a lot of
ways to keep using the object, e.g.:

```
a = [1, 2, 3]
Ractor.new{}.send(a, move: true)
[].concat(a) # Should raise, but wasn't.
```

If it turns out that `rb_obj_clone` isn't performant enough
for some uses, we can always have carefully crafted specialized
paths for the types that would benefit from it.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #20271]
[Bug #20267]
[Bug #20255]

`rb_obj_alloc(RBASIC_CLASS(obj))` will always allocate from the basic
40B pool, so if `obj` is larger than `40B`, we'll create a corrupted
object when we later copy the shape_id.

Instead we can use the same logic than ractor copy, which is
to use `rb_obj_clone`, and later ask the GC to free the original
object.

We then must turn it into a `T_OBJECT`, because otherwise
just changing its class to `RactorMoved` leaves a lot of
ways to keep using the object, e.g.:

```
a = [1, 2, 3]
Ractor.new{}.send(a, move: true)
[].concat(a) # Should raise, but wasn't.
```

If it turns out that `rb_obj_clone` isn't performant enough
for some uses, we can always have carefully crafted specialized
paths for the types that would benefit from it.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add rb_gc_object_metadata API</title>
<updated>2025-02-19T14:47:28+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-02-18T17:58:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7b6e07ea93cfc42bfb8bdf875555d2c8c7d5e507'/>
<id>7b6e07ea93cfc42bfb8bdf875555d2c8c7d5e507</id>
<content type='text'>
This function replaces the internal rb_obj_gc_flags API. rb_gc_object_metadata
returns an array of name and value pairs, with the last element having
0 for the name.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This function replaces the internal rb_obj_gc_flags API. rb_gc_object_metadata
returns an array of name and value pairs, with the last element having
0 for the name.
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove stale declaration for modular GC</title>
<updated>2025-01-10T16:22:26+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-01-10T16:22:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4a2702dafb0852d7a7575fd4c7717402f02ccc25'/>
<id>4a2702dafb0852d7a7575fd4c7717402f02ccc25</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Check whether object is valid in allocation_info_tracer_compact</title>
<updated>2024-12-16T17:24:24+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2024-12-16T16:41:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=516a6cd1ad620b880651c1333bd856a9d7dec3c4'/>
<id>516a6cd1ad620b880651c1333bd856a9d7dec3c4</id>
<content type='text'>
When reference updating ObjectSpace.trace_object_allocations, we need to
check whether the object is valid or not because it does not mark the
object so the object may be dead. This can cause a segmentation fault
if the object is on a free heap page.

For example, the following script crashes:

    require "objspace"

    objs = []
    ObjectSpace.trace_object_allocations do
      1_000_000.times do
        objs &lt;&lt; Object.new
      end
    end

    objs = nil

    # Free pages that the objs were on
    GC.start

    # Run compaction and check that it doesn't crash
    GC.compact
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When reference updating ObjectSpace.trace_object_allocations, we need to
check whether the object is valid or not because it does not mark the
object so the object may be dead. This can cause a segmentation fault
if the object is on a free heap page.

For example, the following script crashes:

    require "objspace"

    objs = []
    ObjectSpace.trace_object_allocations do
      1_000_000.times do
        objs &lt;&lt; Object.new
      end
    end

    objs = nil

    # Free pages that the objs were on
    GC.start

    # Run compaction and check that it doesn't crash
    GC.compact
</pre>
</div>
</content>
</entry>
</feed>
