summaryrefslogtreecommitdiff
path: root/yjit_iface.h
AgeCommit message (Collapse)Author
2021-11-04YJIT code pages refactoring for code GC (#5073)Maxime Chevalier-Boisvert
* New code page allocation logic * Fix leaked globals * Fix leaked symbols, yjit asm tests * Make COUNTED_EXIT take a jit argument, so we can eliminate global ocb * Remove extra whitespace * Change block start_pos/end_pos to be pointers instead of uint32_t * Change branch end_pos and start_pos to end_addr, start_addr Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2021-10-20Fix non RUBY_DEBUG build warningsAlan Wu
On non RUBY_DEBUG builds, assert() compiles to nothing and the compiler warns about uninitialized variables in those code paths. Replace those asserts with rb_bug() to fix the warnings and do the assert in all builds. Since yjit_asm_tests.c compiles outside of Ruby, it needed a distinct version of rb_bug(). Also put YJIT_STATS check for function delcaration that is only defined in YJIT_STATS builds.
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 counter names for getblockparamproxy. Print in --yjit-stats.Maxime Chevalier-Boisvert
2021-10-20Add counted side exit to getblockparamproxyeileencodes
This is so we know the specific reason we're exiting this instruction. Co-authored-by: Aaron Patterson tenderlove@ruby-lang.org
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-20Break up callsite_not_simple into multiple cases.Noah Gibbs
2021-10-20Add a slowpath for opt_getinlinecacheAlan Wu
Before this change, when we encounter a constant cache that is specific to a lexical scope, we unconditionally exit. This change falls back to the interpreter's cache in this situation. This should help constant expressions in `class << self`, which is popular at Shopify due to the style guide. This change relies on the cache being warm while compiling to detect the need for checking the lexical scope for simplicity.
2021-10-20Try to break the code page refactoring into smaller stepsMaxime Chevalier-Boisvert
2021-10-20Add counters for tracking invalidationsAlan Wu
2021-10-20Compile out declaration for runtime stats on non stats buildsAlan Wu
Checked on default build, RUBY_DEBUG build, and YJIT_STATS build.
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-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-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-20Make sure that there is always an index table entry for getivarsMaxime Chevalier-Boisvert
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-20Use cmov to handle Qundef case in getivar instead of side-exitMaxime Chevalier-Boisvert
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-20Add a guard that we start executing on the first PCAaron Patterson
Methods with optional parameters don't always start executing at the first PC, but we compile all methods assuming that they do. This commit adds a guard to ensure that we're actually starting at the first PC for methods with optional params
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-20Code review for expandarray and testsKevin Newton
2021-10-20Implement expandarrayKevin Deisz
2021-10-20Remove seven YJIT counters that are no longer used.Noah Gibbs
2021-10-20Convert yjit static stat variables to countersNoah Gibbs
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-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-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-20Implement calls to methods with simple optional paramsAlan Wu
* Implement calls to methods with simple optional params * Remove unnecessary MJIT_STATIC See comment for MJIT_STATIC. I added it not knowing whether it's required because the function next to it has it. Don't use it and wait for problems to come up instead. * Better naming, some comments * Count bailing on kw only iseqs On railsbench: ``` opt_send_without_block exit reasons: bmethod 59729 (27.7%) optimized_method 59137 (27.5%) iseq_complex_callee 41362 (19.2%) alias_method 33346 (15.5%) callsite_not_simple 19170 ( 8.9%) iseq_only_keywords 1300 ( 0.6%) kw_splat 1299 ( 0.6%) cfunc_ruby_array_varg 18 ( 0.0%) ```
2021-10-20Improve set instance variableAaron Patterson
This commit improves the set ivar implementation.
2021-10-20Merge pull request #114 from Shopify/yjit-dup-commentsMaxime Chevalier-Boisvert
YJIT: Avoid adding duplicate code comments
2021-10-20YJIT: implement calls to ivar getter methodsAlan Wu
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.
2021-10-20YJIT: add comments to disassemblyAlan Wu
Introduce a new macro `ADD_COMMENT(cb, comment)` that records a comment for the current write position in the code block. Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Co-authored-by: Aaron Patterson <aaron.patterson@shopify.com>
2021-10-20Collect statistics about binding allocations / local variable setAaron Patterson
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.
2021-10-20Fix GCC warningsAlan Wu
Mostly unused and uninitialized warnings here and there
2021-10-20Track interpreter return as an exit reason for leave instrMaxime Chevalier-Boisvert
2021-10-20Introduce yjit_guard_known_klass()Alan Wu
2021-10-20Get rid of dependency on rb_call_cacheAlan Wu
2021-10-20YJIT: hash specialization for opt_arefAlan Wu
Make it lazy and add a hash specialization in addition to the array specialization.
2021-10-20Exit reason breakdown for opt_arefAlan Wu
2021-10-20YJIT: lazy polymorphic getinstancevariableAlan Wu
Lazily compile out a chain of checks for different known classes and whether `self` embeds its ivars or not. * Remove trailing whitespaces * Get proper addresss in Capstone disassembly * Lowercase address in Capstone disassembly Capstone uses lowercase for jump targets in generated listings. Let's match it. * Use the same successor in getivar guard chains Cuts down on duplication * Address reviews * Fix copypasta error * Add a comment
2021-10-20Include ruby/ruby.h before vm_core.hAlan Wu
This is how vm.c does it, and if we don't follow it in yjit compilation units, rb_vm_t would have a conflicting size.
2021-10-20Make Blocks depend on BOPSAaron Patterson
When a BOP is redefined, the BOP redefinition callback will invalidate any blocks that depend on BOPS. This allows us to eliminate runtime checks for BOP redefinition.
2021-10-20Yet Another Ruby JIT!Jose Narvaez
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.