<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/yjit/src/yjit.rs, 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>YJIT: track time since initialization (#12263)</title>
<updated>2024-12-04T21:24:36+00:00</updated>
<author>
<name>Maxime Chevalier-Boisvert</name>
<email>maxime.chevalierboisvert@shopify.com</email>
</author>
<published>2024-12-04T21:24:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4b4d52ef50a926f0af6eeb3423c8e0e44603cd26'/>
<id>4b4d52ef50a926f0af6eeb3423c8e0e44603cd26</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix false-positive memory leak using Valgrind in YJIT (#12057)</title>
<updated>2024-11-11T20:45:11+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2024-11-11T20:45:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1d1c80e6443e21a7e10d9d4987b0deb1ef8ec374'/>
<id>1d1c80e6443e21a7e10d9d4987b0deb1ef8ec374</id>
<content type='text'>
When we run with RUBY_FREE_AT_EXIT, there's a false-positive memory leak
reported in YJIT because the METHOD_CODEGEN_TABLE is never freed. This
commit adds rb_yjit_free_at_exit that is called at shutdown when
RUBY_FREE_AT_EXIT is set.

Reported memory leak:

    ==699816== 1,104 bytes in 1 blocks are possibly lost in loss record 1 of 1
    ==699816==    at 0x484680F: malloc (vg_replace_malloc.c:446)
    ==699816==    by 0x155B3E: UnknownInlinedFun (unix.rs:14)
    ==699816==    by 0x155B3E: UnknownInlinedFun (stats.rs:36)
    ==699816==    by 0x155B3E: UnknownInlinedFun (stats.rs:27)
    ==699816==    by 0x155B3E: alloc (alloc.rs:98)
    ==699816==    by 0x155B3E: alloc_impl (alloc.rs:181)
    ==699816==    by 0x155B3E: allocate (alloc.rs:241)
    ==699816==    by 0x155B3E: do_alloc&lt;alloc::alloc::Global&gt; (alloc.rs:15)
    ==699816==    by 0x155B3E: new_uninitialized&lt;alloc::alloc::Global&gt; (mod.rs:1750)
    ==699816==    by 0x155B3E: fallible_with_capacity&lt;alloc::alloc::Global&gt; (mod.rs:1788)
    ==699816==    by 0x155B3E: prepare_resize&lt;alloc::alloc::Global&gt; (mod.rs:2864)
    ==699816==    by 0x155B3E: resize_inner&lt;alloc::alloc::Global&gt; (mod.rs:3060)
    ==699816==    by 0x155B3E: reserve_rehash_inner&lt;alloc::alloc::Global&gt; (mod.rs:2950)
    ==699816==    by 0x155B3E: hashbrown::raw::RawTable&lt;T,A&gt;::reserve_rehash (mod.rs:1231)
    ==699816==    by 0x5BC39F: UnknownInlinedFun (mod.rs:1179)
    ==699816==    by 0x5BC39F: find_or_find_insert_slot&lt;(usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool), alloc::alloc::Global, hashbrown::map::equivalent_key::{closure_env#0}&lt;usize, usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool&gt;, hashbrown::map::make_hasher::{closure_env#0}&lt;usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool, std::hash::random::RandomState&gt;&gt; (mod.rs:1413)
    ==699816==    by 0x5BC39F: hashbrown::map::HashMap&lt;K,V,S,A&gt;::insert (map.rs:1754)
    ==699816==    by 0x57C5C6: insert&lt;usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool, std::hash::random::RandomState&gt; (map.rs:1104)
    ==699816==    by 0x57C5C6: yjit::codegen::reg_method_codegen (codegen.rs:10521)
    ==699816==    by 0x57C295: yjit::codegen::yjit_reg_method_codegen_fns (codegen.rs:10464)
    ==699816==    by 0x5C6B07: rb_yjit_init (yjit.rs:40)
    ==699816==    by 0x393723: ruby_opt_init (ruby.c:1820)
    ==699816==    by 0x393723: ruby_opt_init (ruby.c:1767)
    ==699816==    by 0x3957D4: prism_script (ruby.c:2215)
    ==699816==    by 0x3957D4: process_options (ruby.c:2538)
    ==699816==    by 0x396065: ruby_process_options (ruby.c:3166)
    ==699816==    by 0x236E56: ruby_options (eval.c:117)
    ==699816==    by 0x15BAED: rb_main (main.c:43)
    ==699816==    by 0x15BAED: main (main.c:62)

After this patch, there are no more memory leaks reported when running
RUBY_FREE_AT_EXIT with Valgrind on an empty Ruby script:

    $ RUBY_FREE_AT_EXIT=1 valgrind --leak-check=full ruby -e ""
    ...
    ==700357== HEAP SUMMARY:
    ==700357==     in use at exit: 0 bytes in 0 blocks
    ==700357==   total heap usage: 36,559 allocs, 36,559 frees, 6,064,783 bytes allocated
    ==700357==
    ==700357== All heap blocks were freed -- no leaks are possible</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When we run with RUBY_FREE_AT_EXIT, there's a false-positive memory leak
reported in YJIT because the METHOD_CODEGEN_TABLE is never freed. This
commit adds rb_yjit_free_at_exit that is called at shutdown when
RUBY_FREE_AT_EXIT is set.

Reported memory leak:

    ==699816== 1,104 bytes in 1 blocks are possibly lost in loss record 1 of 1
    ==699816==    at 0x484680F: malloc (vg_replace_malloc.c:446)
    ==699816==    by 0x155B3E: UnknownInlinedFun (unix.rs:14)
    ==699816==    by 0x155B3E: UnknownInlinedFun (stats.rs:36)
    ==699816==    by 0x155B3E: UnknownInlinedFun (stats.rs:27)
    ==699816==    by 0x155B3E: alloc (alloc.rs:98)
    ==699816==    by 0x155B3E: alloc_impl (alloc.rs:181)
    ==699816==    by 0x155B3E: allocate (alloc.rs:241)
    ==699816==    by 0x155B3E: do_alloc&lt;alloc::alloc::Global&gt; (alloc.rs:15)
    ==699816==    by 0x155B3E: new_uninitialized&lt;alloc::alloc::Global&gt; (mod.rs:1750)
    ==699816==    by 0x155B3E: fallible_with_capacity&lt;alloc::alloc::Global&gt; (mod.rs:1788)
    ==699816==    by 0x155B3E: prepare_resize&lt;alloc::alloc::Global&gt; (mod.rs:2864)
    ==699816==    by 0x155B3E: resize_inner&lt;alloc::alloc::Global&gt; (mod.rs:3060)
    ==699816==    by 0x155B3E: reserve_rehash_inner&lt;alloc::alloc::Global&gt; (mod.rs:2950)
    ==699816==    by 0x155B3E: hashbrown::raw::RawTable&lt;T,A&gt;::reserve_rehash (mod.rs:1231)
    ==699816==    by 0x5BC39F: UnknownInlinedFun (mod.rs:1179)
    ==699816==    by 0x5BC39F: find_or_find_insert_slot&lt;(usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool), alloc::alloc::Global, hashbrown::map::equivalent_key::{closure_env#0}&lt;usize, usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool&gt;, hashbrown::map::make_hasher::{closure_env#0}&lt;usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool, std::hash::random::RandomState&gt;&gt; (mod.rs:1413)
    ==699816==    by 0x5BC39F: hashbrown::map::HashMap&lt;K,V,S,A&gt;::insert (map.rs:1754)
    ==699816==    by 0x57C5C6: insert&lt;usize, fn(&amp;mut yjit::codegen::JITState, &amp;mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option&lt;yjit::codegen::BlockHandler&gt;, i32, core::option::Option&lt;yjit::cruby::VALUE&gt;) -&gt; bool, std::hash::random::RandomState&gt; (map.rs:1104)
    ==699816==    by 0x57C5C6: yjit::codegen::reg_method_codegen (codegen.rs:10521)
    ==699816==    by 0x57C295: yjit::codegen::yjit_reg_method_codegen_fns (codegen.rs:10464)
    ==699816==    by 0x5C6B07: rb_yjit_init (yjit.rs:40)
    ==699816==    by 0x393723: ruby_opt_init (ruby.c:1820)
    ==699816==    by 0x393723: ruby_opt_init (ruby.c:1767)
    ==699816==    by 0x3957D4: prism_script (ruby.c:2215)
    ==699816==    by 0x3957D4: process_options (ruby.c:2538)
    ==699816==    by 0x396065: ruby_process_options (ruby.c:3166)
    ==699816==    by 0x236E56: ruby_options (eval.c:117)
    ==699816==    by 0x15BAED: rb_main (main.c:43)
    ==699816==    by 0x15BAED: main (main.c:62)

After this patch, there are no more memory leaks reported when running
RUBY_FREE_AT_EXIT with Valgrind on an empty Ruby script:

    $ RUBY_FREE_AT_EXIT=1 valgrind --leak-check=full ruby -e ""
    ...
    ==700357== HEAP SUMMARY:
    ==700357==     in use at exit: 0 bytes in 0 blocks
    ==700357==   total heap usage: 36,559 allocs, 36,559 frees, 6,064,783 bytes allocated
    ==700357==
    ==700357== All heap blocks were freed -- no leaks are possible</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Pass panic message to rb_bug()</title>
<updated>2024-11-08T15:06:47+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-11-07T16:46:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d1969474e9762d2ca293efadce0f68da0c2137c0'/>
<id>d1969474e9762d2ca293efadce0f68da0c2137c0</id>
<content type='text'>
So that the Rust panic message is forwarded to the RUBY_CRASH_REPORT
system, instead of only the static "YJIT panicked" message done so
previously. This helps with triaging crashes since it's easier than
trying to parse stderr output.

Sample:

    &lt;internal:yjit_hook&gt;:2: [BUG] YJIT: panicked at src/codegen.rs:1197:5:
    explicit panic
    ...
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
So that the Rust panic message is forwarded to the RUBY_CRASH_REPORT
system, instead of only the static "YJIT panicked" message done so
previously. This helps with triaging crashes since it's easier than
trying to parse stderr output.

Sample:

    &lt;internal:yjit_hook&gt;:2: [BUG] YJIT: panicked at src/codegen.rs:1197:5:
    explicit panic
    ...
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Add compilation log (#11818)</title>
<updated>2024-10-17T21:36:43+00:00</updated>
<author>
<name>Kevin Menard</name>
<email>kevin@nirvdrum.com</email>
</author>
<published>2024-10-17T21:36:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=158b8cb52ec58c8ef8f5241a9db1c6dea4285253'/>
<id>158b8cb52ec58c8ef8f5241a9db1c6dea4285253</id>
<content type='text'>
* YJIT: Add `--yjit-compilation-log` flag to print out the compilation log at exit.

* YJIT: Add an option to enable the compilation log at runtime.

* YJIT: Fix a typo in the `IseqPayload` docs.

* YJIT: Add stubs for getting the YJIT compilation log in memory.

* YJIT: Add a compilation log based on a circular buffer to cap the log size.

* YJIT: Allow specifying either a file or directory name for the YJIT compilation log.

The compilation log will be populated as compilation events occur. If a directory is supplied, then a filename based on the PID will be used as the write target. If a file name is supplied instead, the log will be written to that file.

* YJIT: Add JIT compilation of C function substitutions to the compilation log.

* YJIT: Add compilation events to the circular buffer even if output is sent to a file.

Previously, the two modes were treated as being exclusive of one another. However, it could be beneficial to log all events to a file while also allowing for direct access of the last N events via `RubyVM::YJIT.compilation_log`.

* YJIT: Make timestamps the first element in the YJIT compilation log tuple.

* YJIT: Stream log to stderr if `--yjit-compilation-log` is supplied without an argument.

* YJIT: Eagerly compute compilation log messages to avoid hanging on to references that may GC.

* YJIT: Log all compiled blocks, not just the method entry points.

* YJIT: Remove all compilation events other than block compilation to slim down the log.

* YJIT: Replace circular buffer iterator with a consuming loop.

* YJIT: Support `--yjit-compilation-log=quiet` as a way to activate the in-memory log without printing it.

Co-authored-by: Randy Stauner &lt;randy.stauner@shopify.com&gt;

* YJIT: Promote the compilation log to being the one YJIT log.

Co-authored-by: Randy Stauner &lt;randy.stauner@shopify.com&gt;

* Update doc/yjit/yjit.md

* Update doc/yjit/yjit.md

---------

Co-authored-by: Randy Stauner &lt;randy.stauner@shopify.com&gt;
Co-authored-by: Maxime Chevalier-Boisvert &lt;maximechevalierb@gmail.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* YJIT: Add `--yjit-compilation-log` flag to print out the compilation log at exit.

* YJIT: Add an option to enable the compilation log at runtime.

* YJIT: Fix a typo in the `IseqPayload` docs.

* YJIT: Add stubs for getting the YJIT compilation log in memory.

* YJIT: Add a compilation log based on a circular buffer to cap the log size.

* YJIT: Allow specifying either a file or directory name for the YJIT compilation log.

The compilation log will be populated as compilation events occur. If a directory is supplied, then a filename based on the PID will be used as the write target. If a file name is supplied instead, the log will be written to that file.

* YJIT: Add JIT compilation of C function substitutions to the compilation log.

* YJIT: Add compilation events to the circular buffer even if output is sent to a file.

Previously, the two modes were treated as being exclusive of one another. However, it could be beneficial to log all events to a file while also allowing for direct access of the last N events via `RubyVM::YJIT.compilation_log`.

* YJIT: Make timestamps the first element in the YJIT compilation log tuple.

* YJIT: Stream log to stderr if `--yjit-compilation-log` is supplied without an argument.

* YJIT: Eagerly compute compilation log messages to avoid hanging on to references that may GC.

* YJIT: Log all compiled blocks, not just the method entry points.

* YJIT: Remove all compilation events other than block compilation to slim down the log.

* YJIT: Replace circular buffer iterator with a consuming loop.

* YJIT: Support `--yjit-compilation-log=quiet` as a way to activate the in-memory log without printing it.

Co-authored-by: Randy Stauner &lt;randy.stauner@shopify.com&gt;

* YJIT: Promote the compilation log to being the one YJIT log.

Co-authored-by: Randy Stauner &lt;randy.stauner@shopify.com&gt;

* Update doc/yjit/yjit.md

* Update doc/yjit/yjit.md

---------

Co-authored-by: Randy Stauner &lt;randy.stauner@shopify.com&gt;
Co-authored-by: Maxime Chevalier-Boisvert &lt;maximechevalierb@gmail.com&gt;</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: Fix `cargo doc --document-private-items` warnings [ci skip]</title>
<updated>2024-06-28T17:44:35+00:00</updated>
<author>
<name>Alan Wu</name>
<email>alanwu@ruby-lang.org</email>
</author>
<published>2024-06-28T17:44:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3e14fe7c2115a71ac46bca50443c12c4be516efc'/>
<id>3e14fe7c2115a71ac46bca50443c12c4be516efc</id>
<content type='text'>
Mostly putting angle brackets around links to follow markdown syntax.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Mostly putting angle brackets around links to follow markdown syntax.
</pre>
</div>
</content>
</entry>
<entry>
<title>Don't add `+YJIT` to `RUBY_DESCRIPTION` until it's actually enabled</title>
<updated>2024-06-05T18:53:49+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2024-06-05T09:52:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=33f92b3c88e8f03ec2aaf9db762e1eea845bee10'/>
<id>33f92b3c88e8f03ec2aaf9db762e1eea845bee10</id>
<content type='text'>
If you start Ruby with `--yjit-disable`, the `+YJIT` shouldn't be
added until `RubyVM::YJIT.enable` is actually called. Otherwise
it's confusing in crash reports etc.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If you start Ruby with `--yjit-disable`, the `+YJIT` shouldn't be
added until `RubyVM::YJIT.enable` is actually called. Otherwise
it's confusing in crash reports etc.
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Lazily push a frame for specialized C funcs (#10080)</title>
<updated>2024-02-23T19:08:09+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-02-23T19:08:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8a6740c70edf39cdf6230659d191240c43dc6d22'/>
<id>8a6740c70edf39cdf6230659d191240c43dc6d22</id>
<content type='text'>
* YJIT: Lazily push a frame for specialized C funcs

Co-authored-by: Maxime Chevalier-Boisvert &lt;maxime.chevalierboisvert@shopify.com&gt;

* Fix a comment on pc_to_cfunc

* Rename rb_yjit_check_pc to rb_yjit_lazy_push_frame

* Rename it to jit_prepare_lazy_frame_call

* Fix a typo

* Optimize String#getbyte as well

* Optimize String#byteslice as well

---------

Co-authored-by: Maxime Chevalier-Boisvert &lt;maxime.chevalierboisvert@shopify.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* YJIT: Lazily push a frame for specialized C funcs

Co-authored-by: Maxime Chevalier-Boisvert &lt;maxime.chevalierboisvert@shopify.com&gt;

* Fix a comment on pc_to_cfunc

* Rename rb_yjit_check_pc to rb_yjit_lazy_push_frame

* Rename it to jit_prepare_lazy_frame_call

* Fix a typo

* Optimize String#getbyte as well

* Optimize String#byteslice as well

---------

Co-authored-by: Maxime Chevalier-Boisvert &lt;maxime.chevalierboisvert@shopify.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Add --yjit-perf=codegen option (#9957)</title>
<updated>2024-02-14T17:09:14+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-02-14T17:09:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7177731282bea651385818076d4fa6b9bdf717c0'/>
<id>7177731282bea651385818076d4fa6b9bdf717c0</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Let RubyVM::YJIT.enable respect --yjit-stats (#9415)</title>
<updated>2024-01-05T19:08:57+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-01-05T19:08:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7f9c174102d0e2369befc7b88f2c073becaa7560'/>
<id>7f9c174102d0e2369befc7b88f2c073becaa7560</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
