only when its receiver and the argument are both Integers.
Since 6bedbf4625, Integer#[] has supported a range extraction.
This means that Integer#[] now accepts multiple arguments, which made
the method very slow unfortunately.
This change fixes the performance issue by adding a special handling for
its traditional use case: `num[idx]` where both `num` and `idx` are
Integers.
* numeric.c (int_pow): fix infinite loop in the case of y equal 1
and power of x does not overflow.
[ruby-core:91734] [Bug #15651]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67203 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* complex.c (rb_complex_new_polar): renamed with _new to clarify
that it creates a new instance, but is not an instance method.
* complex.c (rb_complex_polar): deprecated.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66359 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
In C, division by zero is undefined, even if the expression is double
(cf: ISO/IEC 9899:1990 section 6.3.5). OTOH we have tests about such
operations and results, means we expect no exceptional situation shall
occur. We need to carefully reroute the situation, and generate what
is needed.
See also: https://travis-ci.org/ruby/ruby/jobs/452680646#L2943
PS: Recently (last two decades), C have Annex. F document. It
normatively specifies that the division operator is IEEE 754's
division operator (cf: ISO/IEC 9899:1999 section F.3). If we could
move to such newer version this could be no problem. But that is not
possible today.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65642 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* complex.c (rb_dbl_complex_polar_pi): suffixed with _pi to
clarify that `ang` is not radian, but multiplied by PI.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65522 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* complex.c (rb_complex_pow): calculate power of a Fixnum without
allocating intermediate Complex objects, and avoid unexpected
NaNs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65190 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit introduces new core class Enumerator::ArithmeticSequence.
Enumerator::ArithmeticSequence is a subclass of Enumerator, and
represents a number generator of an arithmetic sequence.
After this commit, Numeric#step and Range#step without blocks
returned an ArithmeticSequence object instead of an Enumerator.
This class introduces the following incompatibilities:
- You can create a zero-step ArithmeticSequence,
and its size is not ArgumentError, but Infinity.
- You can create a negative-step ArithmeticSequence from a range.
[ruby-core:82816] [Feature #13904]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64205 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* include/ruby/ruby.h (UNREACHABLE_RETURN): UNREACHABLE at the end
of non-void functions.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* complex.c (rb_dbl_complex_polar): utility function, which
returns more precise value in right angle cases.
* bignum.c (rb_big_pow): use rb_dbl_complex_polar().
* numeric.c (rb_float_pow, fix_pow): create a Complex by polar
form.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* bignum.c (int_pow_tmp3): get rid of redefined Integer#> on
internal calculations, as well as the GMP version.
* bignum.c (rb_int_powm): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63660 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Typical usages:
```
p ary[1..] # drop the first element; identical to ary[1..-1]
(1..).each {|n|...} # iterate forever from 1; identical to 1.step{...}
```
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Since 2.5, Numeric instances can be cloned and duplicated.
[Fix GH-1850]
From: Miguel Landaeta <miguel@miguel.cc>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63112 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
tool/ruby_vm/views/_insn_name_info.erb: on Linux, rb_vm_insn_name_offset
was needed to compile with --jit-debug (Usually --jit-debug requires
more symbols than the situation without --jit-debug because -O2 skips
some functions to compile).
vm.c: when running transform_mjit_header.rb with --jit-wait,
rb_source_location_cstr was repoted to be missing.
string.c: ditto, for rb_str_eql
numeric.c: ditto, for rb_float_eql
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62313 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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
And remove redundant `HAVE_*` macros,
and use `USE_RB_*` macros instead.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62067 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
instead of scattering #ifdef HAVE_NANF here and there define our
own nan() unless defined elsewhere.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61971 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It seems HUGE_VAL is already used. Why not eliminate INTINITY.
NAN is also float. That of double is called nan(). This is also
fixed.
Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e