summaryrefslogtreecommitdiff
path: root/tool/ruby_vm/views/_mjit_compile_send.erb
AgeCommit message (Collapse)Author
2019-11-07extend rb_call_cache卜部昌平
Prior to this changeset, majority of inline cache mishits resulted into the same method entry when rb_callable_method_entry() resolves a method search. Let's not call the function at the first place on such situations. In doing so we extend the struct rb_call_cache from 44 bytes (in case of 64 bit machine) to 64 bytes, and fill the gap with secondary class serial(s). Call cache's class serials now behavies as a LRU cache. Calculating ------------------------------------- ours 2.7 2.6 vm2_poly_same_method 2.339M 1.744M 1.369M i/s - 6.000M times in 2.565086s 3.441329s 4.381386s Comparison: vm2_poly_same_method ours: 2339103.0 i/s 2.7: 1743512.3 i/s - 1.34x slower 2.6: 1369429.8 i/s - 1.71x slower Notes: Merged: https://github.com/ruby/ruby/pull/2583
2019-10-24Combine call info and cache to speed up method invocationAlan Wu
To perform a regular method call, the VM needs two structs, `rb_call_info` and `rb_call_cache`. At the moment, we allocate these two structures in separate buffers. In the worst case, the CPU needs to read 4 cache lines to complete a method call. Putting the two structures together reduces the maximum number of cache line reads to 2. Combining the structures also saves 8 bytes per call site as the current layout uses separate two pointers for the call info and the call cache. This saves about 2 MiB on Discourse. This change improves the Optcarrot benchmark at least 3%. For more details, see attached bugs.ruby-lang.org ticket. Complications: - A new instruction attribute `comptime_sp_inc` is introduced to calculate SP increase at compile time without using call caches. At compile time, a `TS_CALLDATA` operand points to a call info struct, but at runtime, the same operand points to a call data struct. Instruction that explicitly define `sp_inc` also need to define `comptime_sp_inc`. - MJIT code for copying call cache becomes slightly more complicated. - This changes the bytecode format, which might break existing tools. [Misc #16258] Notes: Merged: https://github.com/ruby/ruby/pull/2564
2019-07-03Revert "Avoid corrupting VM stack on inlined setlocal"Koichi Sasada
This reverts commit ea30dd702512ff9df34fe8c71c825f8f901bf5b1. because it fails when VM_CHECK_MODE=1.
2019-07-02Avoid corrupting VM stack on inlined setlocalTakashi Kokubun
setlocal relies on cfp->ep, and frame-omitted method inlining introduced in Ruby 2.7 kept it wrong. This change might slow down frame-omitted method inlining for cfp->ep manipulation, and it obviously complicates the implementaion more. By introducing an optimization that changes Ruby's local variable to C local variable, we could optimize it and simplify the cfp->ep manipulation later. [Bug #15971]
2019-04-20Invalidate JIT-ed code if ISeq is moved by GC.compactk0kubun
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67638 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-16Recompile without method inliningk0kubun
if cancel happens in an inlined method. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67575 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-16Introduce frame-omitted method inliningk0kubun
for ISeq including only leaf and no-handles_sp insns except leaf. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67574 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-16Implement single-level basic method inlining in JITk0kubun
"Basic" means it does not omit a call frame. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67572 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-14Share optimization cancel handlersk0kubun
$ benchmark-driver benchmark.yml --rbenv='before --jit;after --jit' -v --output=all --repeat-count=12 before --jit: ruby 2.7.0dev (2019-04-14 trunk 67549) +JIT [x86_64-linux] after --jit: ruby 2.7.0dev (2019-04-14 trunk 67549) +JIT [x86_64-linux] last_commit=Share optimization cancel handlers Calculating ------------------------------------- before --jit after --jit Optcarrot Lan_Master.nes 69.55360655447375 74.15329176797863 fps 73.74545038318978 79.60903046141544 75.85637357897092 82.00930075612054 77.10594124022951 82.56228187301674 78.67350527368366 83.37512204205953 79.97235230767613 83.41521927993719 81.03050342478066 84.20227901852776 81.61308297895094 84.73733526226468 82.06805141753206 85.27884867863791 82.46493179193394 85.36558922650367 83.85259832896313 85.39993587223481 84.02325292922997 85.63649355214602 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67550 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-14Recompile JIT-ed code without optimizationk0kubun
based on inline cache when JIT cancel happens by that. This feature was in the original MJIT implementation by Vladimir, but on merging MJIT to Ruby it was removed for simplification. This commit adds the functionality again for the following benchmark: https://github.com/benchmark-driver/misc/blob/52f05781f65467baf895bf6ba79d172c9b0826fd/concurrent-map/bench.rb (shown float is duration seconds. shorter is better) * Before ``` $ INHERIT=0 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] -- 1.6507579649914987 $ INHERIT=0 ruby -v --jit bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] -- 1.5091587850474752 $ INHERIT=1 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] -- 1.6124781150138006 $ INHERIT=1 ruby --jit -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] -- 1.7495657080435194 # <-- this ``` * After ``` $ INHERIT=0 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.653559010999743 $ INHERIT=0 ruby --jit -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.4738391840364784 $ INHERIT=1 ruby -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.645227018976584 $ INHERIT=1 ruby --jit -v bench.rb ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux] last_commit=Recompile JIT-ed code without optimization -- 1.523708809982054 # <-- this ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67530 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-06Fix typo in a comment [ci skip]k0kubun
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-29Add debug counters for MJIT cancelk0kubun
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67379 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-25Prefer using vm_base_ptr rather than cfp->bpk0kubun
in MJIT implementation. This allows us to drop cfp->bp by just modifying vm_base_ptr in the future. No performance impact: $ benchmark-driver benchmark.yml --rbenv='before::before --disable-gems --jit;bp_::after --disable-gems --jit;vm_env_ptr::ruby-svn --disable-gems --jit' -v --output=all --repeat-count=12 before: ruby 2.7.0dev (2019-03-24 trunk 67341) +JIT [x86_64-linux] bp_: ruby 2.7.0dev (2019-03-24 trunk 67342) +JIT [x86_64-linux] vm_env_ptr: ruby 2.7.0dev (2019-03-25 trunk 67343) +JIT [x86_64-linux] last_commit=Prefer using vm_base_ptr rather than cfp->bp Calculating ------------------------------------- before bp_ vm_env_ptr Optcarrot Lan_Master.nes 77.15059205092646 70.18873044267853 69.62171387083328 fps 78.75767783870441 77.49867689173411 75.43496867709587 79.60102690369321 77.78037687683523 79.36688927929428 80.25144236638835 78.74729849101701 80.42363742291455 82.22375417165489 80.44265482494045 80.90287243299306 82.29166786292619 80.51740049420938 81.81153053252902 83.35386925305345 80.91054205210609 81.93562989125176 83.39770634366975 81.34550754145043 82.24544621470430 83.88523450309972 81.60698516017347 82.76801860263230 84.17553130135879 82.69615943446324 83.02530407910871 84.42132328119858 83.00969158037691 83.19968539409922 84.60731429793329 83.32703363300098 83.81352746019631 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67344 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-25use cfp->bp more.ko1
cfp->bp was (re-)introduced by Kokubun san, but VM doesn't use it because I (ko1) want to remove it in a future. But using it make leave instruction fast because of sp consisntency check. So now VM uses cfp->bp. To use cfp->bp, I checked the value and I found that it is not a "initial value of sp" but a "initial value of ep". Fix this problem and fix all bp references (this is why bp is renamed to bp_). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67342 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-21Check argument_arity_error condition in inlinable_iseq_pk0kubun
to avoid inlining a method call when it becomes argument_arity_error, fixing a potential bug. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67330 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-27delete emacs mode lines [ci skip]shyouhei
These settings are now covered by .dir-locals.el. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26Support targetting TracePoint [Feature #15289]ko1
* vm_trace.c (rb_tracepoint_enable_for_target): support targetting TracePoint. [Feature #15289] Tragetting TracePoint is only enabled on specified method, proc and so on, example: `tp.enable(target: code)`. `code` should be consisted of InstructionSeuqnece (iseq) (RubyVM::InstructionSeuqnece.of(code) should not return nil) If code is a tree of iseq, TracePoint is enabled on all of iseqs in a tree. Enabled tragetting TracePoints can not enabled again with and without target. * vm_core.h (rb_iseq_t): introduce `rb_iseq_t::local_hooks` to store local hooks. `rb_iseq_t::aux::trace_events` is renamed to `global_trace_events` to contrast with `local_hooks`. * vm_core.h (rb_hook_list_t): add `rb_hook_list_t::running` to represent how many Threads/Fibers are used this list. If this field is 0, nobody using this hooks and we can delete it. This is why we can remove code from cont.c. * vm_core.h (rb_vm_t): because of above change, we can eliminate `rb_vm_t::trace_running` field. Also renamed from `rb_vm_t::event_hooks` to `global_hooks`. * vm_core.h, vm.c (ruby_vm_event_enabled_global_flags): renamed from `ruby_vm_event_enabled_flags. * vm_core.h, vm.c (ruby_vm_event_local_num): added to count enabled targetting TracePoints. * vm_core.h, vm_trace.c (rb_exec_event_hooks): accepts hook list. * vm_core.h (rb_vm_global_hooks): added for convinience. * method.h (rb_method_bmethod_t): added to maintain Proc and `rb_hook_list_t` for bmethod (defined by define_method). * prelude.rb (TracePoint#enable): extracet a keyword parameter (because it is easy than writing in C). It calls `TracePoint#__enable` internal method written in C. * vm_insnhelper.c (vm_trace): check also iseq->local_hooks. * vm.c (invoke_bmethod): check def->body.bmethod.hooks. * vm.c (hook_before_rewind): check iseq->local_hooks and def->body.bmethod.hooks before rewind by exception. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30_mjit_compile_send.erb: do not inline tailcall ISeqk0kubun
because it's not supported by this file. Also, shared `def_iseq_ptr` instead of copying the main definition of it. vm_core.h: moved `def_iseq_ptr` to this place. added `inline` to avoid compiler warnings since it's not used in some files including vm_core.h. vm_insnhelper.c: moved `def_iseq_ptr` to vm_core.h. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-23_mjit_compile_send.erb: fix wrong cc usagesk0kubun
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65318 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-21mjit.c: remove wrongly-committed debug codek0kubun
mistake in r65279. === Optcarrot Benchmark === $ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems --jit;after::after --disable-gems --jit' -v --repeat-count 24 before: ruby 2.6.0dev (2018-10-21 trunk 65277) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-21 trunk 65279) +JIT [x86_64-linux] last_commit=mjit.c: remove wrongly-committed debug code Calculating ------------------------------------- before after Optcarrot Lan_Master.nes 85.008 86.078 fps Comparison: Optcarrot Lan_Master.nes after: 86.1 fps before: 85.0 fps - 1.01x slower git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65280 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-21mjit.c: copy call cache values to MJIT workerk0kubun
same as r65275 but for call cache. === Optcarrot Benchmark === $ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems --jit;after::after --disable-gems --jit' -v --repeat-count 24 before: ruby 2.6.0dev (2018-10-21 trunk 65277) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-10-21 trunk 65277) +JIT [x86_64-linux] last_commit=mjit.c: copy call cache values to MJIT worker Calculating ------------------------------------- before after Optcarrot Lan_Master.nes 85.372 85.359 fps Comparison: Optcarrot Lan_Master.nes before: 85.4 fps after: 85.4 fps - 1.00x slower git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-21_mjit_compile_send.erb: don't split send_guardk0kubun
to another file, because it's no longer shared. It was created when attr_reader was inlined but it's no longer included. common.mk: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65276 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-24_mjit_compile_send.erb: remove TODO comment solved [ci skip]k0kubun
which was solved by r64820 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64821 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-24_mjit_compile_send.erb: refactor code to setup iseqk0kubun
by sharing vm_call_iseq_setup_normal. This is a retry of r64280. vm_insnhelper.c: Remove unused argument `ci` and pass `me` instead of `cc` to share this with JIT. Declare this with ALWAYS_INLINE to make sure this function is inlined in JIT. tool/mk_call_iseq_optimized.rb: deal with the interface change of vm_call_iseq_setup_normal. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64820 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-18vm_insnhelper.h: rename CI_SET_FASTPATH to CC_SET_FASTPATHk0kubun
because it's actually setting fastpath to cc instead of ci since r51903. vm_insnhelper.c: ditto mjit_compile.c: ditto tool/ruby_vm/views/_mjit_compile_send.erb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64772 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-13Revert "vm_insnhelper.h: simplify EXEC_EC_CFP implementation"k0kubun
This reverts commit r64711, because EXEC_EC_CFP on JIT-ed code does not call jit_func with the patch when catch_except_p is true. It wasn't intentional. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-13vm_insnhelper.h: simplify EXEC_EC_CFP implementationk0kubun
and possibly memory access for iseq->body may be reduced. No significant impact for performance on Optcarrot. * before fps: 55.03865935187656 fps: 57.16854675983188 fps: 57.672458407661765 fps: 58.28989837869383 fps: 58.80503815099268 fps: 59.068054176528534 fps: 59.55736806358244 fps: 61.01018920533034 fps: 63.34167049232186 fps: 65.20575018321766 fps: 65.46758316561318 * after fps: 55.21860411005677 fps: 55.34840351179166 fps: 58.23666596747484 fps: 59.71987124578901 fps: 61.131485120234935 fps: 61.279905164649485 fps: 61.66060774175459 fps: 64.11215576508765 fps: 64.63699742853154 fps: 65.28260058920769 fps: 65.85447796482678 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64711 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-11_mjit_compile_insn.erb: move pc on JIT cancelk0kubun
if and only if it's not moved yet, to avoid potential bugs in the future. _mjit_compile_send.erb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64687 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-12vm_insnhelper.c: revert r64280k0kubun
This commit caused test-all failure with --jit-wait. I don't know the reason yet, but let me revert it to normalize CI. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64314 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-11vm_args.c: stop requiring `calling` in vm_caller_setup_arg_blockk0kubun
_mjit_compile_send.erb: simplify code using the change insns.def: adapt to the interface change git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64281 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-11_mjit_compile_send.erb: refactor to share vm_call_iseq_setup_normalk0kubun
implementation. This had no major performance impact by effort to keep them inlined. vm_insnhelper.c: ditto mjit_compile.c: just update the comment about opt_pc=0 assumption git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64280 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-19mjit_compile.c: reduce sp motion on JITk0kubun
This retries r62655, which was reverted at r63863 for r63763. tool/ruby_vm/views/_mjit_compile_insn.erb: revert the revert. tool/ruby_vm/views/_mjit_compile_insn_body.erb: ditto. tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb: ditto. tool/ruby_vm/views/_mjit_compile_send.erb: ditto. tool/ruby_vm/views/mjit_compile.inc.erb: ditto. tool/ruby_vm/views/_insn_entry.erb: revert half of r63763. The commit was originally reverted since changing pc motion was bad for tracing, but changing sp motion was totally fine. For JIT, I wanna resurrect the sp motion change in r62051. tool/ruby_vm/models/bare_instructions.rb: ditto. insns.def: ditto. vm_insnhelper.c: ditto. vm_insnhelper.h: ditto. * benchmark $ benchmark-driver benchmark.yml --rbenv 'before;after;before --jit;after --jit' --repeat-count 12 -v before: ruby 2.6.0dev (2018-07-19 trunk 63998) [x86_64-linux] after: ruby 2.6.0dev (2018-07-19 add-sp 63998) [x86_64-linux] last_commit=mjit_compile.c: reduce sp motion on JIT before --jit: ruby 2.6.0dev (2018-07-19 trunk 63998) +JIT [x86_64-linux] after --jit: ruby 2.6.0dev (2018-07-19 add-sp 63998) +JIT [x86_64-linux] last_commit=mjit_compile.c: reduce sp motion on JIT Calculating ------------------------------------- before after before --jit after --jit Optcarrot Lan_Master.nes 51.354 50.238 70.010 72.139 fps Comparison: Optcarrot Lan_Master.nes after --jit: 72.1 fps before --jit: 70.0 fps - 1.03x slower before: 51.4 fps - 1.40x slower after: 50.2 fps - 1.44x slower git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-17revert r63988k0kubun
Due to trunk-mjit CI failures: http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1130097 http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1130196 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63991 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-17mjit_compile.c: resurrect local variable stackk0kubun
This optimization was reverted on r63863, but this commit resurrects the optimization to skip some sp motions on JIT execution. tool/ruby_vm/views/_mjit_compile_insn_body.erb: ditto tool/ruby_vm/views/_mjit_compile_insn.erb: ditto insns.def: resurrect handles_frame as handles_stack, which was deleted on r63763. tool/ruby_vm/models/bare_instructions.rb: ditto vm_insnhelper.c: prevent moving sp outside insns.def to allow modifying it by JIT. * Optcarrot benchmark $ benchmark-driver benchmark.yml --rbenv 'before --jit;after --jit' --repeat-count 12 -v before --jit: ruby 2.6.0dev (2018-07-17 trunk 63987) +JIT [x86_64-linux] after --jit: ruby 2.6.0dev (2018-07-17 local-stack 63987) +JIT [x86_64-linux] last_commit=mjit_compile.c: resurrect local variable stack Calculating ------------------------------------- before --jit after --jit Optcarrot Lan_Master.nes 70.518 72.144 fps Comparison: Optcarrot Lan_Master.nes after --jit: 72.1 fps before --jit: 70.5 fps - 1.02x slower git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63988 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-05revert r62655 for r63763k0kubun
r63655 was tightly coupled to handle_frames and some assumptions seems to have been broken by r63763. To partially resolve Bug#14892, this reverts the optimization for now. I want to make MJIT CI happy first and then I'll probably retry r63655 by partially reverting r63763 for sp changes. The skipped test is not fixed yet. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63863 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-05-17_mjit_compile_send.erb: disable attr_reader inlinek0kubun
for now, which was committed in r63333. Currently trunk's JIT seems to have some wrong behaviors, and this is the most suspicious culprit of them for now. In the future, I may have a strict test environment to detect the cause, but there's no enough time to test this until preview2. So let me revert this and see how it goes after this. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-05-09_mjit_compile_send.erb: revert r63350k0kubun
Revert "_mjit_compile_send.erb: inline recursive call" I reverted r63360 in r63379, but the errors were reproductive from r63350. So I need to revert this. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63382 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-05-07_mjit_compile_send.erb: inline recursive callk0kubun
mjit_compile.c: propagate funcname to compile_insn test_jit.rb: add test covering this behavior * Benchmark ``` require 'benchmark_driver' Benchmark.driver(runner: :time, repeat_count: 4) do |x| x.prelude %{ def fib(x) return x if x == 0 || x == 1 fib(x-1) + fib(x-2) end } x.report 'fib(40)' x.loop_count 1 x.rbenv( 'before,--jit', 'before', 'after,--jit', 'after', ) x.verbose end ``` ``` before,--jit: ruby 2.6.0dev (2018-05-08 trunk 63349) +JIT [x86_64-linux] before: ruby 2.6.0dev (2018-05-08 trunk 63349) [x86_64-linux] after,--jit: ruby 2.6.0dev (2018-05-08 trunk 63349) +JIT [x86_64-linux] last_commit=_mjit_compile_send.erb: inline recursive call after: ruby 2.6.0dev (2018-05-08 trunk 63349) [x86_64-linux] last_commit=_mjit_compile_send.erb: inline recursive call Calculating ------------------------------------- before,--jit before after,--jit after fib(40) 2.886 8.685 2.562 8.800 s - 1.000 times Comparison: fib(40) after,--jit: 2.6 s before,--jit: 2.9 s - 1.13x slower before: 8.7 s - 3.39x slower after: 8.8 s - 3.44x slower ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63350 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-05-03_mjit_compile_send.erb: retry inlining attr_readerk0kubun
This reverts r63249 (revert r63212) and fixes a bug in it. The test to prevent the bug is added as well. vm_insnhelper.c: add `index` argument to vm_getivar. The argument is created so that MJIT can pass the value of `cc->aux.index` on compilation time. The cache invalidation in _mjit_compile_send_guard.erb is only working for the cache value on compilation time. Note: As `index` is always passed as constant and it's force-inlined, the performance of `vm_getivar` won't be degraded in VM. _mjit_compile_send_guard.erb: New. Used to invalidate inlined values of cc. common.mk: update dependencies for _mjit_compile_send_guard.erb git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63333 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-29_mjit_compile_send.erb: fix pointer conversion warningk0kubun
/var/folders/b0/9hgj_tyx10zgkcbyx3_j2dlr0000gn/T//_ruby_mjit_p72619u0.c:37:58: warning: incompatible integer to pointer conversion passing 'long' to parameter of type 'const struct rb_call_info *' [-Wint-conversion] vm_caller_setup_arg_block(ec, reg_cfp, &calling, 0x7ff6b2e10ca0, 0x7ff6b3847108, FALSE); ^~~~~~~~~~~~~~ /Users/kokubun/.rbenv/versions/ruby-svn/include/ruby-2.6.0/x86_64-darwin16/rb_mjit_min_header-2.6.0.h:15613:66: note: passing argument to parameter 'ci' here struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super) ^ /var/folders/b0/9hgj_tyx10zgkcbyx3_j2dlr0000gn/T//_ruby_mjit_p72619u0.c:37:74: warning: incompatible integer to pointer conversion passing 'long' to parameter of type 'rb_iseq_t *' (aka 'struct rb_iseq_struct *') [-Wint-conversion] vm_caller_setup_arg_block(ec, reg_cfp, &calling, 0x7ff6b2e10ca0, 0x7ff6b3847108, FALSE); ^~~~~~~~~~~~~~ /Users/kokubun/.rbenv/versions/ruby-svn/include/ruby-2.6.0/x86_64-darwin16/rb_mjit_min_header-2.6.0.h:15613:81: note: passing argument to parameter 'blockiseq' here struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super) ^ 2 warnings generated. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63298 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-23revert r63212k0kubun
except test_jit.rb. In some situations, this generates a wrong code. I'll add a test for it later but let me revert this to make it work for now. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63249 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-20_mjit_compile_send.erb: inline attr_reader callk0kubun
_mjit_compile_send_guard.erb: carve out the shared logic to invalidate inlined method call common.mk: update dependency for this change test_jit.rb: add test for attr_reader optimization * Benchmark ``` require 'benchmark_driver' Benchmark.driver do |x| x.prelude %{ class C attr_reader :a def initialize @a = 1 end end o = C.new def l o i = 0 while i < 1000000 o.a i += 1 end end } x.report 'aread', %{ l o } x.loop_count 1000 x.rbenv 'before', 'before,--jit', 'after,--jit' x.verbose end ``` ``` before: ruby 2.6.0dev (2018-04-20 trunk 63211) [x86_64-linux] before,--jit: ruby 2.6.0dev (2018-04-20 trunk 63211) +JIT [x86_64-linux] after,--jit: ruby 2.6.0dev (2018-04-20 trunk 63211) +JIT [x86_64-linux] last_commit=_mjit_compile_send.erb: inline attr_reader call Calculating ------------------------------------- before before,--jit after,--jit aread 54.597 122.894 218.574 i/s - 1.000k times in 18.316102s 8.137089s 4.575106s Comparison: aread after,--jit: 218.6 i/s before,--jit: 122.9 i/s - 1.78x slower before: 54.6 i/s - 4.00x slower ``` * Optcarrot A little made faster? fps: 71.35 -> 72.11 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63212 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-19_mjit_compile_send.erb: simplify control flowk0kubun
to introduce additional optimization for another `cc->me->def->type` later. I carved out the `cc->me->def->type == VM_METHOD_TYPE_ISEQ` part because I wanted to check other types as well. mjit_compile.c: drop get_iseq_if_available and define simplified version of it, has_valid_method_type. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-06_mjit_compile_pc_and_sp.erb: skip moving pck0kubun
on !body->catch_except_p. We need to move pc only when JIT execution is canceled if the frame does not catch an exception. _mjit_compile_insn.erb: lazily move pc for such optimized case _mjit_compile_insn_body.erb: ditto _mjit_compile_send.erb: ditto * Optcarrot benchmark (--jit) Before: 65.31 fps After: 67.82 fps git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-04mjit_compile.c: use local variables for stackk0kubun
if catch_except_p is FALSE. If catch_except_p is TRUE, stack values should be on VM's stack when exception is thrown and the JIT-ed frame is re-executed by VM's exception handler. If it's FALSE, the JIT-ed frame won't be re-executed and don't need to keep values on VM's stack. Using local variables allows us to reduce cfp->sp motion. Moving cfp->sp is needed only for insns whose handles_frame? is false. So it improves performance. _mjit_compile_insn.erb: Prepare `stack_size` variable for GET_SP, STACK_ADDR_FROM_TOP, TOPN macros. Share pc and sp motion partial view. Use cancel handler created in mjit_compile.c. _mjit_compile_send.erb: ditto. Also, when iseq->body->catch_except_p is TRUE, this stops to call mjit_exec directly. I described the reason in vm_insnhelper.h's comment for EXEC_EC_CFP. _mjit_compile_pc_and_sp.erb: Shared logic for moving sp and pc. As you can see from thsi file, when status->local_stack_p is TRUE and insn.handles_frame? is false, moving sp is skipped. But if insn.handles_frame? is true, values should be rolled back to VM's stack. common.mk: add dependency for the file _mjit_compile_insn_body.erb: Set sp value before canceling JIT on DISPATCH_ORIGINAL_INSN. Replace GET_SP, STACK_ADDR_FROM_TOP, TOPN macros for the case ocal_stack_p is TRUE and insn.handles_frame? is false. In that case, values are not available on VM's stack and those macros should be replaced. mjit_compile.inc.erb: updated comments of macros which are supported by JIT compiler. All references to `cfp->sp` should be replaced and thus INC_SP, SET_SV, PUSH are no longer supported for now, because they are not used now. vm_exec.h: moved EXEC_EC_CFP definition to vm_insnhelper.h because it's tighly coupled to CALL_METHOD. vm_insnhelper.h: Have revised EXEC_EC_CFP definition moved from vm_exec.h. Now it triggers mjit_exec for VM, and has the guard for catch_except_p on JIT-ed code. See comments for details. CALL_METHOD delegates triggering mjit_exec to EXEC_EC_CFP. insns.def: Stopped using EXEC_EC_CFP for the case we don't want to trigger mjit_exec. Those insns (defineclass, opt_call_c_function) are not supported by JIT and it's safe to use RESTORE_REGS(), NEXT_INSN(). expandarray is changed to pass GET_SP() to replace the macro in _mjit_compile_insn_body.erb. vm_insnhelper.c: change to take sp for the above reason. [close https://github.com/ruby/ruby/pull/1828] This patch resurrects the performance which was attached in [Feature #14235]. * Benchmark Optcarrot (with configuration for benchmark_driver.gem) https://github.com/benchmark-driver/optcarrot $ benchmark-driver benchmark.yml --verbose 1 --rbenv 'before;before+JIT::before,--jit;after;after+JIT::after,--jit' --repeat-count 10 before: ruby 2.6.0dev (2018-03-04 trunk 62652) [x86_64-linux] before+JIT: ruby 2.6.0dev (2018-03-04 trunk 62652) +JIT [x86_64-linux] after: ruby 2.6.0dev (2018-03-04 local-variable.. 62652) [x86_64-linux] last_commit=mjit_compile.c: use local variables for stack after+JIT: ruby 2.6.0dev (2018-03-04 local-variable.. 62652) +JIT [x86_64-linux] last_commit=mjit_compile.c: use local variables for stack Calculating ------------------------------------- before before+JIT after after+JIT optcarrot 53.552 59.680 53.697 63.358 fps Comparison: optcarrot after+JIT: 63.4 fps before+JIT: 59.7 fps - 1.06x slower after: 53.7 fps - 1.18x slower before: 53.6 fps - 1.18x slower git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62655 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-03vm.c: add mjit_enable_p flagk0kubun
to count up total calls properly. Some places (especially CALL_METHOD) invoke mjit_exec twice for one method call. It would be problematic when debugging, or possibly it would result in a wrong profiling result. This commit doesn't have impact for performance: * Optcarrot benchmark ** before fps: 59.37757770848619 fps: 56.49998488958699 fps: 59.07900362739362 fps: 58.924749807695996 fps: 57.667905665594894 fps: 57.540021018385254 fps: 59.5518055679647 fps: 55.93831555148311 fps: 57.82685112863262 fps: 59.22391754481736 checksum: 59662 ** after fps: 58.461881158098194 fps: 59.32685183081354 fps: 54.11334310279802 fps: 59.2281560439788 fps: 58.60495705318312 fps: 55.696478648491045 fps: 58.49003452654724 fps: 58.387771929393224 fps: 59.24156772816439 fps: 56.68804731968107 checksum: 59662 * Discourse Your Results: (note for timings- percentile is first, duration is second in millisecs) ** before (without JIT) categories_admin: 50: 16 75: 17 90: 24 99: 37 home_admin: 50: 20 75: 20 90: 24 99: 42 topic_admin: 50: 16 75: 16 90: 18 99: 28 categories: 50: 36 75: 37 90: 45 99: 68 home: 50: 38 75: 40 90: 53 99: 92 topic: 50: 14 75: 15 90: 17 99: 26 ** after (without JIT) categories_admin: 50: 16 75: 16 90: 24 99: 36 home_admin: 50: 19 75: 20 90: 23 99: 41 topic_admin: 50: 16 75: 16 90: 19 99: 33 categories: 50: 35 75: 36 90: 44 99: 61 home: 50: 38 75: 40 90: 52 99: 101 topic: 50: 14 75: 15 90: 15 99: 24 ** before (with JIT) categories_admin: 50: 19 75: 23 90: 29 99: 44 home_admin: 50: 24 75: 26 90: 32 99: 46 topic_admin: 50: 20 75: 22 90: 27 99: 44 categories: 50: 41 75: 43 90: 51 99: 66 home: 50: 46 75: 49 90: 56 99: 68 topic: 50: 18 75: 19 90: 22 99: 31 ** after (with JIT) categories_admin: 50: 18 75: 21 90: 28 99: 42 home_admin: 50: 23 75: 25 90: 31 99: 51 topic_admin: 50: 19 75: 20 90: 24 99: 31 categories: 50: 41 75: 44 90: 52 99: 69 home: 50: 45 75: 48 90: 61 99: 88 topic: 50: 19 75: 20 90: 24 99: 33 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62641 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-11_mjit_compile_send.erb: resolve warnings on clangk0kubun
/var/folders/tp/g1f_46nj7md_d5_j799rfb140000gn/T//_ruby_mjit_p17396u162.c:2920:143: warning: incompatible integer to pointer conversion passing 'long' to parameter of type 'const VALUE *' (aka 'const unsigned long *') [-Wint-conversion] ...| VM_ENV_FLAG_LOCAL, calling.recv, calling.block_handler, 0x7fc14ceee660, 0x7fc14c870c00, argv + 0, 2, 3); ^~~~~~~~~~~~~~ /Users/k0kubun/.rbenv/versions/ruby-svn/include/ruby-2.6.0/x86_64-darwin16/rb_mjit_min_header-2.6.0.h:21299:21: note: passing argument to parameter 'pc' here const VALUE *pc, ^ /var/folders/tp/g1f_46nj7md_d5_j799rfb140000gn/T//_ruby_mjit_p17396u162.c:3073:31: warning: incompatible integer to pointer conversion passing 'long' to parameter of type 'const rb_iseq_t *' (aka 'const struct rb_iseq_struct *') [-Wint-conversion] vm_push_frame(ec, 0x7fc14c87d290, VM_FRAME_MAGIC_METHOD | VM_ENV_FLAG_LOCAL, calling.recv, ca... ^~~~~~~~~~~~~~ /Users/k0kubun/.rbenv/versions/ruby-svn/include/ruby-2.6.0/x86_64-darwin16/rb_mjit_min_header-2.6.0.h:21294:25: note: passing argument to parameter 'iseq' here const rb_iseq_t *iseq, ^ git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62368 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-11_mjit_compile_{insn,send}.erb: suppress warningsnobu
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62353 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-11_mjit_compile_send.erb: PRI_SERIALT_PREFIXnobu
* tool/ruby_vm/views/_mjit_compile_send.erb: `printf` modifier for `rb_serial_t` which may not be `long long`, and '%ll' may not be supported. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62351 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-10mjit_compile.c: original_body_iseqnobu
* mjit_compile.c (mjit_compile): name the original iseq pointer to eliminate magic numbers. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62340 b2dd03c8-39d4-4d8f-98ff-823fe69b080e