<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/zjit/src/cruby_bindings.inc.rs, branch master</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Revert "Reserve 2 bits for expressing object layout (#17139)"</title>
<updated>2026-05-29T23:41:31+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2026-05-29T23:41:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ddb5055d961d970aded287cfebd07b78efee3ca7'/>
<id>ddb5055d961d970aded287cfebd07b78efee3ca7</id>
<content type='text'>
This reverts commit 63d9f090b5d9461cf0b9446e0039d9c56156b826.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 63d9f090b5d9461cf0b9446e0039d9c56156b826.
</pre>
</div>
</content>
</entry>
<entry>
<title>Reserve 2 bits for expressing object layout (#17139)</title>
<updated>2026-05-29T22:09:34+00:00</updated>
<author>
<name>Aaron Patterson</name>
<email>tenderlove@ruby-lang.org</email>
</author>
<published>2026-05-29T22:09:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=63d9f090b5d9461cf0b9446e0039d9c56156b826'/>
<id>63d9f090b5d9461cf0b9446e0039d9c56156b826</id>
<content type='text'>
* Reserve 2 bits for expressing object layout

We would like to make instance variable reads in the JIT compiler faster
(as well as simplify the JIT implementation).  Currently, in order to
read an instance variable, we have to:

1. Test for heap object
2. Load object to a 64 bit register
3. Mask the object header
4. Bit test against the masked header
5. JNE
6. Load field

We would like to:

1. Test for heap object
2. Load object shape to a 32 bit register
3. Bit test against the shape
4. JNE
5. Load field

The way we fetch instance variables is not consistent across objects.
In order to realize our goal, we need to encode object layout inside the
shape.  If we encode object layout inside the shape, then the shape
itself will guarantee that the access pattern generated by the JIT
compiler is correct.

We should encode the following load patterns into the shape tag bits.
This way we can share shapes on transitions, but be able to
differentiate the access patterns for the JIT compiler.  In other words,
two objects can have an `@a -&gt; @b -&gt; @c` transition and share the same
shape, but the tag bits can differentiate the access pattern so that the
JIT compiler can be confident that the machine code is correct.

Here are the patterns:

1. Embedded/Extended T_OBJECT Instance Variables

Objects with direct references to instance variables or via malloc
buffer

2. Objects with fields_objects fields

These are Data and TypedData objects.  They have an associated axillary
imemo/fields object that stores the instance variables.  The access
pattern is `object[2] + 2`.  The fields object is the 3rd field, and the
instance variables start at +2 inside the fields object.  The fields
object itself is a Ruby object, so it contains the usual header bits +
class headers.

3. Non Boxable Classes / Modules

This is similar to Objects with fields_objects, but the fields object is
stored at a different offset.  We’re differentiating this from boxable
classes and modules because those are harder to support.

4. Other

"Other" pattern is for objects that are rare, or have
difficult-to-implement access patterns.  This includes:

* Boxable classes and modules
* Structs (for now)
* Objects that use the geniv table

Proposed shape bit layout:

```
  Current shape_id_t is 32 bits:
  31        28 27 26 25 24 23 22        19 18                         0
  +-----------+--+--+--+--+--+------------+----------------------------+
  | unused    |L1|L0|OI|FR|CX| heap index | shape tree offset          |
  +-----------+--+--+--+--+--+------------+----------------------------+
               |  |  |  |  |  |            |
               |  |  |  |  |  |            +-- bits 0-18: SHAPE_ID_OFFSET_MASK
               |  |  |  |  |  +--------------- bits 19-22: SHAPE_ID_HEAP_INDEX_MASK
               |  |  |  |  +------------------ bit 23: SHAPE_ID_FL_COMPLEX
               |  |  |  +--------------------- bit 24: SHAPE_ID_FL_FROZEN
               |  |  +------------------------ bit 25: SHAPE_ID_FL_HAS_OBJECT_ID
               +--+--------------------------- bits 26-27: SHAPE_ID_LAYOUT_MASK
```

The important part about these layout patterns is that they do not
reflect the _type_ of object, only how the object is laid out in memory.
For example, we currently treat structs as "other", but we can refactor
them to have the same layout as "Objects with fields_objects", and when
we do that they should get a different bit in the shape header.

This commit only reserves the two bits, it doesn't use them in the JIT
compiler yet.

Co-Authored-By: John Hawthorn &lt;john@hawthorn.email&gt;
Co-Authored-By: Max Bernstein &lt;tekknolagi@gmail.com&gt;

* Update gc.c

Co-authored-by: Nobuyoshi Nakada &lt;nobu.nakada@gmail.com&gt;

* Update shape.h

Co-authored-by: Jean Boussier &lt;jean.boussier@gmail.com&gt;

* fix function name

* Update shape.c

Co-authored-by: Jean Boussier &lt;jean.boussier@gmail.com&gt;

* fix function name

* Revert "Update shape.c"

This reverts commit 900711defc6c541a93f3393a350819ae88cf87f1.

* add comment

---------

Co-authored-by: John Hawthorn &lt;john@hawthorn.email&gt;
Co-authored-by: Max Bernstein &lt;tekknolagi@gmail.com&gt;
Co-authored-by: Nobuyoshi Nakada &lt;nobu.nakada@gmail.com&gt;
Co-authored-by: Jean Boussier &lt;jean.boussier@gmail.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Reserve 2 bits for expressing object layout

We would like to make instance variable reads in the JIT compiler faster
(as well as simplify the JIT implementation).  Currently, in order to
read an instance variable, we have to:

1. Test for heap object
2. Load object to a 64 bit register
3. Mask the object header
4. Bit test against the masked header
5. JNE
6. Load field

We would like to:

1. Test for heap object
2. Load object shape to a 32 bit register
3. Bit test against the shape
4. JNE
5. Load field

The way we fetch instance variables is not consistent across objects.
In order to realize our goal, we need to encode object layout inside the
shape.  If we encode object layout inside the shape, then the shape
itself will guarantee that the access pattern generated by the JIT
compiler is correct.

We should encode the following load patterns into the shape tag bits.
This way we can share shapes on transitions, but be able to
differentiate the access patterns for the JIT compiler.  In other words,
two objects can have an `@a -&gt; @b -&gt; @c` transition and share the same
shape, but the tag bits can differentiate the access pattern so that the
JIT compiler can be confident that the machine code is correct.

Here are the patterns:

1. Embedded/Extended T_OBJECT Instance Variables

Objects with direct references to instance variables or via malloc
buffer

2. Objects with fields_objects fields

These are Data and TypedData objects.  They have an associated axillary
imemo/fields object that stores the instance variables.  The access
pattern is `object[2] + 2`.  The fields object is the 3rd field, and the
instance variables start at +2 inside the fields object.  The fields
object itself is a Ruby object, so it contains the usual header bits +
class headers.

3. Non Boxable Classes / Modules

This is similar to Objects with fields_objects, but the fields object is
stored at a different offset.  We’re differentiating this from boxable
classes and modules because those are harder to support.

4. Other

"Other" pattern is for objects that are rare, or have
difficult-to-implement access patterns.  This includes:

* Boxable classes and modules
* Structs (for now)
* Objects that use the geniv table

Proposed shape bit layout:

```
  Current shape_id_t is 32 bits:
  31        28 27 26 25 24 23 22        19 18                         0
  +-----------+--+--+--+--+--+------------+----------------------------+
  | unused    |L1|L0|OI|FR|CX| heap index | shape tree offset          |
  +-----------+--+--+--+--+--+------------+----------------------------+
               |  |  |  |  |  |            |
               |  |  |  |  |  |            +-- bits 0-18: SHAPE_ID_OFFSET_MASK
               |  |  |  |  |  +--------------- bits 19-22: SHAPE_ID_HEAP_INDEX_MASK
               |  |  |  |  +------------------ bit 23: SHAPE_ID_FL_COMPLEX
               |  |  |  +--------------------- bit 24: SHAPE_ID_FL_FROZEN
               |  |  +------------------------ bit 25: SHAPE_ID_FL_HAS_OBJECT_ID
               +--+--------------------------- bits 26-27: SHAPE_ID_LAYOUT_MASK
```

The important part about these layout patterns is that they do not
reflect the _type_ of object, only how the object is laid out in memory.
For example, we currently treat structs as "other", but we can refactor
them to have the same layout as "Objects with fields_objects", and when
we do that they should get a different bit in the shape header.

This commit only reserves the two bits, it doesn't use them in the JIT
compiler yet.

Co-Authored-By: John Hawthorn &lt;john@hawthorn.email&gt;
Co-Authored-By: Max Bernstein &lt;tekknolagi@gmail.com&gt;

* Update gc.c

Co-authored-by: Nobuyoshi Nakada &lt;nobu.nakada@gmail.com&gt;

* Update shape.h

Co-authored-by: Jean Boussier &lt;jean.boussier@gmail.com&gt;

* fix function name

* Update shape.c

Co-authored-by: Jean Boussier &lt;jean.boussier@gmail.com&gt;

* fix function name

* Revert "Update shape.c"

This reverts commit 900711defc6c541a93f3393a350819ae88cf87f1.

* add comment

---------

Co-authored-by: John Hawthorn &lt;john@hawthorn.email&gt;
Co-authored-by: Max Bernstein &lt;tekknolagi@gmail.com&gt;
Co-authored-by: Nobuyoshi Nakada &lt;nobu.nakada@gmail.com&gt;
Co-authored-by: Jean Boussier &lt;jean.boussier@gmail.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>Rename RUBY_FL_USERPRIV0 into RUBY_FL_UNUSED6</title>
<updated>2026-05-29T05:25:03+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2026-05-28T17:40:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4af6e12493a04ff9cf11e2ae08404ec56fbd8e94'/>
<id>4af6e12493a04ff9cf11e2ae08404ec56fbd8e94</id>
<content type='text'>
Last usage was removed in a26f528b3bf1eaecff18520f6ba8083c9c0cbf73
https://github.com/ruby/ruby/pull/15447
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Last usage was removed in a26f528b3bf1eaecff18520f6ba8083c9c0cbf73
https://github.com/ruby/ruby/pull/15447
</pre>
</div>
</content>
</entry>
<entry>
<title>Deprecate `struct RData` in favor of `struct RTypedData`</title>
<updated>2026-05-28T10:29:31+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2025-12-08T07:12:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a26f528b3bf1eaecff18520f6ba8083c9c0cbf73'/>
<id>a26f528b3bf1eaecff18520f6ba8083c9c0cbf73</id>
<content type='text'>
For the backward compatibility for some wrapper generator gems, keep
only `RData` definition.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For the backward compatibility for some wrapper generator gems, keep
only `RData` definition.
</pre>
</div>
</content>
</entry>
<entry>
<title>Treat all T_DATA the same in zjit</title>
<updated>2026-05-27T23:18:43+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2026-05-25T17:30:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c195319c0d66e12356d94de9075ff5070c51d37f'/>
<id>c195319c0d66e12356d94de9075ff5070c51d37f</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>ZJIT: Delete binding for unused rb_reg_new_ary()</title>
<updated>2026-05-26T17:04:22+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2026-05-23T20:11:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b1bf8f31ca1ae1f784c3d3319090e1360177b109'/>
<id>b1bf8f31ca1ae1f784c3d3319090e1360177b109</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>ZJIT: Call only one function for newhash/toregexp (#17092)</title>
<updated>2026-05-23T00:08:49+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-05-23T00:08:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=5855d61ee4c44a4e1b9a6244fb4a3dc7caafa7bf'/>
<id>5855d61ee4c44a4e1b9a6244fb4a3dc7caafa7bf</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Use atomics for kwargs reference count</title>
<updated>2026-05-20T16:48:55+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2026-05-20T09:48:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cb9f2ba8046b10de6b4fa0ff364a8e9d09235d00'/>
<id>cb9f2ba8046b10de6b4fa0ff364a8e9d09235d00</id>
<content type='text'>
Fixes [Bug #22075]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes [Bug #22075]
</pre>
</div>
</content>
</entry>
<entry>
<title>Use IMEMO to store `cdhash`</title>
<updated>2026-05-18T05:58:32+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2026-05-17T12:40:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=99dc513d155484a1291394e953a5cdfd6dab92e1'/>
<id>99dc513d155484a1291394e953a5cdfd6dab92e1</id>
<content type='text'>
RHash isn't a good fit for storing `cdhash` as this force to allow
arbitrary hash types into RHash, which doesn't work with AR tables.

It also cause the cdhash to be larger than needed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
RHash isn't a good fit for storing `cdhash` as this force to allow
arbitrary hash types into RHash, which doesn't work with AR tables.

It also cause the cdhash to be larger than needed.
</pre>
</div>
</content>
</entry>
<entry>
<title>ZJIT: Share a single JITFrame across all C method frames (#16988)</title>
<updated>2026-05-15T19:44:42+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2026-05-15T19:44:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=985fa1bdaa23d2c84aebb7db55b674c0b9993f57'/>
<id>985fa1bdaa23d2c84aebb7db55b674c0b9993f57</id>
<content type='text'>
* ZJIT: Share a single JITFrame across all C method frames

Replace the per-call JITFrame::new_cfunc allocation in gen_push_frame
with a sentinel value (ZJIT_JIT_RETURN_C_FRAME) stored in cfp-&gt;jit_return.
CFP_ZJIT_FRAME now returns a pointer to a single static rb_zjit_c_frame
(pc/iseq both NULL) when it sees the sentinel.

The CFP accessor is split into CFP_ZJIT_FRAME_P (predicate) and
CFP_ZJIT_FRAME (typed accessor that dereferences safely) so callers don't
have to know about the sentinel encoding. ISEQ frames are unchanged: they
still hand cfp-&gt;jit_return a heap-allocated JITFrame pointer.

* Move a pointer location for CFP_ZJIT_FRAME</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* ZJIT: Share a single JITFrame across all C method frames

Replace the per-call JITFrame::new_cfunc allocation in gen_push_frame
with a sentinel value (ZJIT_JIT_RETURN_C_FRAME) stored in cfp-&gt;jit_return.
CFP_ZJIT_FRAME now returns a pointer to a single static rb_zjit_c_frame
(pc/iseq both NULL) when it sees the sentinel.

The CFP accessor is split into CFP_ZJIT_FRAME_P (predicate) and
CFP_ZJIT_FRAME (typed accessor that dereferences safely) so callers don't
have to know about the sentinel encoding. ISEQ frames are unchanged: they
still hand cfp-&gt;jit_return a heap-allocated JITFrame pointer.

* Move a pointer location for CFP_ZJIT_FRAME</pre>
</div>
</content>
</entry>
</feed>
