Граф коммитов

388 Коммитов

Автор SHA1 Сообщение Дата
mame ca494df3e0 insns.def: remove old wrong explanation for get/setconstant
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64074 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-27 06:28:14 +00:00
k0kubun a763bc3c6b insns.def: s/handles_frame/handles_sp/
because it's more suitable to describe the current behavior now.

tool/ruby_vm/models/bare_instructions.rb: ditto.
tool/ruby_vm/views/_insn_entry.erb: ditto.
tool/ruby_vm/views/_mjit_compile_insn_body.erb: ditto.
tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb: ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-25 14:55:43 +00:00
k0kubun c86fc2bba5 mjit_compile.c: reduce sp motion on JIT
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-19 13:25:22 +00:00
k0kubun 80dac806cc revert r63988
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-17 16:20:15 +00:00
k0kubun 5aa52587e8 insns.def: remove redundant ifndef in r63988
By the way, the original patch of r63988 was provided by wanabe:
https://github.com/wanabe/ruby/tree/local-stack

but I forgot to add his credit in the previous commit message.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63990 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-17 15:15:31 +00:00
k0kubun 6a4bb345df mjit_compile.c: resurrect local variable stack
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-17 15:09:41 +00:00
ktsj 78a2a1be76 insns.def: fix typo in comment
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63970 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-15 09:48:09 +00:00
k0kubun 8bec3e1fe2 insns.def: stop pushing unnecessary keys for MJIT
[Bug #14892]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63875 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-07 14:41:03 +00:00
k0kubun 7a0a585444 revert r62655 for r63763
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-07-05 15:56:48 +00:00
shyouhei 6b534134a7 give up insn attr handles_frame
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
2018-06-27 09:28:09 +00:00
shyouhei 529af9c821 refactor move logics out of insns.def
This is a pure refactoring.  I see no difference in this change.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-27 01:10:02 +00:00
shyouhei 22444ae9b1 move function declarations from insns.def to internal.h
Just avoid being loose.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-27 00:57:16 +00:00
nobu a3fe1034c4 insns.def: checktype
* insns.def (checktype): split branchiftype to checktype and
  branchif, to make branch condition negation possible.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-21 10:52:52 +00:00
tenderlove 9e26858e8c Reverting r62775, this should fix i686 builds
We need to mark default values for kwarg methods.  This also fixes
Bootsnap.  IBF iseq loading needed to mark iseqs as "having markable
objects".

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62851 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-19 18:21:54 +00:00
naruse 94c40622f5 Revert "Add direct marking on iseq operands"
This reverts commit r62706.

It causes SEGV on i686-linux (debian) and armv7l-linux-eabihf:
http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20180309T204300Z.diff.html.gz
http://rubyci.s3.amazonaws.com/scw-9d6766/ruby-trunk/log/20180309T211706Z.diff.html.gz

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62775 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-16 07:59:10 +00:00
tenderlove 8952964976 Add direct marking on iseq operands
Directly marking iseq operands allows us to eliminate the "mark array"
stored on ISEQ objects, which will reduce the amount of memory ISEQ
objects consume.  This patch changes the iseq mark function to:

* Directly marks ISEQ operands
* Iterate over and mark child ISEQs

It also introduces two flags on the ISEQ object.  In order to mark
instruction operands, we have to disassemble the instructions and find
the instruction parameters and types.  Instructions may also be
translated to jump addresses.  Instruction sequences may get marked by
the GC *while* they're mid flight (being compiled).  The
`ISEQ_TRANSLATED` flag is used to indicate whether or not the
instructions have been translated to jump addresses so that when we
decode the instructions we know whether or not we need to go from jump
location back to original instruction or not.

Not all ISEQ objects have any markable objects embedded in their
instructions.  We can detect whether or not an ISEQ has markable objects
in the instructions at compile time.  If the instructions contain
markable objects, we set a flag `ISEQ_MARKABLE_ISEQ` on the ISEQ object.
This means that during the mark phase, we can skip decompilation if the
flag is *not* set.  In other words, we can avoid decompilation of we
know in advance there is nothing to mark.

`once` instructions have an operand that contains the result of a
one-time compilation of a regex.  Before this patch, that operand was
called an "inline cache", even though the struct was actually an "inline
storage".  This patch changes the operand to be an "inline storage" so
that we can differentiate between caches that need marking (the inline
storage) and caches that don't need marking (inline cache).

[ruby-core:84909]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62706 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-09 20:11:45 +00:00
k0kubun 8a15857a7f mjit_compile.c: use local variables for stack
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-04 07:04:40 +00:00
k0kubun fc2764e58c insns.def: unwrap vm_exec for yield
Outer vm_exec can catch longjmp. We don't need to call vm_exec first
here.

This optimizes JIT-ed yield:

* Benchmark script

```
require 'benchmark_driver'

Benchmark.driver do |x|
  x.prelude %{
    def yielder
      yield + 1
    end
  }
  x.report 'yielder', %{
    yielder { 1 }
  }
  x.loop_count 300_000_000

  x.rbenv 'before', 'before,--jit', 'after', 'after,--jit'
  x.verbose
end
```

* Result

before: ruby 2.6.0dev (2018-03-03 trunk 62642) [x86_64-linux]
before,--jit: ruby 2.6.0dev (2018-03-03 trunk 62642) +JIT [x86_64-linux]
after: ruby 2.6.0dev (2018-03-03 trunk 62642) [x86_64-linux]
last_commit=insns.def: unwrap vm_exec for yield
after,--jit: ruby 2.6.0dev (2018-03-03 trunk 62642) +JIT [x86_64-linux]
last_commit=insns.def: unwrap vm_exec for yield
Calculating -------------------------------------
                         before  before,--jit       after  after,--jit
             yielder    37.214M       29.222M     35.904M      38.035M i/s -    300.000M times in 8.061581s 10.266312s 8.355716s 7.887447s

Comparison:
                          yielder
         after,--jit:  38035121.0 i/s
              before:  37213544.0 i/s - 1.02x  slower
               after:  35903565.7 i/s - 1.06x  slower
        before,--jit:  29221787.6 i/s - 1.30x  slower

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62643 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-03 04:50:14 +00:00
k0kubun b7aae52851 vm.c: add mjit_enable_p flag
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-03-03 04:07:02 +00:00
k0kubun 1012e50ac7 insns.def: remove unnecessary sp motion
This seems obsoleted after r62087.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62387 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-12 09:05:12 +00:00
nobu aea14e68fb insns.def: cache nil const
* insns.def (getinlinecache): Qnil is a valid value as a constant.
  this can be observable when accessing a deprecated constant
  which is nil.  non-nil constant is warned just once for each
  location, but every time if it is nil.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62350 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-10 16:54:47 +00:00
k0kubun ed935aa5be mjit_compile.c: merge initial JIT compiler
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
2018-02-04 11:22:28 +00:00
shyouhei c788fb4808 eliminate CALL_SIMPLE_METHOD
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
2018-01-29 07:15:08 +00:00
shyouhei 31ecd18f1a s/CALL_SIMPLE_METHOD/DISPATCH_ORIGINAL_INSN/
Now that DISPATCH_ORIGINAL_INSN is introduced, we can replace
CALL_SIMPLE_METHOD with DISPATCH_ORIGINAL_INSN. These two macros
differ in size very much and results in this big difference in
compiled binary size. This changeset reduces the size of
vm_exec_core from 32,352 bytes to 27,008 bytes on my machine.  As
a result it yields slightly better performance.
Closes [GH-1779].

-----------------------------------------------------------
benchmark results:
minimum results in each 3 measurements.
Execution time (sec)
name    before  after
so_ackermann     0.484  0.454
so_array         0.837  0.779
so_binary_trees  5.928  5.801
so_concatenate   3.473  3.543
so_count_words   0.201  0.222
so_exception     0.255  0.252
so_fannkuch      1.080  1.019
so_fasta         1.459  1.463
so_k_nucleotide  1.218  1.180
so_lists         0.499  0.484
so_mandelbrot    2.189  2.324
so_matrix        0.510  0.496
so_meteor_contest        3.025  2.925
so_nbody         1.319  1.273
so_nested_loop   0.941  0.932
so_nsieve        1.806  1.647
so_nsieve_bits   2.151  2.078
so_object        0.632  0.621
so_partial_sums  1.560  1.632
so_pidigits      1.190  1.183
so_random        0.333  0.353
so_reverse_complement    0.604  0.586
so_sieve         0.521  0.481
so_spectralnorm  1.774  1.722

Speedup ratio: compare with the result of `before' (greater is better)
name    after
so_ackermann    1.065
so_array        1.075
so_binary_trees 1.022
so_concatenate  0.980
so_count_words  0.903
so_exception    1.009
so_fannkuch     1.059
so_fasta        0.997
so_k_nucleotide 1.032
so_lists        1.032
so_mandelbrot   0.942
so_matrix       1.028
so_meteor_contest       1.034
so_nbody        1.036
so_nested_loop  1.009
so_nsieve       1.097
so_nsieve_bits  1.035
so_object       1.018
so_partial_sums 0.956
so_pidigits     1.006
so_random       0.943
so_reverse_complement   1.032
so_sieve        1.083
so_spectralnorm 1.030

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62088 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-29 07:04:50 +00:00
shyouhei 7d4ad74f22 also use sp_inc in vm core
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
2018-01-29 06:56:56 +00:00
k0kubun 6cb0126773 insns.def: [DOC] update supported attributes [ci skip]
which are changed at r62051.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62074 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-27 13:50:28 +00:00
shyouhei 3234245ae3 move ADD_PC around to optimize PC manipluiations
This commit introduces new attribute handles_flame and if that is
_not_ the case, places ADD_PC right after INC_SP.  This improves
locality of PC manipulations to prevents unnecessary register spill-
outs. As a result, it reduces the size of vm_exec_core from 32,688
bytes to 32,384 bytes on my machine.

Speedup is very faint, but certain.

-----------------------------------------------------------
benchmark results:
minimum results in each 3 measurements.
Execution time (sec)
name    before  after
so_ackermann     0.476  0.464
so_array         0.742  0.728
so_binary_trees  5.493  5.466
so_concatenate   3.619  3.395
so_count_words   0.190  0.184
so_exception     0.249  0.239
so_fannkuch      0.994  0.953
so_fasta         1.369  1.374
so_k_nucleotide  1.111  1.111
so_lists         0.470  0.481
so_mandelbrot    2.059  2.050
so_matrix        0.466  0.465
so_meteor_contest        2.712  2.781
so_nbody         1.154  1.204
so_nested_loop   0.852  0.846
so_nsieve        1.636  1.623
so_nsieve_bits   2.073  2.039
so_object        0.616  0.584
so_partial_sums  1.464  1.481
so_pidigits      1.075  1.082
so_random        0.321  0.317
so_reverse_complement    0.555  0.558
so_sieve         0.495  0.490
so_spectralnorm  1.634  1.627

Speedup ratio: compare with the result of `before' (greater is better)
name    after
so_ackermann    1.025
so_array        1.019
so_binary_trees 1.005
so_concatenate  1.066
so_count_words  1.030
so_exception    1.040
so_fannkuch     1.043
so_fasta        0.996
so_k_nucleotide 1.000
so_lists        0.978
so_mandelbrot   1.004
so_matrix       1.001
so_meteor_contest       0.975
so_nbody        0.959
so_nested_loop  1.007
so_nsieve       1.008
so_nsieve_bits  1.017
so_object       1.056
so_partial_sums 0.989
so_pidigits     0.994
so_random       1.014
so_reverse_complement   0.996
so_sieve        1.010
so_spectralnorm 1.004

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62051 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-26 06:30:58 +00:00
shyouhei a1d6fba33b suppress warning for VC12
It says "warning C4146: unary minus operator applied
to unsigned type, result still unsigned"


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-12 13:25:03 +00:00
shyouhei 9456f88f00 [ci skip] add comments about file format (2nd try)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61783 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-12 08:38:08 +00:00
shyouhei e2b7cb9d32 new insns.def format (2nd try)
- Gave up @j comments
- Room for sp_inc to be a proper grammer element

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61782 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-12 08:38:07 +00:00
shyouhei 5ad95486e6 merge revisions 61753:61750 61747:61740 61737:61728
Revert all the VM generator rewrites; requested by naruse


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-10 01:53:24 +00:00
kazu a3ecb0f82d Fix a typo [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-10 00:01:31 +00:00
shyouhei 310be7547d [ci skip] add comments about file format
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-09 13:30:29 +00:00
shyouhei 89df12d849 new insns.def format
- Gave up @j comments
- Room for sp_inc to be a proper grammer element

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61729 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-09 13:30:28 +00:00
ko1 7fd1183467 Speedup `block.call` [Feature #14330]
* insns.def (getblockparamproxy): introduce new instruction to return
  the `rb_block_param_proxy` object if possible. This object responds
  to `call` method and invoke given block (completely similar to `yield`).

* method.h (OPTIMIZED_METHOD_TYPE_BLOCK_CALL): add new optimized call type
  which is for `rb_block_param_proxy.cal`.

* vm_insnhelper.c (vm_call_method_each_type): ditto.

* vm_insnhelper.c (vm_call_opt_block_call): ditto.

* vm_core.h (BOP_CALL, PROC_REDEFINED_OP_FLAG): add check for `Proc#call`
  redefinition.

* compile.c (iseq_compile_each0): compile to use new insn
  `getblockparamproxy` for method call.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-07 19:18:49 +00:00
ko1 0d2346f9a1 Speedup `Proc#call` [Feature #14318]
* vm_insnhelper.c (vm_call_opt_call): do same process of `yield` instead of
  invoking `Proc`.

* vm_insnhelper.c (vm_invoke_block): invoke given block handler instead of
  using a block handler in the current frame.
  Also do not check blcok handler here (caller should check it).

* insns.def (invokeblock): catch up this fix.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61624 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-05 17:51:10 +00:00
ko1 0268c85e85 * insns.def (invokeblock): `calling->recv` is not used.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61606 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-05 07:25:55 +00:00
nobu e3f46b1dc5 insns.def: adjust type
* insns.def (checkkeyword): adjust argument type to
  vm_check_keyword as lindex_t.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-23 00:51:36 +00:00
mame c08e8886ba compile.c: add a RUBY_EVENT_COVERAGE_LINE event for line coverage
2.5's line coverage measurement was about two times slower than 2.4
because of two reasons; (1) vm_trace uses rb_iseq_event_flags (which
takes O(n) currently where n is the length of iseq) to get an event
type, and (2) RUBY_EVENT_LINE uses setjmp to call an event hook.

This change adds a special event for line coverage,
RUBY_EVENT_COVERAGE_LINE, and adds `tracecoverage` instructions where
the event occurs in iseq.
`tracecoverage` instruction calls an event hook without vm_trace.
And, RUBY_EVENT_COVERAGE_LINE is an internal event which does not
use setjmp.

This change also cancells lineno change due to the deletion of trace
instructions [Feature #14104].  So fixes [Bug #14191].

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61350 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-20 04:24:14 +00:00
mame c7e4f91246 insns.def (tracebranch): renamed from `trace2`
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61047 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-06 07:04:49 +00:00
ko1 2fb4c36c44 accepts `ec` as first parameter.
* vm_insnhelper.c (vm_check_match): accepts `ec` as first parameter.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-16 06:10:31 +00:00
ko1 665ba24b44 remove `trace` instruction. [Feature #14104]
* 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
2017-11-14 12:58:36 +00:00
ko1 0c2746a7bb th->ec: dtrace
* vm.c (ruby_th_dtrace_setup): rename to rb_dtrace_setup()
  and accept `ec`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60696 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-07 08:19:25 +00:00
ko1 8ea78d66a1 th->ec: vm_once_dispatch.
* vm_insnhelper.c (vm_once_dispatch): accepts `ec`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-07 06:14:00 +00:00
ko1 5dfdaa9299 move rb_thread_t::interrupt_flag and mask
to rb_execution_context_t.

* vm_core.h (rb_thread_t): move
  `rb_thread_t::interrupt_flag` and
  `rb_thread_t::interrupt_mask` to rb_execution_context_t.

  RUBY_VM_CHECK_INTS() accepts `ec` instead of `th`.

* cont.c (rb_fiber_terminate): to propagate interrupt information,
  add new parameter `need_interrupt`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60672 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-06 07:44:28 +00:00
ko1 a288b87c4c EXEC_EVENT_HOOK(ec, ...)
* vm_core.h (EXEC_EVENT_HOOK): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-29 13:19:14 +00:00
ko1 7e9aca4071 catch up recent changes for call threaded code VM.
Fix compile errors for OPT_CALL_THREADED_CODE (in vm_opts.h).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60493 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 19:16:51 +00:00
ko1 baa849443f `th` -> `ec` for `rb_insn_func_t`.
* vm_core.h (rb_insn_func_t): accepts `ec` instead of `th`.

* vm_insnhelper.c (rb_vm_opt_struct_aref): ditto.

* vm_insnhelper.c (rb_vm_opt_struct_aset): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60492 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 19:08:31 +00:00
ko1 04dc3a0ca6 vm_exec_core() accepts `ec` instead of `th`.
* 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
2017-10-27 06:21:50 +00:00
ko1 88910e94a8 `th` -> `ec` for block related functions.
* vm.c: the following functions accept `ec` instead of `th`.
  * invoke_block
  * invoke_bmethod
  * invoke_iseq_block_from_c
  * invoke_block_from_c_bh
  * check_block_handler
  * vm_yield_with_cref
  * vm_yield
  * vm_yield_with_block
  * vm_yield_force_blockarg
  * invoke_block_from_c_proc
  * vm_invoke_proc
  * vm_invoke_bmethod
  * rb_vm_invoke_proc

* vm_insnhelper.c: ditto.
  * vm_yield_with_cfunc
  * vm_yield_with_symbol
  * vm_callee_setup_block_arg
  * vm_yield_setup_args
  * vm_invoke_iseq_block
  * vm_invoke_symbol_block
  * vm_invoke_ifunc_block
  * vm_invoke_block


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 06:06:31 +00:00