aboutsummaryrefslogtreecommitdiffstats
path: root/yjit.h
Commit message (Collapse)AuthorAgeFilesLines
* Rename --jit to --mjit (#5248)Takashi Kokubun2021-12-131-0/+7
| | | | | | | | | | | | | | | * Rename --jit to --mjit [Feature #18349] * Fix a few more --jit references * Fix MJIT Actions * More s/jit/mjit/ and re-introduce --disable-jit * Update NEWS.md * Fix test_bug_reporter_add
* YJIT: Fix incomplete invalidation from opt_setinlinecacheAlan Wu2021-12-061-1/+1
| | | | | | | | | | | | | | | | As part of YJIT's strategy for promoting Ruby constant expressions into constants in the output native code, the interpreter calls rb_yjit_constant_ic_update() from opt_setinlinecache. The block invalidation loop indirectly calls rb_darray_remove_unordered(), which does a shuffle remove. Because of this, looping with an incrementing counter like done previously can miss some elements in the array. Repeatedly invalidate the first element instead. The bug this commit resolves does not seem to cause crashes or divergent behaviors. Co-authored-by: Jemma Issroff <jemmaissroff@gmail.com>
* Add --yjit-no-type-prop so we can test YJIT without type propagation (#5135)Maxime Chevalier-Boisvert2021-11-181-0/+3
| | | | | | | * Add --yjit-no-type-prop so we can test YJIT without type propagation * Fix typo in command line option * Leave just two test workflows enable for YJIT
* Update YJIT code owners. Revert accidental commit.Maxime Chevalier-Boisvert2021-10-251-1/+1
|
* Test PRMaxime Chevalier-Boisvert2021-10-251-1/+1
|
* Move YJIT internal macros away from yjit.h. Tweak styleAlan Wu2021-10-201-26/+4
| | | | | Since this file is exposed to the rest of the codebase and they don't really need to know about things like PLATFORM_SUPPORTED_P.
* Tweak mjit_exec() to remove YJIT symbol exportsAlan Wu2021-10-201-2/+0
| | | | | | | | We were exporting a couple of symbols in yjit.h because they could be used by code generated by MJIT. We don't want MJIT calling into YJIT code anyways so let's stop exporting them to libruby.so. Also adjust indentation and comments in mjit_exec().
* Put YJIT into a single compilation unitAlan Wu2021-10-201-4/+4
| | | | | | | | | | | | | | | | | | | | | 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?
* Fix changes from rebaseNoah Gibbs2021-10-201-0/+3
|
* Count interpreter instructions when -DYJIT_STATS=1Alan Wu2021-10-201-0/+6
| | | | | | | | | | The interpreter instruction count was enabled based on RUBY_DEBUG as opposed to YJIT_STATS. In builds with YJIT_STATS=1 but RUBY_DEBUG=0, the count was not available. Move YJIT_STATS in yjit.h where declarations are expoed to code outside of YJIT. Also reduce the changes made to the interpreter for calling into YJIT's instruction counting function.
* TracePoint supportAlan Wu2021-10-201-0/+1
| | | | | | | | | | | | | | | | | | | | | | 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.
* Make sure we can still compile with the JIT disabledAaron Patterson2021-10-201-0/+2
| | | | | | | 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.
* Always use `ret` to return to the interpreterAaron Patterson2021-10-201-1/+1
| | | | | | | | | | | | | | | | | | | | | 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.
* Try running with more YJIT options in CI to surface more bugsMaxime Chevalier-Boisvert2021-10-201-1/+1
|
* Increase default YJIT call threshold to 10. Add exec mem size arg. (#52)Maxime Chevalier-Boisvert2021-10-201-0/+3
|
* Implement greedy versioning. Refactor versioning logic. (#10)Maxime Chevalier-Boisvert2021-10-201-0/+8
| | | | | | * Implement eager versioning. Refactor versioning logic. * Add --version-limit and --greedy-versioning command-line args
* YJIT: Fancier opt_getinlinecacheAlan Wu2021-10-201-3/+2
| | | | | | | 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.
* Collect statistics about binding allocations / local variable setAaron Patterson2021-10-201-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit collects statistics about how many binding objects are allocated as well as the number of local variables set on bindings. Statistics are output along with other YJIT stats. Here is an example of the output: ``` ***YJIT: Printing runtime counters from yjit.rb*** Number of Bindings Allocated: 195 Number of locals modified through binding: 0 opt_send_without_block exit reasons: ivar_get_method 7515891 (40.4%) se_cc_klass_differ 3081330 (16.6%) iseq_argc_mismatch 1564578 ( 8.4%) se_receiver_not_heap 1557663 ( 8.4%) ic_empty 1407064 ( 7.6%) optimized_method 995823 ( 5.4%) iseq_not_simple 819413 ( 4.4%) alias_method 706972 ( 3.8%) bmethod 685253 ( 3.7%) callsite_not_simple 225983 ( 1.2%) kw_splat 25999 ( 0.1%) ivar_set_method 902 ( 0.0%) cfunc_toomany_args 394 ( 0.0%) refined_method 42 ( 0.0%) cfunc_ruby_array_varg 29 ( 0.0%) invalid_cme 4 ( 0.0%) leave exit reasons: se_finish_frame 4067107 (100.0%) se_interrupt 24 ( 0.0%) getinstancevariable exit reasons: undef 121177 (100.0%) idx_out_of_range 5 ( 0.0%) opt_aref exit reasons: (all relevant counters are zero) compiled_iseq_count: 3944 main_block_code_size: 1.1 MiB side_block_code_size: 0.6 MiB vm_insns_count: 1137268516 yjit_exec_insns_count: 414015644 ratio_in_yjit: 26.7% avg_len_in_yjit: 7.5 total_exit_count: 55491789 most frequent exit op: opt_send_without_block: 18587628 (33.5%) opt_getinlinecache: 11075822 (20.0%) send: 4949300 (8.9%) leave: 4067131 (7.3%) defined: 3975196 (7.2%) setinstancevariable: 3567315 (6.4%) invokesuper: 2982163 (5.4%) getblockparamproxy: 2168852 (3.9%) opt_nil_p: 2104524 (3.8%) opt_aref: 2013858 (3.6%) ``` Running RailsBench allocates 195 binding objects but doesn't set any local variables.
* Get rid of dependency on rb_call_cacheAlan Wu2021-10-201-1/+3
|
* Yet Another Ruby JIT!Jose Narvaez2021-10-201-0/+61
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.