<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/yjit/src/invariants.rs, branch v4.0.4</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>YJIT: Fix not reading locals from `cfp-&gt;ep` after `YJIT.enable` and exceptional entry</title>
<updated>2026-03-16T18:03:25+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2026-03-12T22:33:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8466e93b1d6eb85ad5952ab3a10575fa453e77e2'/>
<id>8466e93b1d6eb85ad5952ab3a10575fa453e77e2</id>
<content type='text'>
[Backport #21941]

In case of `--yjit-disable`, YJIT only starts to record environment
escapes after `RubyVM::YJIT.enable`. Previously we falsely assumed that
we always have a full history all the way back to VM boot. This had YJIT
install and run code that assume EP=BP when EP≠BP for some exceptional
entry into the middle of a running frame, if the environment escaped
before `YJIT.enable`.

The fix is to reject exceptional entry with an escaped environment.
Rename things and explain in more detail how the predicate for deciding
to assume EP=BP works. It's quite subtle since it reasons about all
parties in the system that push a control frame and then run JIT code.

Note that while can_assume_on_stack_env() checks the currently running
environment if it so happens to be the one YJIT is compiling against, it
can return true for any ISEQ. The check isn't necessary for fixing the
bug, and the load bearing part of this patch is the change to
exceptional entries.

This fix is flat on speed and space on ruby-bench headline benchmarks.

Many thanks for the community effort to create a small test case for
this bug.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Backport #21941]

In case of `--yjit-disable`, YJIT only starts to record environment
escapes after `RubyVM::YJIT.enable`. Previously we falsely assumed that
we always have a full history all the way back to VM boot. This had YJIT
install and run code that assume EP=BP when EP≠BP for some exceptional
entry into the middle of a running frame, if the environment escaped
before `YJIT.enable`.

The fix is to reject exceptional entry with an escaped environment.
Rename things and explain in more detail how the predicate for deciding
to assume EP=BP works. It's quite subtle since it reasons about all
parties in the system that push a control frame and then run JIT code.

Note that while can_assume_on_stack_env() checks the currently running
environment if it so happens to be the one YJIT is compiling against, it
can return true for any ISEQ. The check isn't necessary for fixing the
bug, and the load bearing part of this patch is the change to
exceptional entries.

This fix is flat on speed and space on ruby-bench headline benchmarks.

Many thanks for the community effort to create a small test case for
this bug.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add rb_jit_multi_ractor_p and share it in ZJIT and YJIT</title>
<updated>2025-08-29T19:55:14+00:00</updated>
<author>
<name>Stan Lo</name>
<email>stan.lo@shopify.com</email>
</author>
<published>2025-08-29T18:03:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2f6a9c51670dd6dcc1cae52e4a793143fb148eb6'/>
<id>2f6a9c51670dd6dcc1cae52e4a793143fb148eb6</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>ZJIT: Implement SingleRactorMode invalidation (#14121)</title>
<updated>2025-08-06T20:51:41+00:00</updated>
<author>
<name>Stan Lo</name>
<email>stan.lo@shopify.com</email>
</author>
<published>2025-08-06T20:51:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4a70f946a7131da871ca2aef8256a8b94299eba6'/>
<id>4a70f946a7131da871ca2aef8256a8b94299eba6</id>
<content type='text'>
* ZJIT: Implement SingleRactorMode invalidation

* ZJIT: Add macro for compiling jumps

* ZJIT: Fix typo in comment

* YJIT: Fix typo in comment

* ZJIT: Avoid using unexported types in zjit.h

`enum ruby_vminsn_type` is declared in `insns.inc` and is not exported.
Using it in `zjit.h` would cause build errors when the file including it
doesn't include `insns.inc`.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* ZJIT: Implement SingleRactorMode invalidation

* ZJIT: Add macro for compiling jumps

* ZJIT: Fix typo in comment

* YJIT: Fix typo in comment

* ZJIT: Avoid using unexported types in zjit.h

`enum ruby_vminsn_type` is declared in `insns.inc` and is not exported.
Using it in `zjit.h` would cause build errors when the file including it
doesn't include `insns.inc`.</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Add Counter::invalidate_everything</title>
<updated>2025-03-08T01:23:32+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2025-03-07T22:42:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=98790faae3cbbe67a5335df30f6e9000f3a83ad9'/>
<id>98790faae3cbbe67a5335df30f6e9000f3a83ad9</id>
<content type='text'>
When YJIT is forced to discard all the code, that's bad for
performance, so there should be an easy way to know about it.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When YJIT is forced to discard all the code, that's bad for
performance, so there should be an easy way to know about it.
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Speed up block_assumptions_free (#11556)</title>
<updated>2024-09-05T19:39:57+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-09-05T19:39:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f250296efaa7ea3e929eeaecfecd29e5cfe13de3'/>
<id>f250296efaa7ea3e929eeaecfecd29e5cfe13de3</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Make YJIT a GC root rather than an object (#11343)</title>
<updated>2024-08-08T16:19:35+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2024-08-08T16:19:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0bff07644ba5aff9c844b6cf75a0e1365c35c6a3'/>
<id>0bff07644ba5aff9c844b6cf75a0e1365c35c6a3</id>
<content type='text'>
YJIT currently uses the YJIT root object to mark objects during GC and
update references during compaction. This object otherwise serves no
purpose.

This commit changes it YJIT to be step when marking the GC root. This
saves some memory from being allocated from the system and the GC.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
YJIT currently uses the YJIT root object to mark objects during GC and
update references during compaction. This object otherwise serves no
purpose.

This commit changes it YJIT to be step when marking the GC root. This
saves some memory from being allocated from the system and the GC.</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Local variable register allocation (#11157)</title>
<updated>2024-07-15T14:56:57+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-07-15T14:56:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ec773e15f472ae2fe655529ea646d8fb2a4f0919'/>
<id>ec773e15f472ae2fe655529ea646d8fb2a4f0919</id>
<content type='text'>
* YJIT: Local variable register allocation

* locals are not stack temps

* Rename RegTemps to RegMappings

* Rename RegMapping to RegOpnd

* Rename local_size to num_locals

* s/stack value/operand/

* Rename spill_temps() to spill_regs()

* Clarify when num_locals becomes None

* Mention that InsnOut uses different registers

* Rename get_reg_mapping to get_reg_opnd

* Resurrect --yjit-temp-regs capability

* Use MAX_CTX_TEMPS and MAX_CTX_LOCALS</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* YJIT: Local variable register allocation

* locals are not stack temps

* Rename RegTemps to RegMappings

* Rename RegMapping to RegOpnd

* Rename local_size to num_locals

* s/stack value/operand/

* Rename spill_temps() to spill_regs()

* Clarify when num_locals becomes None

* Mention that InsnOut uses different registers

* Rename get_reg_mapping to get_reg_opnd

* Resurrect --yjit-temp-regs capability

* Use MAX_CTX_TEMPS and MAX_CTX_LOCALS</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Move `ocb` parameters into `JITState`</title>
<updated>2024-06-28T15:01:05+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-06-20T22:14:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=bc91e8ff1db329e194f3d9706d94d5261090901d'/>
<id>bc91e8ff1db329e194f3d9706d94d5261090901d</id>
<content type='text'>
Many functions take an outlined code block but do nothing more than
passing it along; only a couple of functions actually make use of it.
So, in most cases the `ocb` parameter is just boilerplate.

Most functions that take `ocb` already also take a `JITState` and this
commit moves `ocb` into `JITState` to remove the visual noise of the
`ocb` parameter.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Many functions take an outlined code block but do nothing more than
passing it along; only a couple of functions actually make use of it.
So, in most cases the `ocb` parameter is just boilerplate.

Most functions that take `ocb` already also take a `JITState` and this
commit moves `ocb` into `JITState` to remove the visual noise of the
`ocb` parameter.
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Fix comment and counter in rb_yjit_invalidate_ep_is_bp() (#10722)</title>
<updated>2024-05-06T14:28:36+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-05-06T14:28:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1df1edc080031b8f18b41a5a8d308a667ea89fc1'/>
<id>1df1edc080031b8f18b41a5a8d308a667ea89fc1</id>
<content type='text'>
`mem::take` substitutes an empty instance which makes `jit.ep_is_bp()`
return false.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`mem::take` substitutes an empty instance which makes `jit.ep_is_bp()`
return false.</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Take VM lock when invalidating</title>
<updated>2024-04-29T20:08:06+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-04-29T20:08:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=de0ad3be8ee0ac3b1f8e97dae934e82951721061'/>
<id>de0ad3be8ee0ac3b1f8e97dae934e82951721061</id>
<content type='text'>
We need the lock to patch code safely.
This might fix some Ractor related crashes seen on CI.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We need the lock to patch code safely.
This might fix some Ractor related crashes seen on CI.</pre>
</div>
</content>
</entry>
</feed>
