summaryrefslogtreecommitdiff
path: root/yjit_iface.c
AgeCommit message (Collapse)Author
2021-10-22YJIT: Don't take VM lock on constant IC fill when disabledAlan Wu
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. Notes: Merged: https://github.com/ruby/ruby/pull/5007
2021-10-20Don't enable YJIT by default. More tests on both Ubuntu and MacOS.Noah Gibbs
Add RUBY_YJIT_ENABLE env var and YJIT_FORCE_ENABLE compile-time constant. Rename YJIT_STATS to RUBY_YJIT_STATS.
2021-10-20Put YJIT into a single compilation unitAlan Wu
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-20Remove unused functionAlan Wu
2021-10-20Fix changes from rebaseNoah Gibbs
2021-10-20style: align pointer "*" to the rightAlan Wu
2021-10-20Add counters for version invalidation reasonsAlan Wu
I noticed that there were two st_table iterators that do exactly the same thing so I merged them into one.
2021-10-20Try to break the code page refactoring into smaller stepsMaxime Chevalier-Boisvert
2021-10-20Fix excessive invalidation for opt_getinlinecacheAlan Wu
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-20Add counters for tracking invalidationsAlan Wu
2021-10-20Fix warnings about redefining YJIT_STATSAlan Wu
Follow up for ecb5b383a0c17550b9b27663005049ddac871edb. Now that YJIT_STATS is defined in yjit.h, it shoudl be the only place that defines it.
2021-10-20Prevent stats being enabled late at run-timeMaxime Chevalier-Boisvert
2021-10-20Implement invokesuper using cfp->ep[ME] checkJohn Hawthorn
This fixes and re-enables invokesuper, replacing the existing guards with a guard on the method entry for the EP.
2021-10-20Store block callee_cme in darrayJohn Hawthorn
This allows a block version to have dependencies on multiple CMEs.
2021-10-20Allow to toggle YJIT stats collection from runtimeJean Boussier
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-20TracePoint supportAlan Wu
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-20Allow to compile with --yjit-stats support but not the full RUBY_DEBUGJean Boussier
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-20If codeblock is NULL because YJIT is disabled, YJIT.runtime_stats should ↵Noah Gibbs
return Qnil
2021-10-20Add flag so we can easily tell if all stats avail. Comment out broken test.Maxime Chevalier-Boisvert
2021-10-20Make sure we can still compile with the JIT disabledAaron Patterson
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-20Remove the scraperAaron Patterson
Now that we're using the jit function entry point, we don't need the scraper. Thank you for your service, scraper. ❤️
2021-10-20make compiler happyAaron Patterson
2021-10-20Always use `ret` to return to the interpreterAaron Patterson
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-20YJIT stats should always include the inlined and outlined sizes, regardless ↵Noah Gibbs
of RUBY_DEBUG and --yjit-stats/YJIT_STATS settings
2021-10-20Add (void) for no arg functionsMaxime Chevalier-Boisvert
2021-10-20First pass at code page GC object.Maxime Chevalier-Boisvert
2021-10-20rb_struct_define_under needs a trailing NULLAaron Patterson
The last parameter to rb_struct_define_under needs to be NULL otherwise we can get a SEGV.
2021-10-20Use snprintf rather than double strncpy.Noah Gibbs
2021-10-20Change strcpy of a static string to strncpyNoah Gibbs
2021-10-20Better comments where we add exits-by-opcode to the stats hash, plus a ↵Noah Gibbs
presumably-unneeded strncpy just to be sure.
2021-10-20Add back ifdefs for RUBY_DEBUG, accidentally removedNoah Gibbs
2021-10-20Convert YJIT stats reporting on exit from C to Ruby.Noah Gibbs
2021-10-20Add exit counters and inline/outlined code size to stats hashNoah Gibbs
2021-10-20Convert yjit static stat variables to countersNoah Gibbs
2021-10-20Add tests, comments, and an assert for invokesuperAlan Wu
2021-10-20Add a macro for tweaking default call thresholdAlan Wu
For use in development for writing `test.rb` and running with `make run`.
2021-10-20Try running with more YJIT options in CI to surface more bugsMaxime Chevalier-Boisvert
2021-10-20Add graphviz outputAaron Patterson
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-20Warn rather than raise when --yjit-stats is ignoredJean Boussier
2021-10-20If --yjit-stats is given without RUBY_DEBUG, that should be an error.Noah Gibbs
2021-10-20Allow to enable `--yjit-stats` via a env variableJean Boussier
2021-10-20Use builtin_inline_p to avoid pushing a frame for primitive C methods (#63)Maxime Chevalier-Boisvert
* 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-20Increase default YJIT call threshold to 10. Add exec mem size arg. (#52)Maxime Chevalier-Boisvert
2021-10-20Implement send with blocksAlan Wu
* 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-20Print top-20 common exit reasons instead of just top-10 (#19)Maxime Chevalier-Boisvert
2021-10-20Try to alloc executable memory within rel32 range on Linux machines (#12)Maxime Chevalier-Boisvert
* 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-20Implement greedy versioning. Refactor versioning logic. (#10)Maxime Chevalier-Boisvert
* Implement eager versioning. Refactor versioning logic. * Add --version-limit and --greedy-versioning command-line args
2021-10-20cYjitCodeComment is only defined if we're not in debugging modeAaron Patterson
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-20Malloc branch entries (#112)Maxime Chevalier-Boisvert
* Malloc branch entries * Add ASM comment for stack overflow check * WIP * Fix branch GC code. Add rb_darray_remove_unordered(). * Fix block end_pos after branch rewriting. Remove dst_patched bits.
2021-10-20YJIT: Fancier opt_getinlinecacheAlan Wu
Make sure `opt_getinlinecache` is in a block all on its own, and invalidate it from the interpreter when `opt_setinlinecache`. It will recompile with a filled cache the second time around. This lets YJIT runs well when the IC for constant is cold.