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

811 Коммитов

Автор SHA1 Сообщение Дата
卜部昌平 9ec4f1f205 rb_big_aref: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 184f0ab4c9 rb_int_parse_cstr: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 5a7c0dd038 str2big_scan_digits: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 4dfc2f2e3d bary_mul_karatsuba_branch: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
Nobuyoshi Nakada b8fadf3a6b
Respect BIGNUM_DEBUG defined by command line option
And fixed typo in compilers.yml.
2020-05-29 02:43:30 +09:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00
卜部昌平 d7f4d732c1 sed -i s|ruby/3|ruby/impl|g
This shall fix compile errors.
2020-05-11 09:24:08 +09:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09:00
Nobuyoshi Nakada 5b287481be
Removed non-RUBY_INTEGER_UNIFICATION code 2020-03-21 16:59:55 +09:00
Nobuyoshi Nakada 6f0446785b
Leave power cache table initialized as Qfalse 2020-03-21 16:42:19 +09:00
卜部昌平 aa44b29030 suppress uninitialized variable warnings
Starting GCC 7, warnings about uninitialized variables are issued around
them.  Such warnings could be false positives (all versions of clang do
not warn), but adding initializers there could never be bad things.
2020-03-04 12:30:42 +09:00
Bernhard F. Brodowsky 07c98537ca
Clarified documentation in rb_integer_unpack [ci skip]
I struggled figuring out which of the pack/unpack functions goes into which direction and the two first sentences were of the documentation were:
* Import an integer into a buffer.
* Export an integer into a buffer.

It sounds like both of them go from a ruby integer to a buffer because both use "into". So I fixed it and went to "Import an integer from a buffer". I find this much more clear.
2020-02-08 09:57:15 +09:00
Kenta Murata 076f24c227
bignum.c: extract bdigits_to_mpz and bdigits_from_mpz (#2805) 2020-01-01 22:55:12 +09:00
Kenta Murata e082f41611
Introduce BIGNUM_EMBED_P to check BIGNUM_EMBED_FLAG (#2802)
* bignum.h: Add BIGNUM_EMBED_P

* bignum.c: Use macros for handling BIGNUM_EMBED_FLAG
2019-12-31 22:48:23 +09:00
卜部昌平 5e22f873ed decouple internal.h headers
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.

We take the following inclusion order in this changeset:

1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.

Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
2019-12-26 20:45:12 +09:00
卜部昌平 099778a6da internal/bingnum.h rework
Turn macros into inline functions for better readability.  Also add
rb_int128t2big delcaration, which was missing.
2019-12-26 20:45:12 +09:00
卜部昌平 0958e19ffb add several __has_something macro
With these macros implemented we can write codes just like we can assume
the compiler being clang.  MSC_VERSION_SINCE is defined to implement
those macros, but turned out to be handy for other places.  The -fdeclspec
compiler flag is necessary for clang to properly handle __has_declspec().
2019-12-26 20:45:12 +09:00
卜部昌平 0e8219f591 make functions static
These functions are used from within a compilation unit so we can
make them static, for better binary size.  This changeset reduces
the size of generated ruby binary from 26,590,128 bytes to
26,584,472 bytes on my macihne.
2019-11-19 12:36:19 +09:00
Yusuke Endoh f364564e66 bignum.c (estimate_initial_sqrt): prevent integer overflow
`Integer.sqrt(0xffff_ffff_ffff_ffff ** 2)` caused assertion failure
because of integer overflow.  [ruby-core:95453] [Bug #16269]
2019-10-21 21:24:21 +09:00
Nobuyoshi Nakada ad6cbc1d33
Unused LONG_MAX_as_double
LONG_MAX_as_double is not needed when long is small enough to be
exactly representable as a double, e.g., IL32LLP64 platforms.
2019-09-10 17:20:31 +09:00
卜部昌平 41bc766763 interesting (but annoying) tidbit warning suppressed
This changeset is to suppress clang's -Wimplicit-int-float-conversion
warning.

In 64 bit signed long and IEEE 754 double combination (== almost
everyone these days), LONG_MAX is 9,223,372,036,854,775,807.  This
value is _not_ exactly representable by double.  The nearest value
that a double can represnt is 9,223,372,036,854,775,808. It is one
greater than LONG_MAX.  Let's call this value the "x".

The expression `LONG_MAX < yi` is a long versus double comparison.
According to ISO/IEC 9899:1999 Section 6.3.1.8 (that defines the
"usual rithmetic conversions"), The long value must first be casted
into double.  Because FLT_ROUNDS is typically 1 ("round to the
nearest" mode), the conversion yields the "x" value shown above.  So
the comparison is in fact `x < yi`.

This comparison is false for yi == x situation, i.e. yi is still
bigger than LONG_MAX.  On such situation the `yn = (long)yi;`
statement that appear several lines below renders underfined
behaviour, as per ISO/IEC 9899:1999 Section 6.3.1.3.

To remedy, we just change the comparison from `<` to `<=` so that
yi == x situation can properly be handled.
2019-09-05 14:29:11 +09:00
git fb96bea7ed * expand tabs. 2019-08-03 10:25:20 +09:00
Nobuyoshi Nakada 4ea5c5610a
Predefine some IDs 2019-08-03 10:18:39 +09:00
nobu 56557ec28a [DOC] fix markups [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-22 11:04:59 +00:00
svn 6304c0c4d1 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66713 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-04 13:14:18 +00:00
normal 23444302d9 introduce rb_nogvl C-API to mark ubf as async-signal-safe
zlib and bignum both contain unblocking functions which are
async-signal-safe and do not require spawning additional
threads.

We can execute those functions directly in signal handlers
without incurring overhead of extra threads, so provide C-API
users the ability to deal with that.  Other C-API users may
have similar need.

This flexible API can supercede existing uses of
rb_thread_call_without_gvl and rb_thread_call_without_gvl2 by
introducing a flags argument to control behavior.

Note: this API is NOT finalized.  It needs approval from other
committers.  I prefer shorter name than previous
rb_thread_call_without_gvl* functions because my eyes requires
big fonts.

[Bug #15499]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66712 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-04 13:14:11 +00:00
nobu dc8afd385d complex.c: rb_complex_new_polar
* 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
2018-12-12 11:06:47 +00:00
shyouhei 73549c501f bignum.c: fix bug in big2dbl()
I was wrong at r65753.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-16 03:34:53 +00:00
shyouhei 1a84c57e23 bignum.c: avoid (size_t)--
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65754 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-16 03:09:00 +00:00
shyouhei ca14914039 bignum.c: BDIGIT might or might not integer-promote
BDIGIT can be unsigned int or unsigned short, depending on BDIGIT_DBL.
Given that, unsigned int and unsigned short are different in how
integer promotion works.  BOGLO assumes its argument is wider than
BDIGIT, which is not always true.  We have to force that explicitly.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65753 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-16 02:59:30 +00:00
shyouhei 3a083985a4 avoid division by zero
* cvt(): use signbit() instead of 1/d < 0
* w_float(): ditto
* ruby_float_step_size(): unit==0 check shall be prior to divisions
* arith_seq_float_step_size(): ditto
* rb_big_divide(): same as r65642
* fix_divide(): ditto
* rb_big_fdiv_double(): ditto
* fix_fdiv_double(): ditto


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-16 01:52:39 +00:00
nobu 9b38ed530f bignum.c: suppress unused variable warning
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65749 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-16 00:28:43 +00:00
svn 906c8788b9 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65740 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-15 07:34:06 +00:00
shyouhei 86d1fc8863 suppress integer overflow warnings
* util.c: annotate as NO_SANITIZE
* bignum.c: avoid (size_t)--
* marshal.c: ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65739 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-15 07:34:01 +00:00
shyouhei 2212c1dc16 bignum.c: ee should be signed
In C, signed + unsigned of the same size results in unsigned (cf:
ISO/IEC 9899:1990 section 6.2.1.5). However `num` is signed here.
Which means the addition must be done in signed.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-15 05:10:40 +00:00
shyouhei 7f6691ae77 suppress integer overflow warnings
* random.c: annotate rb_hash_start with NO_SANITIZE (seed.key.hash + h
  overflows and that seems intentional)
* bignum.c: avoid (size_t)--
* cont.c: ditto
* util.c: ditto
* vm_insnhelper.c: ditto



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65688 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-13 00:40:52 +00:00
shyouhei 199c5cc185 ~(unsigned char) is not unsigned char
The unary ~ operator excercises integer promotion of the operand
_before_ actually applying bitwise complement (cf: ISO/IEC 9899:1990
section 6.3.3.3).  Which means `~buf[i]` is in fact
`(int)~(int)buf[i]`.

The problem is, when buf[i] is 0xFF:

      buf[i]        0xFF
 (int)buf[i] 0x0000_00FF
~(int)buf[i] 0xFFFF_FF00 This is -256, out of unsigned char range.

The proposed fix is to change the char signed.  By doing so,

                   buf[i]        0xFF
      (signed char)buf[i]        0xFF
 (int)(signed char)buf[i] 0xFFFF_FFFF
~(int)(signed char)buf[i] 0x0000_0000 This is 0, does not overflow.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65675 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-12 01:08:35 +00:00
nobu 3e063ca7ae complex.c: rb_dbl_complex_polar_pi
* 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
2018-11-04 00:22:13 +00:00
nobu 603f95a0ed Fix Rational of Float
[ruby-core:89239] [Bug #15189]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-02 16:42:21 +00:00
nobu 97e05dad7f UNREACHABLE_RETURN
* 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
2018-07-24 05:38:07 +00:00
nobu 4fedad85ef refine Integer#** and Float#**
* 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
2018-06-17 02:37:32 +00:00
nobu c9db11ea60 bignum.c: get rid of redefined method
* 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
2018-06-14 07:09:02 +00:00
nobu 8ee960c55c bignum.c: call functions directly
* bignum.c (int_pow_tmp{1,2,3}): call dedicated functions directly
  for internal calculations, instead of method calls.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63643 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-13 01:21:59 +00:00
nobu c3b656bc8e bignum.c: refine pow
* bignum.c (rb_big_pow): make Complex and Rational instances from
  calculated results by API functions.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63642 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-13 01:04:33 +00:00
mame 85bcd2b35f bignum.c: Bignum#fdiv avoids double division when divisor is bignum
`Rational(int, bignum).to_f` sometimes returned a wrong result because
`Bignum#div` casted its divisor to double.  [Bug #14637] [ruby-core:86330]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-04 14:02:59 +00:00
mrkn 2cfc5b03da Add `exception:` keyword in Kernel#Integer()
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
2018-03-15 07:19:43 +00:00
mrkn 591baf8fe3 rb_int_powm: call rb_int_pow directly
* bignum.c (rb_int_powm): call rb_int_pow directly instead of calling `**`
  operator.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62567 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-24 15:36:09 +00:00
nobu b9d01e2257 [DOC] obsolete classes
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62543 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-23 02:16:43 +00:00
nobu d77e8a7da5 Signature of rb_uint2big and rb_int2big
* include/ruby/ruby.h (rb_uint2big, rb_int2big): declare with
  uintptr_t and intptr_t instead of VALUE and SIGNED_VALUE
  respectively.  [ruby-core:83424] [Bug #14036]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-20 08:01:44 +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