Граф коммитов

70 Коммитов

Автор SHA1 Сообщение Дата
Alan Wu e53d07f583 Rename ::YJIT to RubyVM::YJIT
Since the YJIT Ruby module is CRuby specific and not meant for general
use, it should live under RubyVM instead of at top level.
2021-10-28 13:43:02 -04:00
Alan Wu fdbae38546 YJIT: move --yjit-stats at_exit call into Ruby
This change fixes `-v --yjit-stats`. Previously in this situation,
YJIT._print_stats wasn't defined as yjit.rb is not evaluated when there
is only "-v" and no Ruby code to run.
2021-10-27 13:00:05 -04:00
Alan Wu f80069820e YJIT: Don't take VM lock on constant IC fill when disabled
While theoretically it's fine to take the lock and then immediately release
it, we don't need to do it when YJIT is off.
2021-10-22 17:22:41 -04:00
Noah Gibbs 21e58acef3 Don't enable YJIT by default. More tests on both Ubuntu and MacOS.
Add RUBY_YJIT_ENABLE env var and YJIT_FORCE_ENABLE compile-time constant.
Rename YJIT_STATS to RUBY_YJIT_STATS.
2021-10-20 18:19:42 -04:00
Alan Wu f6da559d5b Put YJIT into a single compilation unit
For upstreaming, we want functions we export either prefixed with "rb_"
or made static. Historically we haven't been following this rule, so we
were "leaking" a lot of symbols as `make leak-globals` would tell us.

This change unifies everything YJIT into a single compilation unit,
yjit.o, and makes everything unprefixed static to pass `make leak-globals`.
This manual "unified build" setup is similar to that of vm.o.

Having everything in one compilation unit allows static functions to
be visible across YJIT files and removes the need for declarations in
headers in some cases. Unnecessary declarations were removed.

Other changes of note:
  - switched to MJIT_SYMBOL_EXPORT_BEGIN which indicates stuff as being
    off limits for native extensions
  - the first include of each YJIT file is change to be "internal.h"
  - undefined MAP_STACK before explicitly redefining it since it
    collide's with a definition in system headers. Consider renaming?
2021-10-20 18:19:42 -04:00
Alan Wu 25eed28483 Remove unused function 2021-10-20 18:19:42 -04:00
Noah Gibbs be06112d48 Fix changes from rebase 2021-10-20 18:19:42 -04:00
Alan Wu a10cf74e5c style: align pointer "*" to the right 2021-10-20 18:19:41 -04:00
Alan Wu 0a108601ef Add counters for version invalidation reasons
I noticed that there were two st_table iterators that do exactly the
same thing so I merged them into one.
2021-10-20 18:19:41 -04:00
Maxime Chevalier-Boisvert 0385ca2e97 Try to break the code page refactoring into smaller steps 2021-10-20 18:19:41 -04:00
Alan Wu c46bda6f19 Fix excessive invalidation for opt_getinlinecache
YJIT expects the VM to invalidate opt_getinlinecache when updating the
constant cache, and the invalidation used to happen even when YJIT can't
use the cached value.

Once the first invalidation happens, the block for opt_getinlinecache
becomes a stub. When the stub is hit, YJIT fails to compile the
instruction as the cache is not usable. The stub becomes a block that
exits for opt_getinlinecache which can be invalidated again. Some
workloads that bust the interpreter's constant cache can create an
invalidation loop with this behavior.

Check if the cache is usable become doing invalidation to fix this
problem.

In the test harness, evaluate the test script in a lambda instead of a
proc so `return` doesn't return out of the harness.
2021-10-20 18:19:41 -04:00
Alan Wu 82405ac48a Add counters for tracking invalidations 2021-10-20 18:19:41 -04:00
Alan Wu bc7652998e Fix warnings about redefining YJIT_STATS
Follow up for ecb5b383a0. Now that
YJIT_STATS is defined in yjit.h, it shoudl be the only place that
defines it.
2021-10-20 18:19:40 -04:00
Maxime Chevalier-Boisvert 013a4a31d6 Prevent stats being enabled late at run-time 2021-10-20 18:19:40 -04:00
John Hawthorn 3ecc6befcd Implement invokesuper using cfp->ep[ME] check
This fixes and re-enables invokesuper, replacing the existing guards
with a guard on the method entry for the EP.
2021-10-20 18:19:39 -04:00
John Hawthorn fbde1d9bee Store block callee_cme in darray
This allows a block version to have dependencies on multiple CMEs.
2021-10-20 18:19:39 -04:00
Jean Boussier b5a0baf1c0 Allow to toggle YJIT stats collection from runtime
For use cases where you want to collect the metrics
for a specific piece of code (typically a web request)
you can have the stats turned off by default and then
turn them on at runtime before executing the code you care
about.
2021-10-20 18:19:39 -04:00
Alan Wu bd876c243a TracePoint support
This change fixes some cases where YJIT fails to fire tracing events.
Most of the situations YJIT did not handle correctly involves enabling
tracing while running inside generated code.

A new operation to invalidate all generated code is added, which uses
patching to make generated code exit at the next VM instruction
boundary. A new routine called `jit_prepare_routine_call()` is
introduced to facilitate this and should be used when generating code
that could allocate, or could otherwise use `RB_VM_LOCK_ENTER()`.

The `c_return` event is fired in the middle of an instruction as opposed
to at an instruction boundary, so it requires special handling. C method
call return points are patched to go to a fucntion which does everything
the interpreter does, including firing the `c_return` event. The
generated code for C method calls normally does not fire the event.

Invalided code should not change after patching so the exits are not
clobbered. A new variable is introduced to track the region of code that
should not change.
2021-10-20 18:19:39 -04:00
Jean Boussier 0dc3bba6f2 Allow to compile with --yjit-stats support but not the full RUBY_DEBUG
RUBY_DEBUG have a very significant performance overhead. Enough that
YJIT with RUBY_DEBUG is noticeably slower than the interpreter without
RUBY_DEBUG.

This makes it hard to collect yjit-stats in production environments.

By allowing to collect JIT statistics without the RUBy_DEBUG overhead,
I hope to make such use cases smoother.
2021-10-20 18:19:39 -04:00
Noah Gibbs dd23e4658b If codeblock is NULL because YJIT is disabled, YJIT.runtime_stats should return Qnil 2021-10-20 18:19:38 -04:00
Maxime Chevalier-Boisvert 1891dcaa9f Add flag so we can easily tell if all stats avail. Comment out broken test. 2021-10-20 18:19:38 -04:00
Aaron Patterson e8617d0e7e Make sure we can still compile with the JIT disabled
If `--disable-jit-support` is passed to configure, then `jit_func` is
removed from the iseq body and we can't compile YJIT.  This commit
detects when the JIT function pointer is gone and disables YJIT in that
case.
2021-10-20 18:19:38 -04:00
Aaron Patterson 41f405c486 Remove the scraper
Now that we're using the jit function entry point, we don't need the
scraper.  Thank you for your service, scraper. ❤️
2021-10-20 18:19:38 -04:00
Aaron Patterson 5336f6dada make compiler happy 2021-10-20 18:19:38 -04:00
Aaron Patterson d0174d99c6 Always use `ret` to return to the interpreter
Always using `ret` to return to the interpreter means that we never have
to check the VM_FRAME_FLAG_FINISH flag.

In the case that we return `Qundef`, the interpreter will execute the
cfp.  We can take advantage of this by setting the PC to the instruction
we can't handle, and let the interpreter pick up the ball from there.

If we return a value other than Qundef, the interpreter will take that
value as the "return value" from the JIT and push that to the SP of the
caller

The leave instruction puts the return value on the top of the calling
frame's stack.  YJIT does the same thing for leave instructions.
However, when we're returning back to the interpreter, the leave
instruction _should not_ put the return value on the top of the stack,
but put it in RAX and use RET.  This commit pops the last value from the
stack pointer and puts it in RAX so that the interpreter is happy with
SP.
2021-10-20 18:19:37 -04:00
Noah Gibbs b70383fbea YJIT stats should always include the inlined and outlined sizes, regardless of RUBY_DEBUG and --yjit-stats/YJIT_STATS settings 2021-10-20 18:19:37 -04:00
Maxime Chevalier-Boisvert d5f18f7845 Add (void) for no arg functions 2021-10-20 18:19:37 -04:00
Maxime Chevalier-Boisvert 350b686a2c First pass at code page GC object. 2021-10-20 18:19:37 -04:00
Aaron Patterson 2440fafba0 rb_struct_define_under needs a trailing NULL
The last parameter to rb_struct_define_under needs to be NULL otherwise
we can get a SEGV.
2021-10-20 18:19:37 -04:00
Noah Gibbs 6998246233 Use snprintf rather than double strncpy. 2021-10-20 18:19:37 -04:00
Noah Gibbs db02d73e5e Change strcpy of a static string to strncpy 2021-10-20 18:19:37 -04:00
Noah Gibbs 5e164a77d5 Better comments where we add exits-by-opcode to the stats hash, plus a presumably-unneeded strncpy just to be sure. 2021-10-20 18:19:36 -04:00
Noah Gibbs 89ae21a092 Add back ifdefs for RUBY_DEBUG, accidentally removed 2021-10-20 18:19:36 -04:00
Noah Gibbs d2e9932908 Convert YJIT stats reporting on exit from C to Ruby. 2021-10-20 18:19:36 -04:00
Noah Gibbs 33227b1094 Add exit counters and inline/outlined code size to stats hash 2021-10-20 18:19:36 -04:00
Noah Gibbs 25792c17d4 Convert yjit static stat variables to counters 2021-10-20 18:19:36 -04:00
Alan Wu 3996e0ab07 Add tests, comments, and an assert for invokesuper 2021-10-20 18:19:36 -04:00
Alan Wu 6883aeda77 Add a macro for tweaking default call threshold
For use in development for writing `test.rb` and running with `make
run`.
2021-10-20 18:19:36 -04:00
Maxime Chevalier-Boisvert 7030cae969 Try running with more YJIT options in CI to surface more bugs 2021-10-20 18:19:36 -04:00
Aaron Patterson 46d5e10279 Add graphviz output
This adds a method to blocks to get outgoing ids, then uses the outgoing
ids to generate a graphviz graph.  Two methods were added to the Block
object.  One method returns an id for the block, which is just the
address of the underlying block.  The other method returns a list of
outgoing block ids.  We can use Block#id in conjunction with
Block#outgoing_ids to construct a graph of blocks
2021-10-20 18:19:36 -04:00
Jean Boussier d416a15c86 Warn rather than raise when --yjit-stats is ignored 2021-10-20 18:19:36 -04:00
Noah Gibbs d1d3d2c0aa If --yjit-stats is given without RUBY_DEBUG, that should be an error. 2021-10-20 18:19:36 -04:00
Jean Boussier 3365e1d719 Allow to enable `--yjit-stats` via a env variable 2021-10-20 18:19:36 -04:00
Maxime Chevalier-Boisvert 860589c7fa Use builtin_inline_p to avoid pushing a frame for primitive C methods (#63)
* Use builtin_inline_p to skip a frame of C methods

* Fix bugs in primitive cfunc call code

* Remove if (push_frame) {}

* Remove if (push_frame) {}

* Push Aaron's fix to avoid hardcoding insn lengths

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2021-10-20 18:19:35 -04:00
Maxime Chevalier-Boisvert b415ceb92e Increase default YJIT call threshold to 10. Add exec mem size arg. (#52) 2021-10-20 18:19:35 -04:00
Alan Wu 0758115d11 Implement send with blocks
* Implement send with blocks

Not that much extra work compared to `opt_send_without_block`.
Moved the stack over flow check because it could've exited after changes
are made to cfp.

* rename oswb counters

* Might as well implement sending block to cfuncs

* Disable sending blocks to cfuncs for now

* Reconstruct interpreter sp before calling into cfuncs

In case the callee cfunc calls a method or delegates to a block.
This also has the side benefit of letting call sites that sometimes are
iseq calls and sometimes cfunc call share the same successor.

* only sync with interpreter sp when passing a block


Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Aaron Patterson <aaron.patterson@shopify.com>
2021-10-20 18:19:34 -04:00
Maxime Chevalier-Boisvert 8249f6ef57 Print top-20 common exit reasons instead of just top-10 (#19) 2021-10-20 18:19:34 -04:00
Maxime Chevalier-Boisvert cf2b508375 Try to alloc executable memory within rel32 range on Linux machines (#12)
* Use INT32_MIN, INT32_MAX, etc. constants in yjit_asm.c

* Print warning on stderr when code past rel32 jump range

* Fix preprocessor snafu

* Move rel32 warning into --yjit-stats

* Try to allocate within rel32 offset on Linux machines

* Update yjit_asm.c

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

* On Linux, use sysconf to get the page size

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2021-10-20 18:19:34 -04:00
Maxime Chevalier-Boisvert 96f4f918b0 Implement greedy versioning. Refactor versioning logic. (#10)
* Implement eager versioning. Refactor versioning logic.

* Add --version-limit and --greedy-versioning command-line args
2021-10-20 18:19:34 -04:00
Aaron Patterson ac88c61ed8 cYjitCodeComment is only defined if we're not in debugging mode
This commit fixes a build error.  If we build in release mode (IOW
*without* RUBY_DEBUG), then this constant isn't defined.  Release mode
builds are required by yjit-bench
2021-10-20 18:19:34 -04:00