<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/yjit/src/disasm.rs, branch v4.0.2</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 unread field lint in release builds</title>
<updated>2024-12-11T22:44:43+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-12-11T21:45:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d53e4545f4754c789828cdf491df1eacf982d121'/>
<id>d53e4545f4754c789828cdf491df1eacf982d121</id>
<content type='text'>
```
warning: fields `blue_begin` and `blue_end` are never read
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
```
warning: fields `blue_begin` and `blue_end` are never read
```
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Only enable disassembly colors for tty (#12283)</title>
<updated>2024-12-09T15:36:17+00:00</updated>
<author>
<name>Max Bernstein</name>
<email>max.bernstein@shopify.com</email>
</author>
<published>2024-12-09T15:36:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8010d79bb429ed8dac5244e481ba5ddc108797a2'/>
<id>8010d79bb429ed8dac5244e481ba5ddc108797a2</id>
<content type='text'>
* YJIT: Use fully-qualified name for OPTIONS in get_options!

* YJIT: Only enable disassembly colors for tty</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* YJIT: Use fully-qualified name for OPTIONS in get_options!

* YJIT: Only enable disassembly colors for tty</pre>
</div>
</content>
</entry>
<entry>
<title>Ignore return value of `into_raw_fd`</title>
<updated>2024-11-06T03:37:13+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2024-11-06T02:03:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c690ca03f33441f299d0b59e4a91fc22bf1781bf'/>
<id>c690ca03f33441f299d0b59e4a91fc22bf1781bf</id>
<content type='text'>
Fix as the compiler orders:
```
warning: unused return value of `into_raw_fd` that must be used
   --&gt; ../src/yjit/src/disasm.rs:123:21
    |
123 |                     file.into_raw_fd(); // keep the fd open
    |                     ^^^^^^^^^^^^^^^^^^
    |
    = note: losing the raw file descriptor may leak resources
    = note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
    |
123 |                     let _ = file.into_raw_fd(); // keep the fd open
    |                     +++++++

warning: unused return value of `into_raw_fd` that must be used
  --&gt; ../src/yjit/src/log.rs:84:21
   |
84 |                     file.into_raw_fd(); // keep the fd open
   |                     ^^^^^^^^^^^^^^^^^^
   |
   = note: losing the raw file descriptor may leak resources
help: use `let _ = ...` to ignore the resulting value
   |
84 |                     let _ = file.into_raw_fd(); // keep the fd open
   |                     +++++++
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix as the compiler orders:
```
warning: unused return value of `into_raw_fd` that must be used
   --&gt; ../src/yjit/src/disasm.rs:123:21
    |
123 |                     file.into_raw_fd(); // keep the fd open
    |                     ^^^^^^^^^^^^^^^^^^
    |
    = note: losing the raw file descriptor may leak resources
    = note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
    |
123 |                     let _ = file.into_raw_fd(); // keep the fd open
    |                     +++++++

warning: unused return value of `into_raw_fd` that must be used
  --&gt; ../src/yjit/src/log.rs:84:21
   |
84 |                     file.into_raw_fd(); // keep the fd open
   |                     ^^^^^^^^^^^^^^^^^^
   |
   = note: losing the raw file descriptor may leak resources
help: use `let _ = ...` to ignore the resulting value
   |
84 |                     let _ = file.into_raw_fd(); // keep the fd open
   |                     +++++++
```
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: `dump-disasm`: Print comments and bytes in release builds</title>
<updated>2024-07-08T20:02:30+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-07-08T20:02:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3be9ce3cf61e8396ecc3eea6169a2fd1a2c2bfea'/>
<id>3be9ce3cf61e8396ecc3eea6169a2fd1a2c2bfea</id>
<content type='text'>
This change implements a fallback mode for the `--yjit-dump-disasm`
development command-line option to make it usable in release builds.
Previously, using the option with release builds of YJIT yielded only
a warning asking the user to build with `--enable-yjit=dev`.

While builds that use the `disasm` feature still give the best output,
just having the comments is useful enough for many kinds of debugging.
Having it usable in release builds is nice for new hackers, too, since
this allows for tinkering without having to learn how to build YJIT in
development mode.

Sample output on A64:

```
  # regenerate_branch
  # Insn: 0001 opt_send_without_block (stack_size: 1)
  # guard known object with singleton class
  0x11f7e0034: 4b 00 00 58 03 00 00 14 08 ce 9c 04 01 00 00
  0x11f7e0043: 00 3f 00 0b eb 81 06 01 54 1f 20 03 d5
  # RUBY_VM_CHECK_INTS(ec)
  0x11f7e0050: 8b 02 42 b8 cb 07 01 35
  # stack overflow check
  0x11f7e0058: ab 62 02 91 7f 02 0b eb 69 07 01 54
  # save PC to CFP
  0x11f7e0064: 0b 3b 9a d2 2b 2f a0 f2 0b 00 cc f2 6b 02 00
  0x11f7e0073: f8 ab 82 00 91
```

To ensure this feature doesn't incur too much cost when running without
the `--yjit-dump-disasm` option, I checked that there is no significant
impact to compile time and memory usage with the `compile_time_ns` and
`yjit_alloc_size` entry in `RubyVM::YJIT.runtime_stats`. For each
sample, I ran 3 iterations of the `lobsters` YJIT benchmark. The
statistics summary and done with the `summary` function in R.

Compile time, sample size of 60, lower is better:

```
       Before              After
 Min.   :2.054e+09   Min.   :2.028e+09
 1st Qu.:2.069e+09   1st Qu.:2.044e+09
 Median :2.081e+09   Median :2.060e+09
 Mean   :2.089e+09   Mean   :2.066e+09
 3rd Qu.:2.109e+09   3rd Qu.:2.085e+09
 Max.   :2.146e+09   Max.   :2.144e+09
```

Allocation size, sample size of 20, lower is better:

```
       Before             After
 Min.   :21804742   Min.   :21794082
 1st Qu.:21826682   1st Qu.:21816282
 Median :21844042   Median :21826814
 Mean   :21960664   Mean   :22026291
 3rd Qu.:21861228   3rd Qu.:22040439
 Max.   :22587426   Max.   :22930614
```

The `yjit_alloc_size` samples are noisy, but since the average increased
by only 0.3%, and the median is lower, I feel safe saying that there is
no significant change.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change implements a fallback mode for the `--yjit-dump-disasm`
development command-line option to make it usable in release builds.
Previously, using the option with release builds of YJIT yielded only
a warning asking the user to build with `--enable-yjit=dev`.

While builds that use the `disasm` feature still give the best output,
just having the comments is useful enough for many kinds of debugging.
Having it usable in release builds is nice for new hackers, too, since
this allows for tinkering without having to learn how to build YJIT in
development mode.

Sample output on A64:

```
  # regenerate_branch
  # Insn: 0001 opt_send_without_block (stack_size: 1)
  # guard known object with singleton class
  0x11f7e0034: 4b 00 00 58 03 00 00 14 08 ce 9c 04 01 00 00
  0x11f7e0043: 00 3f 00 0b eb 81 06 01 54 1f 20 03 d5
  # RUBY_VM_CHECK_INTS(ec)
  0x11f7e0050: 8b 02 42 b8 cb 07 01 35
  # stack overflow check
  0x11f7e0058: ab 62 02 91 7f 02 0b eb 69 07 01 54
  # save PC to CFP
  0x11f7e0064: 0b 3b 9a d2 2b 2f a0 f2 0b 00 cc f2 6b 02 00
  0x11f7e0073: f8 ab 82 00 91
```

To ensure this feature doesn't incur too much cost when running without
the `--yjit-dump-disasm` option, I checked that there is no significant
impact to compile time and memory usage with the `compile_time_ns` and
`yjit_alloc_size` entry in `RubyVM::YJIT.runtime_stats`. For each
sample, I ran 3 iterations of the `lobsters` YJIT benchmark. The
statistics summary and done with the `summary` function in R.

Compile time, sample size of 60, lower is better:

```
       Before              After
 Min.   :2.054e+09   Min.   :2.028e+09
 1st Qu.:2.069e+09   1st Qu.:2.044e+09
 Median :2.081e+09   Median :2.060e+09
 Mean   :2.089e+09   Mean   :2.066e+09
 3rd Qu.:2.109e+09   3rd Qu.:2.085e+09
 Max.   :2.146e+09   Max.   :2.144e+09
```

Allocation size, sample size of 20, lower is better:

```
       Before             After
 Min.   :21804742   Min.   :21794082
 1st Qu.:21826682   1st Qu.:21816282
 Median :21844042   Median :21826814
 Mean   :21960664   Mean   :22026291
 3rd Qu.:21861228   3rd Qu.:22040439
 Max.   :22587426   Max.   :22930614
```

The `yjit_alloc_size` samples are noisy, but since the average increased
by only 0.3%, and the median is lower, I feel safe saying that there is
no significant change.</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Remove done TODO, fix indent</title>
<updated>2024-07-03T23:10:57+00:00</updated>
<author>
<name>Alan Wu</name>
<email>alanwu@ruby-lang.org</email>
</author>
<published>2024-07-03T23:10:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b160a78d6b466fc58e716be1f108edc57f6ec6e5'/>
<id>b160a78d6b466fc58e716be1f108edc57f6ec6e5</id>
<content type='text'>
Type check now done in rb_iseqw_to_iseq().
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Type check now done in rb_iseqw_to_iseq().
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: `--yjit-dump-disasm=dir`: Hold descriptor for dump file</title>
<updated>2024-06-17T19:09:32+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2024-06-14T20:24:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=657c8db8deb06741ca4b6a8b6635230f68c6d263'/>
<id>657c8db8deb06741ca4b6a8b6635230f68c6d263</id>
<content type='text'>
This mainly aims to make `--yjit-dump-disasm=&lt;relative_path&gt;` more
usable. Previously, it crashed if the program did chdir(2), since it
opened the dump file every time when appending.

Tested with:

    ./miniruby --yjit-dump-disasm=. --yjit-call-threshold=1 -e 'Dir.chdir("/") {}'

And the `lobsters` benchmark.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This mainly aims to make `--yjit-dump-disasm=&lt;relative_path&gt;` more
usable. Previously, it crashed if the program did chdir(2), since it
opened the dump file every time when appending.

Tested with:

    ./miniruby --yjit-dump-disasm=. --yjit-call-threshold=1 -e 'Dir.chdir("/") {}'

And the `lobsters` benchmark.
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Use u32 for CodePtr to save 4 bytes each</title>
<updated>2023-11-07T22:43:43+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2023-10-16T22:35:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a1c61f0ae5f5ecaa7d8289942b78e6b0c77118fe'/>
<id>a1c61f0ae5f5ecaa7d8289942b78e6b0c77118fe</id>
<content type='text'>
We've long had a size restriction on the code memory region such that a
u32 could refer to everything. This commit capitalizes on this
restriction by shrinking the size of `CodePtr` to be 4 bytes from 8.

To derive a full raw pointer from a `CodePtr`, one needs a base pointer.
Both `CodeBlock` and `VirtualMemory` can be used for this purpose. The
base pointer is readily available everywhere, except for in the case of
the `jit_return` "branch". Generalize lea_label() to lea_jump_target()
in the IR to delay deriving the `jit_return` address until `compile()`,
when the base pointer is available.

On railsbench, this yields roughly a 1% reduction to `yjit_alloc_size`
(58,397,765 to 57,742,248).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We've long had a size restriction on the code memory region such that a
u32 could refer to everything. This commit capitalizes on this
restriction by shrinking the size of `CodePtr` to be 4 bytes from 8.

To derive a full raw pointer from a `CodePtr`, one needs a base pointer.
Both `CodeBlock` and `VirtualMemory` can be used for this purpose. The
base pointer is readily available everywhere, except for in the case of
the `jit_return` "branch". Generalize lea_label() to lea_jump_target()
in the IR to delay deriving the `jit_return` address until `compile()`,
when the base pointer is available.

On railsbench, this yields roughly a 1% reduction to `yjit_alloc_size`
(58,397,765 to 57,742,248).
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Fix --yjit-dump-disasm coloring on less(1) (#8158)</title>
<updated>2023-08-02T14:16:37+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2023-08-02T14:16:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=452debba22cfae0ed61042afb21f2bf86135c1dc'/>
<id>452debba22cfae0ed61042afb21f2bf86135c1dc</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Avoid splitting mov for small values on arm64 (#7745)</title>
<updated>2023-04-20T17:05:30+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2023-04-20T17:05:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=995b960c70c624639552a04c38c7822f9875c53d'/>
<id>995b960c70c624639552a04c38c7822f9875c53d</id>
<content type='text'>
* YJIT: Avoid splitting mov for small values on arm64

* Fix a comment

Co-authored-by: Alan Wu &lt;XrXr@users.noreply.github.com&gt;

* YJIT: Test the 0xffff boundary

---------

Co-authored-by: Alan Wu &lt;XrXr@users.noreply.github.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* YJIT: Avoid splitting mov for small values on arm64

* Fix a comment

Co-authored-by: Alan Wu &lt;XrXr@users.noreply.github.com&gt;

* YJIT: Test the 0xffff boundary

---------

Co-authored-by: Alan Wu &lt;XrXr@users.noreply.github.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>YJIT: Use raw pointers and shared references over `Rc&lt;RefCell&lt;_&gt;&gt;`</title>
<updated>2023-03-17T16:30:24+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2023-03-16T19:39:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=10e4fa3a0f05f72733d132794cedd08906b40196'/>
<id>10e4fa3a0f05f72733d132794cedd08906b40196</id>
<content type='text'>
`Rc` and `RefCell` both incur runtime space costs.
In addition, `RefCell` has given us some headaches with the
non obvious borrow panics it likes to throw out. The latest
one started with 7fd53eeb46db261bbc20025cdab70096245a5cbe
and is yet to be resolved.

Since we already rely on the GC to properly reclaim memory for `Block`
and `Branch`, we might as well stop paying the overhead of `Rc` and
`RefCell`. The `RefCell` panics go away with this change, too.

On 25 iterations of `railsbench` with a stats build I got
`yjit_alloc_size: 8,386,129 =&gt; 7,348,637`, with the new memory size 87.6%
of the status quo. This makes the metadata and machine code size roughly
line up one-to-one.

The general idea here is to use `&amp;` shared references with
[interior mutability][1] with `Cell`, which doesn't take any extra
space. The `noalias` requirement that `&amp;mut` imposes is way too hard to
meet and verify. Imagine replacing places where we would've gotten
`BorrowError` from `RefCell` with Rust/LLVM miscompiling us due to aliasing
violations. With shared references, we don't have to think about subtle
cases like the GC _sometimes_ calling the mark callback while codegen
has an aliasing reference in a stack frame below. We mostly only need to
worry about liveness, with which the GC already helps.

There is now a clean split between blocks and branches that are not yet
fully constructed and ones that are "in-service", so to speak. Working
with `PendingBranch` and `JITState` don't really involve `unsafe` stuff.
This change allows `Branch` and `Block` to not have as many optional
fields as many of them are only optional during compilation. Fields that
change post-compilation are wrapped in `Cell` to facilitate mutation
through shared references.

I do some `unsafe` dances here. I've included just a couple tests to run
with Miri (`cargo +nightly miri test miri`). We can add more Miri tests
if desired.

[1]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`Rc` and `RefCell` both incur runtime space costs.
In addition, `RefCell` has given us some headaches with the
non obvious borrow panics it likes to throw out. The latest
one started with 7fd53eeb46db261bbc20025cdab70096245a5cbe
and is yet to be resolved.

Since we already rely on the GC to properly reclaim memory for `Block`
and `Branch`, we might as well stop paying the overhead of `Rc` and
`RefCell`. The `RefCell` panics go away with this change, too.

On 25 iterations of `railsbench` with a stats build I got
`yjit_alloc_size: 8,386,129 =&gt; 7,348,637`, with the new memory size 87.6%
of the status quo. This makes the metadata and machine code size roughly
line up one-to-one.

The general idea here is to use `&amp;` shared references with
[interior mutability][1] with `Cell`, which doesn't take any extra
space. The `noalias` requirement that `&amp;mut` imposes is way too hard to
meet and verify. Imagine replacing places where we would've gotten
`BorrowError` from `RefCell` with Rust/LLVM miscompiling us due to aliasing
violations. With shared references, we don't have to think about subtle
cases like the GC _sometimes_ calling the mark callback while codegen
has an aliasing reference in a stack frame below. We mostly only need to
worry about liveness, with which the GC already helps.

There is now a clean split between blocks and branches that are not yet
fully constructed and ones that are "in-service", so to speak. Working
with `PendingBranch` and `JITState` don't really involve `unsafe` stuff.
This change allows `Branch` and `Block` to not have as many optional
fields as many of them are only optional during compilation. Fields that
change post-compilation are wrapped in `Cell` to facilitate mutation
through shared references.

I do some `unsafe` dances here. I've included just a couple tests to run
with Miri (`cargo +nightly miri test miri`). We can add more Miri tests
if desired.

[1]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html
</pre>
</div>
</content>
</entry>
</feed>
