Commit graph

153 commits

Author SHA1 Message Date
Stan Lo
4da569b53e [DOC] YJIT: Add YJIT to autolink_excluded_words 2025-08-11 18:37:51 -04:00
Takashi Kokubun
2cd10de330
ZJIT: Prepare for sharing JIT hooks with ZJIT (#14044) 2025-07-30 10:11:10 -07:00
Takashi Kokubun
f1acf47ca2
YJIT: Call YJIT hooks before enabling YJIT (#14032) 2025-07-28 15:17:45 -07:00
Daniel Colson
eead83160b
Prevent enabling yjit when zjit enabled (GH-13358)
`ruby --yjit --zjit` already warns and exits, but it was still possible
to enable both with `ruby --zjit -e 'RubyVM:YJIT.enable`.

This commit prevents that with a warning and an early return. (We could
also exit, but that seems a bit unfriendly once we're already running
the program.)

Co-authored-by: ywenc <ywenc@github.com>
2025-05-16 17:31:43 +00:00
a5-stable
53579e5718 yjit.rb: Fix parameter name in documentation 2025-03-05 10:19:31 -05:00
Nobuyoshi Nakada
53f8b269ef
* append newline at EOF. [ci skip] 2025-03-04 10:26:03 +09:00
annichai-stripe
5085ec3ed9
Allow YJIT mem-size and call-threshold to be set at runtime via YJIT.enable() (#12505)
* first commit

* yjit.rb change

* revert formatting

* rename mem-size to exec-mem-size for correctness

* wip, move setting into rb_yjit_enable directly

* remove unused helper functions

* add in call threshold

* input validation with extensive eprintln

* delete test script

* exec-mem-size -> mem-size

* handle input validation with asserts

* add test cases related to input validation

* modify test cases

* move validation out of rs, into rb

* add comments

* remove trailing spaces

* remove logging

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* remove helper fn

* Update test/ruby/test_yjit.rb

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* trailing white space

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2025-03-03 15:45:39 -05:00
Aaron Patterson
8cafa5b8ce Only count VM instructions in YJIT stats builds
The instruction counter is slowing multi-Ractor applications.  I had
changed it to use a thread local, but using a thread local is slowing
single threaded applications.  This commit only enables the instruction
counter in YJIT stats builds until we can figure out a way to gather the
information with lower overhead.

Co-authored-by: Randy Stauner <randy.stauner@shopify.com>
2025-02-14 14:39:35 -05:00
Takashi Kokubun
e25b350fc5 [DOC] Fix the broken format of RubyVM::YJIT.enable docs 2024-12-24 20:42:06 -08:00
Maxime Chevalier-Boisvert
8502a549ef
YJIT: small fix to stats formatting. (#12282)
Avoid division by zero and NaN%, e.g.
num_throw_break:                   0 ( NaN%)
num_throw_retry:                   0 ( NaN%)
num_throw_return:                  0 ( NaN%)
2024-12-06 09:25:39 -08:00
Maxime Chevalier-Boisvert
4b4d52ef50
YJIT: track time since initialization (#12263) 2024-12-04 21:24:36 +00:00
Takashi Kokubun
30e1d6b5a8
YJIT: Add inline_block_count stat (#12081) 2024-11-13 16:17:29 -05:00
Takashi Kokubun
478e0fc710
YJIT: Replace Array#each only when YJIT is enabled (#11955)
* YJIT: Replace Array#each only when YJIT is enabled

* Add comments about BUILTIN_ATTR_C_TRACE

* Make Ruby Array#each available with --yjit as well

* Fix all paths that expect a C location

* Use method_basic_definition_p to detect patches

* Copy a comment about C_TRACE flag to compilers

* Rephrase a comment about add_yjit_hook

* Give METHOD_ENTRY_BASIC flag to Array#each

* Add --yjit-c-builtin option

* Allow inconsistent source_location in test-spec

* Refactor a check of BUILTIN_ATTR_C_TRACE

* Set METHOD_ENTRY_BASIC without touching vm->running
2024-11-04 11:14:28 -05:00
Kevin Menard
158b8cb52e
YJIT: Add compilation log (#11818)
* 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 <randy.stauner@shopify.com>

* YJIT: Promote the compilation log to being the one YJIT log.

Co-authored-by: Randy Stauner <randy.stauner@shopify.com>

* Update doc/yjit/yjit.md

* Update doc/yjit/yjit.md

---------

Co-authored-by: Randy Stauner <randy.stauner@shopify.com>
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2024-10-17 21:36:43 +00:00
Randy Stauner
7c4b028435
YJIT: Accept key for runtime_stats to return only that stat (#11536) 2024-09-17 20:06:27 -04:00
Randy Stauner
942317ebf8
YJIT: Encode doubles to VALUE objects and move stat generation to rust (#11388)
* YJIT: Encode doubles to VALUE objects and move stat generation to rust

Stats that can now be generated from rust have been moved there.

* Move object_shape_count call for runtime_stats to rust

This reduces the ruby method to a single primitive.

* Change hash_aset_usize from macro to function
2024-08-27 22:24:17 -04:00
Alan Wu
ffd895156f YJIT: Delete otherwise-empty defer_compilation() blocks
Calls to defer_compilation() leave behind a stub and a `struct Block`
that we retain. If the block is empty, it only exits to hold the
`struct Branch` that the stub needs.

This patch transplants the branch out of the empty block into the newly
generated block when the defer_compilation() stub is hit, and deletes
the empty block to save memory.

To assist the transplantation, `Block::outgoing` is now a
`MutableBranchList`, and `Branch::Block` now in a `Cell`. These types
don't incur a size cost.

On the `lobsters` benchmark, `yjit_alloc_size` is roughly 98% of what
it was before the change.

Co-authored-by: Kevin Menard <kevin.menard@shopify.com>
Co-authored-by: Randy Stauner <randy@r4s6.net>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2024-06-13 13:00:46 -04:00
Alan Wu
28d1685ebb YJIT: Align number of total_exits for --yjit-stats 2024-06-13 13:00:46 -04:00
Maxime Chevalier-Boisvert
ce06924a17
YJIT: add context cache hits stat (#10979)
* YJIT: add context cache hits stat

This stat should make more sense when it comes to interpreting
the effectiveness of the cache on large deployed apps.
2024-06-12 13:33:27 -04:00
Maxime Chevalier-Boisvert
39019b6a63
YJIT: add context cache size stat, lazily allocate cache
* YJIT: add context cache size stat
* Allocate the context cache in a box so CRuby doesn't pay overhead
* Add an extra debug assertion
2024-06-11 12:46:11 -04:00
Maxime Chevalier-Boisvert
425e630ce7
YJIT: implement variable-length context encoding scheme (#10888)
* Implement BitVector data structure for variable-length context encoding

* Rename method to make intent clearer

* Rename write_uint => push_uint to make intent clearer

* Implement debug trait for BitVector

* Fix bug in BitVector::read_uint_at(), enable more tests

* Add one more test for good measure

* Start sketching Context::encode()

* Progress on variable length context encoding

* Add tests. Fix bug.

* Encode stack state

* Add comments. Try to estimate context encoding size.

* More compact encoding for stack size

* Commit before rebase

* Change Context::encode() to take a BitVector as input

* Refactor BitVector::read_uint(), add helper read functions

* Implement Context::decode() function. Add test.

* Fix bug, add tests

* Rename methods

* Add Context::encode() and decode() methods using global data

* Make encode and decode methods use u32 indices

* Refactor YJIT to use variable-length context encoding

* Tag functions as allow unused

* Add a simple caching mechanism and stats for bytes per context etc

* Add comments, fix formatting

* Grow vector of bytes by 1.2x instead of 2x

* Add debug assert to check round-trip encoding-decoding

* Take some rustfmt formatting

* Add decoded_from field to Context to reuse previous encodings

* Remove olde context stats

* Re-add stack_size assert

* Disable decoded_from optimization for now
2024-06-07 16:26:14 -04:00
Maxime Chevalier-Boisvert
ade22339e3
YJIT: print msg to stderr when RubyVM::YJIT.disasm not available (#10688)
* YJIT: print msg to stderr when RubyVM::YJIT.disasm not available

Print a more useful error message when people try to use this
feature without YJIT dev.

Also fix an issue with .gitignore file on macOS

* Update yjit.rb

Co-authored-by: Randy Stauner <randy@r4s6.net>

* Use warn and always return nil if YJIT disasm not available.

---------

Co-authored-by: Randy Stauner <randy@r4s6.net>
2024-04-30 17:57:18 +00:00
Maxime Chevalier-Boisvert
bb3cbdfe2f
YJIT: add iseq_alloc_count to stats (#10398)
* YJIT: add iseq_alloc_count to stats

* Remove an empty line

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2024-03-28 15:21:09 -04:00
Takashi Kokubun
8a6740c70e
YJIT: Lazily push a frame for specialized C funcs (#10080)
* YJIT: Lazily push a frame for specialized C funcs

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>

* 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 <maxime.chevalierboisvert@shopify.com>
2024-02-23 19:08:09 +00:00
Alan Wu
075b6ac8ae YJIT: Remove unused counters 2024-02-16 18:16:13 -05:00
Takashi Kokubun
c04782c2cb
YJIT: Adjust the padding size of counts automatically (#9912) 2024-02-12 11:56:24 -05:00
Nobuyoshi Nakada
739eec0456
[DOC] :stopdoc: directive must be on its own line (#9916) 2024-02-12 10:48:10 -05:00
Nobuyoshi Nakada
6cafbd35d9
YJIT: Remove unused variables 2024-02-10 14:24:28 +09:00
Takashi Kokubun
e7b0a01002
YJIT: Add top ISEQ call counts to --yjit-stats (#9906) 2024-02-09 22:12:24 +00:00
Takashi Kokubun
717adb564b
YJIT: Fallback megamorphic opt_case_dispatch (#9894) 2024-02-09 12:12:45 -05:00
Takashi Kokubun
c1f8d974a8
YJIT: Specialize splatkw on T_HASH (#9764)
* YJIT: Specialize splatkw on T_HASH

* Fix a typo

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>

* Fix a few more comments

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2024-01-30 14:59:53 -05:00
Takashi Kokubun
d4cc77e7b6
YJIT: Add a counter for invokebuiltin exits (#9696) 2024-01-25 11:23:26 -05:00
Takashi Kokubun
27c1dd8634
YJIT: Allow inlining ISEQ calls with a block (#9622)
* YJIT: Allow inlining ISEQ calls with a block

* Leave a TODO comment about u16 inline_block
2024-01-23 19:36:23 +00:00
Maxime Chevalier-Boisvert
afba09d30f
YJIT: specialized codegen for integer right shift (#9564)
* YJIT: specialized codegen for integer right shift

Used in optcarrot. May also be used to write pure-Ruby gems.
No overflow check or fixnum untagging required.

* Update yjit/src/codegen.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2024-01-17 10:35:48 -05:00
Takashi Kokubun
5e61cc26c9
YJIT: Optimize Integer#succ (#9519) 2024-01-15 10:32:48 -05:00
Takashi Kokubun
a0eecfb5ba
YJIT: Fallback Integer#<< if a shift amount varies (#9426)
* YJIT: Fallback Integer#<< if a shift amount varies

* YJIT: Do not fallback lshift in the first chain
2024-01-08 17:34:57 +00:00
Takashi Kokubun
7f9c174102
YJIT: Let RubyVM::YJIT.enable respect --yjit-stats (#9415) 2024-01-05 14:08:57 -05:00
Takashi Kokubun
bd91c5127f
YJIT: Add stats option to RubyVM::YJIT.enable (#9297) 2023-12-19 11:47:27 -08:00
Maxime Chevalier-Boisvert
ea3e17e430
YJIT: fix bug in top cfunc logging in --yjit-stats (#9056)
YJIT: correctly handle case where there are no cfunc calls

Fix bug in top cfunc logging in `--yjit-stats`
2023-11-28 22:27:11 +00:00
Maxime Chevalier-Boisvert
7f50c70574
YJIT: add top C function call counts to --yjit-stats (#9047)
* YJIT: gather call counts for individual cfuncs

Co-authored by Takashi Kokubun
2023-11-27 22:49:53 +00:00
Maxime Chevalier-Boisvert
f05d586cc9
YJIT: record num_send_cfunc stat (#9022)
* YJIT: record num_send_cfunc stat

Also report num_send_known_cfunc as percentage of num_send_cfunc

* Rename num_send_known_cfunc => num_send_cfunc_inline

Name seems more descriptive of what we do with out custom codegen
2023-11-23 15:33:43 -05:00
Alan Wu
277a3ecbf5 [DOC] RubyVM::YJIT doc improvements
* Weaken notice about API stability. A few public APIs in here now.
* Prune out APIs from the docs that are private in nature
* Enable markdown mode and ensure `--` options are quoted so they are
  rendered as two dashes in the HTML.
2023-11-10 19:08:13 -05:00
Mau Magnaguagno
eb2abc3f16
YJIT: refactor format_number (#8869)
Replace enumerators with simpler and faster version that only inserts commas before '.' or end of integer string.
2023-11-08 10:37:19 -05:00
Takashi Kokubun
9877f3ada8
YJIT: Inline basic Ruby methods (#8855)
* YJIT: Inline basic Ruby methods

* YJIT: Fix "InsnOut operand made it past register allocation"

checktype should not generate a useless instruction.
2023-11-07 10:54:33 -05:00
Mau Magnaguagno
d3ea9070bb
YJIT: skip to_a in format_number (#8815)
String#chars returns an array instead of an enumerator since Ruby 2.0.
2023-11-01 18:40:40 +00:00
Alan Wu
9047fe5ea4 YJIT: Print exit reasons on failure in test_yjit.rb
For <https://bugs.ruby-lang.org/issues/19921>, I suspect the test is
failing due to a timing related interrupt, which on paper could
happen with slow-enough GC runs.

In any case, it's helpful for debugging to have more information when
tests fail.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-19 15:14:20 -04:00
Takashi Kokubun
6beb09c2c9
YJIT: Add RubyVM::YJIT.enable (#8705) 2023-10-19 10:54:35 -07:00
Alan Wu
d2b0c9da2e
YJIT: Add a live ISeq counter
It's an estimator for application size and could be used as a
compilation heuristic later.

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-18 23:46:35 +00:00
Takashi Kokubun
d458b4127f
YJIT: Add a few missing counters for send fallback (#8681) 2023-10-17 11:36:13 -04:00
Maxime Chevalier-Boisvert
b2e1ddffa5
YJIT: port call threshold logic from Rust to C for performance (#8628)
* Port call threshold logic from Rust to C for performance

* Prefix global/field names with yjit_

* Fix linker error

* Fix preprocessor condition for rb_yjit_threshold_hit

* Fix third linker issue

* Exclude yjit_calls_at_interv from RJIT bindgen

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-12 10:05:34 -04:00