summaryrefslogtreecommitdiff
path: root/vm_insnhelper.h
Commit message (Collapse)AuthorAgeFilesLines
...
* remove assertion for hidden objects.ko12018-06-271-1/+1
| | | | | | | | | * vm_insnhelper.h (PUSH): r63763 increase "PUSH()" op and it reveals that there are hidden objects (at least T_IMEMO/iseq objects) are located on VM stack. Remove this check and I'll revisit it later. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63765 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* give up insn attr handles_frameshyouhei2018-06-271-2/+3
| | | | | | | | | | | | | | I introduced this mechanism in r62051 to speed things up. Later it was reported that the change causes problems. I searched for workarounds but nothing seemed appropriate. I hereby officially give it up. The idea to move ADD_PC around was a mistake. Fixes [Bug #14809] and [Bug #14834]. Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63763 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* NULL class Data_Wrap_Struct is not allowed.ko12018-06-191-1/+1
| | | | | | | | | | | * spec/ruby/optional/capi/typed_data_spec.rb: same as r63692. * spec/ruby/optional/capi/ext/typed_data_spec.c: ditto. * vm_insnhelper.h (PUSH): re-enable assertion to check hidden objects. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63694 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* remvoe assertion because rubyspec hit this assertko12018-06-181-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63688 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* hidden objects should not be pushed.ko12018-06-181-1/+12
| | | | | | | | * vm_insnhelper.h (PUSH): hidden objects (klass == 0) should not be pushed to a VM value stack. Add assertion for it. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63687 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* mjit_compile.c: use local variables for stackk0kubun2018-03-041-2/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* vm.c: add mjit_enable_p flagk0kubun2018-03-031-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* prefixed functions exported for mjitnobu2018-02-171-2/+6
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* mjit_compile.c: share the definition of macrosk0kubun2018-02-061-0/+8
| | | | | | | | | (IS_ARGS_SPLAT, IS_ARGS_KEYWORD) with vm_args.c. vm_args.c: share them with mjit_compile.c. vm_insnhelper.h: get those definitions, with CALLER_SETUP_ARG too git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62254 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* mjit_compile.c: merge initial JIT compilerk0kubun2018-02-041-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | which has been developed by Takashi Kokubun <takashikkbn@gmail> as YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>. This JIT compiler is designed to be a safe migration path to introduce JIT compiler to MRI. So this commit does not include any bytecode changes or dynamic instruction modifications, which are done in original MJIT. This commit even strips off some aggressive optimizations from YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still fairly faster than Ruby 2.5 in some benchmarks (attached below). Note that this JIT compiler passes `make test`, `make test-all`, `make test-spec` without JIT, and even with JIT. Not only it's perfectly safe with JIT disabled because it does not replace VM instructions unlike MJIT, but also with JIT enabled it stably runs Ruby applications including Rails applications. I'm expecting this version as just "initial" JIT compiler. I have many optimization ideas which are skipped for initial merging, and you may easily replace this JIT compiler with a faster one by just replacing mjit_compile.c. `mjit_compile` interface is designed for the purpose. common.mk: update dependencies for mjit_compile.c. internal.h: declare `rb_vm_insn_addr2insn` for MJIT. vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to compiler. This avoids to include some functions which take a long time to compile, e.g. vm_exec_core. Some of the purpose is achieved in transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are manually resolved for now. Load mjit_helper.h for MJIT header. mjit_helper.h: New. This is a file used only by JIT-ed code. I'll refactor `mjit_call_cfunc` later. vm_eval.c: add some #ifdef switches to skip compiling some functions like Init_vm_eval. win32/mkexports.rb: export thread/ec functions, which are used by MJIT. include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify that a function is exported only for MJIT. array.c: export a function used by MJIT. bignum.c: ditto. class.c: ditto. compile.c: ditto. error.c: ditto. gc.c: ditto. hash.c: ditto. iseq.c: ditto. numeric.c: ditto. object.c: ditto. proc.c: ditto. re.c: ditto. st.c: ditto. string.c: ditto. thread.c: ditto. variable.c: ditto. vm_backtrace.c: ditto. vm_insnhelper.c: ditto. vm_method.c: ditto. I would like to improve maintainability of function exports, but I believe this way is acceptable as initial merging if we clarify the new exports are for MJIT (so that we can use them as TODO list to fix) and add unit tests to detect unresolved symbols. I'll add unit tests of JIT compilations in succeeding commits. Author: Takashi Kokubun <takashikkbn@gmail.com> Contributor: wanabe <s.wanabe@gmail.com> Part of [Feature #14235] --- * Known issues * Code generated by gcc is faster than clang. The benchmark may be worse in macOS. Following benchmark result is provided by gcc w/ Linux. * Performance is decreased when Google Chrome is running * JIT can work on MinGW, but it doesn't improve performance at least in short running benchmark. * Currently it doesn't perform well with Rails. We'll try to fix this before release. --- * Benchmark reslts Benchmarked with: Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores - 2.0.0-p0: Ruby 2.0.0-p0 - r62186: Ruby trunk (early 2.6.0), before MJIT changes - JIT off: On this commit, but without `--jit` option - JIT on: On this commit, and with `--jit` option ** Optcarrot fps Benchmark: https://github.com/mame/optcarrot | |2.0.0-p0 |r62186 |JIT off |JIT on | |:--------|:--------|:--------|:--------|:--------| |fps |37.32 |51.46 |51.31 |58.88 | |vs 2.0.0 |1.00x |1.38x |1.37x |1.58x | ** MJIT benchmarks Benchmark: https://github.com/benchmark-driver/mjit-benchmarks (Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks) | |2.0.0-p0 |r62186 |JIT off |JIT on | |:----------|:--------|:--------|:--------|:--------| |aread |1.00 |1.09 |1.07 |2.19 | |aref |1.00 |1.13 |1.11 |2.22 | |aset |1.00 |1.50 |1.45 |2.64 | |awrite |1.00 |1.17 |1.13 |2.20 | |call |1.00 |1.29 |1.26 |2.02 | |const2 |1.00 |1.10 |1.10 |2.19 | |const |1.00 |1.11 |1.10 |2.19 | |fannk |1.00 |1.04 |1.02 |1.00 | |fib |1.00 |1.32 |1.31 |1.84 | |ivread |1.00 |1.13 |1.12 |2.43 | |ivwrite |1.00 |1.23 |1.21 |2.40 | |mandelbrot |1.00 |1.13 |1.16 |1.28 | |meteor |1.00 |2.97 |2.92 |3.17 | |nbody |1.00 |1.17 |1.15 |1.49 | |nest-ntimes|1.00 |1.22 |1.20 |1.39 | |nest-while |1.00 |1.10 |1.10 |1.37 | |norm |1.00 |1.18 |1.16 |1.24 | |nsvb |1.00 |1.16 |1.16 |1.17 | |red-black |1.00 |1.02 |0.99 |1.12 | |sieve |1.00 |1.30 |1.28 |1.62 | |trees |1.00 |1.14 |1.13 |1.19 | |while |1.00 |1.12 |1.11 |2.41 | ** Discourse's script/bench.rb Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb NOTE: Rails performance was somehow a little degraded with JIT for now. We should fix this. (At least I know opt_aref is performing badly in JIT and I have an idea to fix it. Please wait for the fix.) *** JIT off Your Results: (note for timings- percentile is first, duration is second in millisecs) categories_admin: 50: 17 75: 18 90: 22 99: 29 home_admin: 50: 21 75: 21 90: 27 99: 40 topic_admin: 50: 17 75: 18 90: 22 99: 32 categories: 50: 35 75: 41 90: 43 99: 77 home: 50: 39 75: 46 90: 49 99: 95 topic: 50: 46 75: 52 90: 56 99: 101 *** JIT on Your Results: (note for timings- percentile is first, duration is second in millisecs) categories_admin: 50: 19 75: 21 90: 25 99: 33 home_admin: 50: 24 75: 26 90: 30 99: 35 topic_admin: 50: 19 75: 20 90: 25 99: 30 categories: 50: 40 75: 44 90: 48 99: 76 home: 50: 42 75: 48 90: 51 99: 89 topic: 50: 49 75: 55 90: 58 99: 99 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* mjit.c: merge MJIT infrastructurek0kubun2018-02-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | that allows to JIT-compile Ruby methods by generating C code and using C compiler. See the first comment of mjit.c to know what this file does. mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>. After he invented great method JIT infrastructure for MRI as MJIT, Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW in MJIT. In addition to merging it, I ported pthread to Windows native threads. Now this MJIT infrastructure can be compiled on Visual Studio. This commit simplifies mjit.c to decrease code at initial merge. For example, this commit does not provide multiple JIT threads support. We can resurrect them later if we really want them, but I wanted to minimize diff to make it easier to review this patch. `/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby developers may not know the name "mjit" and the file name should make sure it's from Ruby and not from some harmful programs. TODO: it may be better to store this to some temporary directory which Ruby is already using by Tempfile, if it's not bad for performance. mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is for triggering MJIT. This drops interface for AOT compared to the original MJIT. Makefile.in: define macros to let MJIT know the path of MJIT header. Probably we can refactor this to reduce the number of macros (TODO). win32/Makefile.sub: ditto. common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this commit separates MJIT infrastructure and JIT compiler code as independent object files. As initial patch is NOT going to have ultra-fast JIT compiler, it's likely to replace JIT compiler, e.g. original MJIT's compiler or some future JIT impelementations which are not public now. inits.c: define MJIT module. This is added because `MJIT.enabled?` was necessary for testing. test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this wouldn't work with current code when JIT is enabled. test/ruby/test_io.rb: skip this too. This would make no sense with MJIT. ruby.c: define MJIT CLI options. As major difference from original MJIT, "-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support not only gcc/clang but also cl.exe (Visual Studio) in the future. But it takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit" options are allowed since some Ruby committers preferred it at Ruby developers Meeting on January, and some of options are renamed. This file also triggers to initialize MJIT thread and variables. eval.c: finalize MJIT worker thread and variables. test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit. thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for functions which are used by other files. thread_win32.c: ditto, for Windows. Those pthread porting is one of major works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235. thread.c: follow rb_ prefix changes vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid SEGV by race between JIT and GC of ISeq. The improvement was provided by wanabe <s.wanabe@gmail.com>. In JIT compiler I created and am going to add in my next commit, I found that having `mjit_exec` after `vm_loop_start:` is harmful because the JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn. Executing non-FINISH frame is unexpected for my JIT compiler and `exception_handler` triggers executions of such ISeqs. So `mjit_exec` here should be executed only when it directly comes from `vm_exec` call. `RubyVM::MJIT` module and `.enabled?` method is added so that we can skip some tests which don't expect JIT threads or compiler file descriptors. vm_insnhelper.h: trigger MJIT on method calls during VM execution. vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because rb_control_frame_struct is likely to be casted to another struct. The last position is the safest place to add the new field. vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an optimization which are done in both MJIT and YARV-MJIT. So this change is added in this commit. Calculating bp from ep is a little heavy work, so bp is kind of cache for it. iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue is GCed to avoid SEGV. TODO: unload some GCed units in some safe way. gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous JIT and GC executions may cause SEGV and so we should synchronize them. cont.c: save continuation information in MJIT worker. As MJIT shouldn't unload JIT-ed code which is being used, MJIT wants to know full list of saved execution contexts for continuation and detect ISeqs in use. mjit_compile.c: added empty JIT compiler so that you can reuse this commit to build your own JIT compiler. This commit tries to compile ISeqs but all of them are considered as not supported in this commit. So you can't use JIT compiler in this commit yet while we added --jit option now. Patch author: Vladimir Makarov <vmakarov@redhat.com>. Contributors: Takashi Kokubun <takashikkbn@gmail.com>. wanabe <s.wanabe@gmail.com>. Lars Kanis <lars@greiz-reinsdorf.de>. Part of Feature 12589 and 14235. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* bare_instructions.rb: sp_inc is signednobu2018-01-301-15/+0
| | | | | | | | | | | * tool/ruby_vm/models/bare_instructions.rb (predefine_attributes): `sp_inc` attribute which may return negative values must be signed `rb_snum_t`, to be signed-expanded at type promotion. * vm_insnhelper.h (ADJ_SP): removed the workaround for platforms where rb_num_t is wider than int. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62103 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* eliminate CALL_SIMPLE_METHODshyouhei2018-01-291-8/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Arrange operands of several opt_something insns so that jumps to opt_send_without_block can be applied to them. This makes it possible to eliminate CALL_SIMPLE_METHOD macro at all. Results in binary size of vm_exec_core to change from 27,008 bytes to 26,016 bytes on my machine. [close GH-1779] Note however that PC can point somewhere non-instruction now. ----------------------------------------------------------- benchmark results: minimum results in each 3 measurements. Execution time (sec) name before after so_ackermann 0.450 0.426 so_array 0.789 0.824 so_binary_trees 5.760 5.635 so_concatenate 3.594 3.508 so_count_words 0.211 0.196 so_exception 0.256 0.244 so_fannkuch 1.049 1.044 so_fasta 1.485 1.472 so_k_nucleotide 1.195 1.216 so_lists 0.517 0.513 so_mandelbrot 2.264 2.394 so_matrix 0.501 0.468 so_meteor_contest 2.987 2.912 so_nbody 1.307 1.289 so_nested_loop 0.908 0.925 so_nsieve 1.679 1.614 so_nsieve_bits 2.131 2.092 so_object 0.620 0.625 so_partial_sums 1.623 1.675 so_pidigits 1.135 1.190 so_random 0.357 0.321 so_reverse_complement 0.619 0.583 so_sieve 0.493 0.496 so_spectralnorm 1.749 1.737 Speedup ratio: compare with the result of `before' (greater is better) name after so_ackermann 1.057 so_array 0.958 so_binary_trees 1.022 so_concatenate 1.024 so_count_words 1.077 so_exception 1.049 so_fannkuch 1.004 so_fasta 1.009 so_k_nucleotide 0.983 so_lists 1.007 so_mandelbrot 0.946 so_matrix 1.072 so_meteor_contest 1.026 so_nbody 1.013 so_nested_loop 0.982 so_nsieve 1.040 so_nsieve_bits 1.018 so_object 0.992 so_partial_sums 0.969 so_pidigits 0.954 so_random 1.111 so_reverse_complement 1.062 so_sieve 0.994 so_spectralnorm 1.007 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62089 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* also use sp_inc in vm coreshyouhei2018-01-291-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Now that sp_inc attributes are officially provided as inline functions. Why not use them directly from the vm core, not just by the compiler. By doing so, it is now possible for us to optimize stack manipulations. We can now know exactly how many words of stack space an instruction consumes before it actually does. This changeset deletes some lines from insns.def because they are no longer needed. As a result it reduces the size of vm_exec_core function from 32,400 bytes to 32,352 bytes on my machine. It seems it does not affect performance: ----------------------------------------------------------- benchmark results: minimum results in each 3 measurements. Execution time (sec) name before after loop_for 1.093 1.061 loop_generator 1.156 1.152 loop_times 0.982 0.974 loop_whileloop 0.549 0.587 loop_whileloop2 0.115 0.121 Speedup ratio: compare with the result of `before' (greater is better) name after loop_for 1.030 loop_generator 1.003 loop_times 1.008 loop_whileloop 0.935 loop_whileloop2 0.949 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62087 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* comma at the end of enum is a C99ismshyouhei2018-01-021-2/+2
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61549 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* remove `trace` instruction. [Feature #14104]ko12017-11-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | * tool/instruction.rb: create `trace_` prefix instructions. * compile.c (ADD_TRACE): do not add `trace` instructions but add TRACE link elements. TRACE elements will be unified with a next instruction as instruction information. * vm_trace.c (update_global_event_hook): modify all ISeqs when hooks are enabled. * iseq.c (rb_iseq_trace_set): added to toggle `trace_` instructions. * vm_insnhelper.c (vm_trace): added. This function is a body of `trace_` prefix instructions. * vm_insnhelper.h (JUMP): save PC to a control frame. * insns.def (trace): removed. * vm_exec.h (INSN_ENTRY_SIG): add debug output (disabled). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60763 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h (GET_SP_COUNT): removed because nobody use it.ko12017-10-291-2/+0
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60562 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_exec_core() accepts `ec` instead of `th`.ko12017-10-271-2/+2
| | | | | | | | | * vm_exec.c (vm_exec_core): accepts `ec` instead of `th`. * vm_args.c (vm_caller_setup_arg_block): also accepts `ec`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* `vm_call_handler` and related functions accept `ec` instead of `th`.ko12017-10-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * vm_core.h (vm_call_handler): fix to accept `ec` instead of `th`. * vm_args.c: the following functions accept `ec` instead of `th`. * raise_argument_error * argument_arity_error * argument_kw_error * setup_parameters_complex * vm_eval.c: ditto. * vm_call0 * vm_call0_cfunc_with_frame * vm_call0_cfunc * vm_call0_body * vm_insnhelper.c: ditto * vm_call_iseq_setup_tailcall_0start * vm_call_iseq_setup_normal_0start * vm_callee_setup_arg * vm_call_iseq_setup * vm_call_iseq_setup_2 * vm_call_iseq_setup_normal * vm_call_iseq_setup_tailcall * vm_cfp_consistent_p * vm_call_cfunc_with_frame * vm_call_cfunc * vm_call_ivar * vm_call_attrset * vm_call_bmethod_body * vm_call_bmethod * vm_call_opt_send * vm_call_opt_call * vm_call_method_missing * vm_call_zsuper * current_method_entry * vm_call_method_each_type * vm_call_method_nome * vm_call_method * vm_call_general * vm_call_super_method * tool/mk_call_iseq_optimized.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Use rb_execution_context_t instead of rb_thread_tko12017-10-261-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | to represent execution context [Feature #14038] * vm_core.h (rb_thread_t): rb_thread_t::ec is now a pointer. There are many code using `th` to represent execution context (such as cfp, VM stack and so on). To access `ec`, they need to use `th->ec->...` (adding one indirection) so that we need to replace them by passing `ec` instead of `th`. * vm_core.h (GET_EC()): introduced to access current ec. Also remove `ruby_current_thread` global variable. * cont.c (rb_context_t): introduce rb_context_t::thread_ptr instead of rb_context_t::thread_value. * cont.c (ec_set_vm_stack): added to update vm_stack explicitly. * cont.c (ec_switch): added to switch ec explicitly. * cont.c (rb_fiber_close): added to terminate fibers explicitly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c, vm_insnhelper.h: export symbols of VM serialsk0kubun2017-10-211-0/+3
| | | | | | | | | This change is for future JIT compiler introduction. See r60231 for the purpose. [close GH-1721] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: export symbols of shared variablesk0kubun2017-10-211-0/+4
| | | | | | | | | | | | | vm_insnhelper.h: ditto. All changes are for reducing changes required to introduce JIT compiler. Unlike functions that can be inlined by header, those variables should be shared with JIT-ed code. This will help reducing cost of rebase against upstream. [close GH-1720] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* rename rb_execution_context_t::stack(_size) to vm_stack(_size).ko12017-08-101-1/+1
| | | | | | | | | * vm_core.h: Ruby processes run with two stacks, a machine stack and a VM stack. To make it clear, this fix renames rb_execution_context_t::stack(_size) to vm_stack(_size). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59563 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* fixup r58614 for raspi3 and maybe other systems with odd compilenormal2017-05-091-1/+1
| | | | | | [ruby-core:81048] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58615 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* rb_execution_context_t: move stack, stack_size and cfp from rb_thread_tnormal2017-05-091-1/+1
| | | | | | | | | | The goal is to reduce rb_context_t and rb_fiber_t size by removing the need to store the entire rb_thread_t in there. [ruby-core:81045] Work-in-progress: soon, we will move more fields here. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58614 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insert assertions for THROW_DATA_* macros.ko12017-04-071-0/+5
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58269 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* fix TracePoint#return_value with non-local exitsko12017-04-061-13/+29
| | | | | | | | | | | | | | | | | | * vm.c: get return_value from imemo_throw_data object (THROW_DATA_VAL()). imemo_throw_data (TAG_BREAK) contains returned value. However, imemo_throw_data (TAG_BREAK) can skip several frames so that we need to use it only once (at most internal frame). To record it, we introduced THROW_DATA_CONSUMED and check it. * internal.h: define THROW_DATA_CONSUMED flag. * test/ruby/test_settracefunc.rb: add tests for [Bug #13369] * vm_insnhelper.h: add THROW_DATA_CONSUMED_P() and THROW_DATA_CONSUMED_SET(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def: float comparisonnobu2017-01-131-0/+2
| | | | | | | * insns.def (opt_lt, opt_le, opt_gt, opt_ge): optimize flonum and on-heap float comparison. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57319 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h: rename REG_(CFP|PC|SP|EP) to VM_REG_....ko12016-11-051-17/+17
| | | | | | | | | [Bug #12527] * vm_exec.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56609 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_core.h: revisit the structure of frame, block and env.ko12016-07-281-4/+4
| | | | | | | | | | | | | | | | | | | | | | [Bug #12628] This patch introduce many changes. * Introduce concept of "Block Handler (BH)" to represent passed blocks. * move rb_control_frame_t::flag to ep[0] (as a special local variable). This flags represents not only frame type, but also env flags such as escaped. * rename `rb_block_t` to `struct rb_block`. * Make Proc, Binding and RubyVM::Env objects wb-protected. Check [Bug #12628] for more details. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55766 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* NoMethodError#private_call?nobu2016-02-281-2/+2
| | | | | | | | | | | | * error.c (nometh_err_initialize): add private_call? parameter. * error.c (nometh_err_private_call_p): add private_call? method, to tell if the exception raised in private form FCALL or VCALL. [Feature #12043] * vm_eval.c (make_no_method_exception): append private_call? argument. * vm_insnhelper.c (ci_missing_reason): copy FCALL flag. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_eval.c: fstring formatnobu2016-01-131-1/+1
| | | | | | | * vm_eval.c (make_no_method_exception): make format string fstring. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53525 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * refactoring CREF related code.ko12015-11-131-19/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval_intern.h: remove unused setter functions. CREF_CLASS_SET() CREF_NEXT_SET() CREF_SCOPE_VISI_COPY() * eval_intern.h: rename flags: * NODE_FL_CREF_PUSHED_BY_EVAL_ -> CREF_FL_PUSHED_BY_EVAL * NODE_FL_CREF_OMOD_SHARED_ -> CREF_FL_OMOD_SHARED and use IMEMO_FL_USER1/2. * vm.c (vm_cref_new): accept push_by_eval parameter. * vm.c (vm_cref_new_use_prev): added for rb_vm_rewrite_cref(). * vm_insnhelper.c (vm_cref_push): accept pushed_by_eval parameter. * vm_insnhelper.h: remove unused macros: COPY_CREF_OMOD() and COPY_CREF(). * vm_eval.c, insns.def: catch up this fix. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52564 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_core.h, vm_insnhelper.h: move definition of VMDEBUGko12015-10-231-22/+0
| | | | | | | | from vm_insnhelper.h to vm_core.h. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52252 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_core.h: split rb_call_info_t into several structs.ko12015-09-191-7/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * rb_call_info (ci) has compiled fixed information. * if ci->flag & VM_CALL_KWARG, then rb_call_info is also rb_call_info_with_kwarg. This technique reduce one word for major rb_call_info data. * rb_calling_info has temporary data (argc, blockptr, recv). for each method dispatch. This data is allocated only on machine stack. * rb_call_cache is for inline method cache. Before this patch, only rb_call_info_t data is passed. After this patch, above three structs are passed. This patch improves: * data locarity (rb_call_info is now read-only data). * reduce memory consumption (rb_call_info_with_kwarg, rb_calling_info). * compile.c: use above data. * insns.def: ditto. * iseq.c: ditto. * vm_args.c: ditto. * vm_eval.c: ditto. * vm_insnhelper.c: ditto. * vm_insnhelper.h: ditto. * iseq.h: add iseq_compile_data::ci_index and iseq_compile_data::ci_kw_indx. * tool/instruction.rb: introduce TS_CALLCACHE operand type. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51903 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h (GET_PC_COUNT): remove unused macro.ko12015-09-021-2/+0
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51740 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * method.h: split rb_method_definition_t::flag to several flags.ko12015-06-031-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `flag' contains several categories of attributes and it makes us confusion (at least, I had confused). * rb_method_visibility_t (flags::visi) * NOEX_UNDEF -> METHOD_VISI_UNDEF = 0 * NOEX_PUBLIC -> METHOD_VISI_PUBLIC = 1 * NOEX_PRIVATE -> METHOD_VISI_PRIVATE = 2 * NOEX_PROTECTED -> METHOD_VISI_PROTECTED = 3 * NOEX_SAFE(flag)) -> safe (flags::safe, 2 bits) * NOEX_BASIC -> basic (flags::basic, 1 bit) * NOEX_MODFUNC -> rb_scope_visibility_t in CREF * NOEX_SUPER -> MISSING_SUPER (enum missing_reason) * NOEX_VCALL -> MISSING_VCALL (enum missing_reason) * NOEX_RESPONDS -> BOUND_RESPONDS (macro) Now, NOEX_NOREDEF is not supported (I'm not sure it is needed). Background: I did not know what "NOEX" stands for. I asked Matz (who made this name) and his answer was "Nothing". "At first, it meant NO EXport (private), but the original meaning was gone." This is why I remove the mysterious word "NOEX" from MRI. * vm_core.h: introduce `enum missing_reason' to represent method_missing (NoMethodError) reason. * eval_intern.h: introduce rb_scope_visibility_t to represent scope visibility. It has 3 method visibilities (public/private/protected) and `module_function`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50743 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * node.h: remove NODE_IFUNC, NEW_IFUNC.ko12015-03-111-8/+0
| | | | | | | | | | | | | | | | | * internal.h: use T_IMEMO for IFUNC. rename `struct IFUNC' to `struct vm_ifunc' and move the definition from vm_insnhelper.h. Add imemo_ifunc. * gc.c (gc_mark_children): mark imemo_ifunc type T_IMEMO object. * compile.c: catch up these changes. * proc.c: ditto. * vm_core.h (RUBY_VM_IFUNC_P): ditto. * vm_eval.c (rb_iterate): ditto. * vm_insnhelper.c: ditto. * ext/objspace/objspace.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h: use T_IMEMO to create THROW_DATA.ko12015-03-111-16/+8
| | | | | | | | | | | | | | | | | Add THROW_DATA_NEW(). * internal.h: move defnition of `struct THROW_DATA' from vm_insnhelper.h to internal.h. Rename `THROW_DATA' to `vm_throw_data'. * eval_intern.h (THROW_DATA_P): move to internal.h. THROW_DATA is no longer T_NODE, so check T_IMEMO. * gc.c (gc_mark_children): mark THROW_DATA. * vm.c: catch up these changes. * vm_eval.c: ditto. * vm_insnhelper.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49936 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.c: use T_IMEMO to create SVAR.ko12015-03-111-10/+0
| | | | | | | | | | | | * internal.h, vm_insnhelper.h: move definition `struct SVAR' from vm_insnhelper.h to internal.h. And rename it to strcut vm_svar. new imemo_type imemo_svar is added. * gc.c (gc_mark_children): mark imemo_svar. * node.c (rb_gc_mark_node): remove useless marking. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49935 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h (THROW_DATA_STATE): return int, not VALUE.ko12015-03-101-4/+4
| | | | | | | | * vm_insnhelper.h (THROW_DATA_STATE_SET): accept int value. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49927 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h: define struct IFUNC.ko12015-03-101-0/+8
| | | | | | | | | * vm_eval.c (rb_iterate): use it. * vm_insnhelper.c (vm_yield_with_cfunc): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49925 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h: define struct THROW_DATA to representko12015-03-101-0/+44
| | | | | | | | | | | | | | throwing data. Also define accessor functions. * eval_intern.h: move related changes into vm_insnhelper.h. Now these MACROs (functions) are only used in vm*.c. There is only THROW_DATA_P(err) to check this data type or not. * vm.c: catch up these changes. * vm_eval.c: ditto. * vm_insnhelper.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49921 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h: define struct SVAR for SVAR.ko12015-03-081-0/+9
| | | | | | | | | This data type is also same layout of NODE (NODE_IF). * vm_insnhelper.c: catch up this change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49899 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * internal.h: define rb_cref_t and change to use it.ko12015-03-081-5/+5
| | | | | | | | | rb_cref_t is data type of CREF. Now, the body is still NODE. It is easy to understand what is CREF and what is pure NODE. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * vm_insnhelper.h (COPY_CREF_OMOD): fix translation miss.ko12015-03-081-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * internal.h: define CREF accessor macros.ko12015-03-081-9/+9
| | | | | | | | | | | | | | | | | | * CREF_CLASS(cref) * CREF_NEXT(cref) * CREF_VISI(cref) * CREF_VISI_SET(cref, v) * CREF_REFINEMENTS(cref) * CREF_PUSHED_BY_EVAL(cref) * CREF_PUSHED_BY_EVAL_SET(cref) * CREF_OMOD_SHARED(cref) * CREF_OMOD_SHARED_SET(cref) * CREF_OMOD_SHARED_UNSET(cref) This is process to change CREF data type from NODE. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49894 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: redefined_flag in rb_vm_tnobu2014-07-181-40/+0
| | | | | | | | | * vm_core.h (struct rb_vm_struct): move redefined_flag from ruby_vm_redefined_flag. * vm_core.h (BASIC_OP_UNREDEFINED_P): move from vm_insnhelper.h. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46858 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * include/ruby/ruby.h: rename OBJ_WRITE and OBJ_WRITTEN intoko12013-12-201-3/+3
| | | | | | | | | | | | RB_OBJ_WRITE and RB_OBJ_WRITTEN. * array.c, class.c, compile.c, hash.c, internal.h, iseq.c, proc.c, process.c, re.c, string.c, variable.c, vm.c, vm_eval.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: catch up this change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44299 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * compile.c, insns.def, test/ruby/test_rubyvm.rb, vm.c, vm_core.h,charliesome2013-12-091-4/+4
| | | | | | | | vm_insnhelper.c, vm_insnhelper.h, vm_method.c: Rename method_serial to global_method_state and constant_serial to global_constant_state after discussion with ko1. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44097 b2dd03c8-39d4-4d8f-98ff-823fe69b080e