* object.c (rb_f_integer): prefer `base` optional argument over
keyword arguments. this issue should be resolved more generally
by separating keyword arguments from hashes in the future.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64015 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (mutable_obj_clone): `Kernel#clone` should not copy
FL_USER* flags because they are copied unexpectedly.
Unexpected copy will break internal data consistency.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63912 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_cstr_to_dbl_raise): do not ignore exponent part
when the input string longer than internal buffer contains
underscore(s). [ruby-core:86836] [Bug #14731]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63322 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Support `exception:` keyword argument in `Kernel#Float()`.
If `exception:` is `false`, `Kernel#Float()` returns `nil` if the given
value cannot be interpreted as a float value.
The default value of `exception:` is `true`.
This is part of [Feature #12732].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Support `exception:` keyword argument in Kernel#Integer().
If `exception:` is `false`, `Kernel#Integer()` returns `nil` if the given
value cannot be interpreted as an integer value.
The default value of `exception:` is `true`.
This is part of [Feature #12732].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62757 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
For checking whether an object is an Integer, because a subclass of
Integer is meaningless in Ruby, RB_INTEGER_TYPE_P is better than
rb_obj_is_kind_of for speed.
* object.c (rb_to_integer): Use RB_INTEGER_TYPE_P instead of rb_obj_is_kind_of.
* object.c (rb_check_to_integer): ditto.
* range.c (range_max): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62582 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
* array.c (rb_check_to_array): conversion to array by to_a method.
returns nil if not possible.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62072 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
FrozenError will be used instead of RuntimeError for exceptions
raised when there is an attempt to modify a frozen object. The
reason for this change is to differentiate exceptions related
to frozen objects from generic exceptions such as those generated
by Kernel#raise without an exception class.
From: Jeremy Evans <code@jeremyevans.net>
Signed-off-by: Urabe Shyouhei <shyouhei@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61131 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Array(arg) does more than just call to_ary or to_a on the argument.
It also falls back to returning [arg] if neither method is available.
This patch extends the description and adds a few examples of how it
handles common types of arguments, including an integer
(which does not implement to_ary or to_a).
Extend Kernel#Array doc to mention TypeError
patched by ragesoss (Sage Ross) [fix GH-1663]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60327 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (convert_type_with_id): fix failure message for
explicit conversion. rb_convert_type_with_id and
rb_check_convert_type_with_id are not only for implicit
conversions.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59919 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Ensure space for the terminating NUL byte. Note that this code path is
reachable only when Ruby is compiled with SHARABLE_MIDDLE_SUBSTRING=1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59714 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
To convert the object implicitly, it has had two parts in convert_type() which are
1. lookink up the method's id
2. calling the method
Seems that strncmp() and strcmp() in convert_type() are slightly heavy to look up
the method's id for type conversion.
This patch will add and use internal APIs (rb_convert_type_with_id, rb_check_convert_type_with_id)
to call the method without looking up the method's id when convert the object.
Array#flatten -> 19 % up
Array#+ -> 3 % up
[ruby-dev:50024] [Bug #13341] [Fix GH-1537]
### Before
Array#flatten 104.119k (± 1.1%) i/s - 525.690k in 5.049517s
Array#+ 1.993M (± 1.8%) i/s - 10.010M in 5.024258s
### After
Array#flatten 124.005k (± 1.0%) i/s - 624.240k in 5.034477s
Array#+ 2.058M (± 4.8%) i/s - 10.302M in 5.019328s
### Test Code
require 'benchmark/ips'
class Foo
def to_ary
[1,2,3]
end
end
Benchmark.ips do |x|
ary = []
100.times { |i| ary << i }
array = [ary]
x.report "Array#flatten" do |i|
i.times { array.flatten }
end
x.report "Array#+" do |i|
obj = Foo.new
i.times { array + obj }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58978 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c: [DOC] add an example for Object#yield_self that
better illustrates its purpose; other small improvements.
Reported by Vitaly Tatarintsev (ck3g). Patch by Marcus Stollsteimer.
[Fix GH-1637]
* object.c: [DOC] improve docs for Object#{itself,tap}.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58972 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This improvement is similar with https://github.com/ruby/ruby/pull/1552
internal.h: add declaration of rb_eql_opt() API.
vm_insnhelper.c (rb_eql_opt): add rb_eql_opt() API which provides optimized
path for #eql? method such as rb_equal_opt().
object.c (rb_eql): optimize using rb_eql_opt() such as rb_equal().
Array#eql? and some methods have used rb_eql() and Array#eql? will be faster
around 20%.
[ruby-core:80761] [Bug #13447] [Fix GH-#1589]
### Before
user system total real
1.570000 0.000000 1.570000 ( 1.569754)
### After
user system total real
1.300000 0.000000 1.300000 ( 1.303624)
### Test code
require 'benchmark'
Benchmark.bmbm do |x|
ary1 = Array.new(1000) { rand(1000) }
ary2 = Array.new(1000) { rand(1000) }
x.report do
5000000.times do
ary1.eql?(ary2)
end
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58881 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_equal): add optimized path to compare the objects using
rb_equal_opt(). Previously, if not same objects were given, rb_equal() would
call `==' method via rb_funcall() which took a long time.
rb_equal_opt() has provided faster comparing for Fixnum/Float/String objects.
Now, Time#eql? uses rb_equal() to compare with argument object and it will
be faster around 40% on 64-bit environment.
* array.c (rb_ary_index): remove redundant rb_equal_opt() calling.
Now, rb_equal() was optimized using rb_equal_opt().
If rb_equal_opt() returns Qundef, it will invoke rb_equal() -> rb_equal_opt(),
and it will cause the performance regression.
So, this patch will remove first redundant rb_equal_opt() calling.
* array.c (rb_ary_rindex): ditto.
* array.c (rb_ary_includes): ditto.
[ruby-core:80360] [Bug #13365] [Fix GH-#1552]
### Before
Time#eql? with other 7.309M (± 1.4%) i/s - 36.647M in 5.014964s
Array#index(val) 1.433M (± 1.2%) i/s - 7.207M in 5.030942s
Array#rindex(val) 1.418M (± 1.6%) i/s - 7.103M in 5.009164s
Array#include?(val) 1.451M (± 0.9%) i/s - 7.295M in 5.026392s
### After
Time#eql? with other 10.321M (± 1.9%) i/s - 51.684M in 5.009203s
Array#index(val) 1.474M (± 0.9%) i/s - 7.433M in 5.044384s
Array#rindex(val) 1.449M (± 1.7%) i/s - 7.292M in 5.034436s
Array#include?(val) 1.466M (± 1.7%) i/s - 7.373M in 5.030047s
### Test code
require 'benchmark/ips'
Benchmark.ips do |x|
t1 = Time.now
t2 = Time.now
x.report "Time#eql? with other" do |i|
i.times { t1.eql?(t2) }
end
# Benchmarks to check whether it didn't introduce the regression
obj = Object.new
x.report "Array#index(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.index(obj) }
end
x.report "Array#rindex(val)" do |i|
ary = [1, 2, true, false, obj].reverse
i.times { ary.rindex(obj) }
end
x.report "Array#include?(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.include?(obj) }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58880 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_obj_size): The #yield_self Enumerator instance
always has a #count of `1`. This provides a lazy #size of `1`
to match the count instead of `nil`. [Fix GH-1615]
Author: Shannon Skipper <shannonskipper@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58714 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_obj_yield_self): new method which yields the
receiver and returns the result.
[ruby-core:46320] [Feature #6721]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58528 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_cstr_to_dbl): stop at successive underscores, as
well as Float literals. [ruby-core:80098] [Bug #13105]
* `_` should be within digits
* only one `_` allowed between digits
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is auto-generated using following command:
svn diff -r57807:57788 include internal.h bignum.c numeric.c compile.c insns.def object.c sprintf.c | patch -p0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57818 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Looking at the source code, FIXABLE tends to be just before LOING2FIX
to check applicability of that operation. Why not try computing first
then check for overflow, which should be optimial.
I also tried the same thing for unsigned types but resulted in slower
execution. It seems RB_POSFIXABLE() is fast enough on modern CPUs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* numeric.c (num_clone, num_dup): no longer raises TypeError,
returns the receiver instead as well as Integer and Float.
[ruby-core:79636] [Bug #13237]
* object.c (rb_immutable_obj_clone): immutable object clone with
freeze optional keyword argument.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57682 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_obj_clone2): extract option for clone, and split by
whether the object is immutable or mutable.
* object.c (rb_obj_clone): no arguments, return immutable object
immediately.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57680 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (special_object_p): uninterned Symbol also should not
raise a TypeError but return itself instead, as well as interned
Symbols. [ruby-core:79216] [Bug #13145]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_obj_alloc): add pathological check of klass for
extension libraries which do not check given arguments properly.
[ruby-core:78934] [Bug #13093]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57250 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (rb_class_new_instance): add pathological check of
klass for extension libraries which do not check given arguments
properly. [ruby-core:78934] [Bug #13093]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57249 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* object.c (special_object_p): no longer raise a TypeError for
Integer and Float, and return itself instead. [Feature#12979]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56933 b2dd03c8-39d4-4d8f-98ff-823fe69b080e