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

998 Коммитов

Автор SHA1 Сообщение Дата
Yusuke Endoh 95297a15f1 compile.c (compile_hash): rewrite the compilation algorithm
This is a similar refactoring to 8c908c9890,
but the target is compile_hash.
2019-09-08 03:17:04 +09:00
Yusuke Endoh 4f63634af1 compile.c (NODE_OP_ASGN1): Remove unneeded DECL_ANCHOR 2019-09-08 01:22:26 +09:00
Yusuke Endoh 95f9d7c76d compile.c (keyword_node_p): Refactor out keyword node checks 2019-09-08 00:28:03 +09:00
Yusuke Endoh 86b74d1a73 compile.c (compile_hash): Remove redundant check for NODE_ZLIST
NODE_ZLIST case is handled in compile_hash, so iseq_compile_each0
doesn't have to do the same check redundantly.
2019-09-08 00:28:03 +09:00
Yusuke Endoh 050f67c9c6 compile.c (compile_hash): Simplify the keyword handling
The length of NODE_LIST chain in NODE_HASH is always even because it
represents key-value pairs.  There is no need to check for the
odd-length case.
2019-09-08 00:28:03 +09:00
Yusuke Endoh bb78c83678 compile.c (compile_hash): don't add a temporal array to mark_ary
The array is just for a temporal buffer to create a hash, not stored in
the final iseq.
2019-09-08 00:28:03 +09:00
Yusuke Endoh 7cba9a8406 compile.c (compile_array): undef a temporal macro 2019-09-08 00:28:02 +09:00
git a9b63db3b6 * remove trailing spaces. [ci skip] 2019-09-07 22:22:30 +09:00
Yusuke Endoh 8c908c9890 compile.c (compile_array): rewrite the compilation algorithm
The original code looks unnecessarily complicated (to me).
Also, it creates a pre-allocated array only for the prefix of the array.

The new code optimizes not only the prefix but also the subsequence that
is longer than 0x40 elements.

    # not optimized
    10000000.times { [1+1, 1,2,3,4,...,63]    } # 2.12 sec.
    # (1+1; push 1; push 2; ...; puts 63; newarray 64; concatarray)

    # optimized
    10000000.times { [1+1, 1,2,3,4,...,63,64] } # 1.46 sec.
    # (1+1; newarray 1; putobject [1,2,3,...,64]; concatarray)
2019-09-07 22:08:39 +09:00
Yusuke Endoh 07876bf6db compile.c (compile_hash): refactoring
The same refactoring as to b601b13c7267889bf394146353c5f2b0eb488278.
2019-09-07 20:25:12 +09:00
Yusuke Endoh 187328b703 compile.c (compile_array): refactoring
"popped" case can be so simple, so this change moves the branch to the
first, instead of scattering `if (popped)` branches to the main part.
Also, the return value "len" is not used.  So it returns just 0 or 1.
2019-09-07 20:25:12 +09:00
Yusuke Endoh a2260bd636 compile.c: Separate compile_list to two functions for Array and Hash
compile_list was for the compilation of Array literal and Hash literal.
I guess it was originally reasonable to handle them in one function, but
now, compilation of Array is very different from Hash.  So the function
was complicated by many branches for Array and Hash.

This change separates the function to two ones for Array and Hash.
2019-09-07 16:45:49 +09:00
Yusuke Endoh 2f2f8107d0 compile.c (compile_list): allow an odd-length hidden array literal
An array literal [1,2,...,301] was compiled to the following iseq:

  duparray [1,2,...,300]
  putobject [301]
  concatarray

The Array literal optimization took every two elements maybe because it
must handle not only Array but also Hash.
Now the optimization takes each element if it is an Array literal.  So
the new iseq is: duparray [1,2,...,301].
2019-09-07 16:26:38 +09:00
Yusuke Endoh 1e008105bc compile.c (compile_list): emit newarraykwsplat only at the last chunk
`[{}, {}, {}, ..., {}, *{}]` is wrongly created.

A big array literal is created and concatenated for every 256 elements.
The newarraykwsplat must be emitted only at the last chunk.
2019-09-07 16:05:15 +09:00
Yusuke Endoh a7a2be7a31 Rename some function/definition names that handles NODE_LIST
from array to list.
Follow up to ac50ac03aeb210763730cdc45f230e236519223d
2019-09-07 13:56:41 +09:00
Yusuke Endoh 99c9431ea1 Rename NODE_ARRAY to NODE_LIST to reflect its actual use cases
and NODE_ZARRAY to NODE_ZLIST.

NODE_ARRAY is used not only by an Array literal, but also the contents
of Hash literals, method call arguments, dynamic string literals, etc.
In addition, the structure of NODE_ARRAY is a linked list, not an array.

This is very confusing, so I believe `NODE_LIST` is a better name.
2019-09-07 13:56:29 +09:00
Jeremy Evans 1d5066efb0 Make m(**{}) mean call without keywords
Previously, **{} was removed by the parser:

```
$ ruby --dump=parse -e '{**{}}'
 @ NODE_SCOPE (line: 1, location: (1,0)-(1,6))
 +- nd_tbl: (empty)
 +- nd_args:
 |   (null node)
 +- nd_body:
     @ NODE_HASH (line: 1, location: (1,0)-(1,6))*
     +- nd_brace: 1 (hash literal)
     +- nd_head:
         (null node)
```

Since it was removed by the parser, the compiler did not know
about it, and `m(**{})` was therefore treated as `m()`.

This modifies the parser to not remove the `**{}`.  A simple
approach for this is fairly simple by just removing a few
lines from the parser, but that would cause two hash
allocations every time it was used.  The approach taken here
modifies both the parser and the compiler, and results in `**{}`
not allocating any hashes in the usual case.

The basic idea is we use a literal node in the parser containing
a frozen empty hash literal.  In the compiler, we recognize when
that is used, and if it is the only keyword present, we just
push it onto the VM stack (no creation of a new hash or merging
of keywords).  If it is the first keyword present, we push a
new empty hash onto the VM stack, so that later keywords can
merge into it.  If it is not the first keyword present, we can
ignore it, since the there is no reason to merge an empty hash
into the existing hash.

Example instructions for `m(**{})`

Before (note ARGS_SIMPLE):

```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,7)> (catch: FALSE)
0000 putself                                                          (   1)[Li]
0001 opt_send_without_block       <callinfo!mid:m, argc:0, FCALL|ARGS_SIMPLE>, <callcache>
0004 leave
```

After (note putobject and KW_SPLAT):

```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,7)> (catch: FALSE)
0000 putself                                                          (   1)[Li]
0001 putobject                    {}
0003 opt_send_without_block       <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache>
0006 leave
```

Example instructions for `m(**h, **{})`

Before and After (no change):

```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 putself                                                          (   1)[Li]
0001 putspecialobject             1
0003 newhash                      0
0005 putself
0006 opt_send_without_block       <callinfo!mid:h, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache>
0009 opt_send_without_block       <callinfo!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>, <callcache>
0012 opt_send_without_block       <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache>
0015 leave
```

Example instructions for `m(**{}, **h)`

Before:

```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 putself                                                          (   1)[Li]
0001 putspecialobject             1
0003 newhash                      0
0005 putself
0006 opt_send_without_block       <callinfo!mid:h, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache>
0009 opt_send_without_block       <callinfo!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>, <callcache>
0012 opt_send_without_block       <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache>
0015 leave
```

After (basically the same except for the addition of swap):

```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 putself                                                          (   1)[Li]
0001 newhash                      0
0003 putspecialobject             1
0005 swap
0006 putself
0007 opt_send_without_block       <callinfo!mid:h, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache>
0010 opt_send_without_block       <callinfo!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>, <callcache>
0013 opt_send_without_block       <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache>
0016 leave
```
2019-09-05 09:57:43 -07:00
Takashi Kokubun beaabd2308
Unify SUPPORT_JOKE and OPT_SUPPORT_JOKE
for simplicity and consistency.

Now SUPPORT_JOKE needs to be prefixed with OPT_ to make the config
visible in `RubyVM::VmOptsH`, and the inconsistency was introduced.

As it has never been available for override in configure (no #ifndef
guard), it should be fine to rename the config.
2019-09-03 21:12:31 +09:00
Jeremy Evans f560609d66
Merge pull request #2418 from jeremyevans/array-empty-kwsplat
Ignore empty keyword splats in arrays
2019-09-02 08:21:30 -07:00
Takashi Kokubun ca8ae759d0
Fix compilation error in SUPPORT_JOKE
This seems to have been broken since 4e15be8bad.
2019-09-02 23:37:52 +09:00
Urabe, Shyouhei 8ad7fafcdd opt_regexpmatch1 is actually making things slower.
----

trunk: ruby 2.6.0dev (2018-09-18 trunk 64767) [x86_64-darwin15]
ours: ruby 2.6.0dev (2018-09-18 opt_regexpmatch 64775) [x86_64-darwin15]
last_commit=opt_regexpmatch1 is actually making things slower.
Calculating -------------------------------------
                              trunk        ours
Optcarrot Lan_Master.nes     33.877      35.282 fps

Comparison:
             Optcarrot Lan_Master.nes
                    ours:        35.3 fps
                   trunk:        33.9 fps - 1.04x  slower
2019-09-02 13:56:40 +09:00
Kazuki Tsujimoto 94d6ec1d90
Make pattern matching support **nil syntax 2019-09-01 16:39:34 +09:00
Jeremy Evans 6a9ce1fea8 Support **nil syntax for specifying a method does not accept keyword arguments
This syntax means the method should be treated as a method that
uses keyword arguments, but no specific keyword arguments are
supported, and therefore calling the method with keyword arguments
will raise an ArgumentError.  It is still allowed to double splat
an empty hash when calling the method, as that does not pass
any keyword arguments.
2019-08-30 12:39:31 -07:00
Yusuke Endoh 16c6984bb9 Separate keyword arguments from positional arguments
And, allow non-symbol keys as a keyword arugment
2019-08-30 12:39:31 -07:00
卜部昌平 50f5a0a8d6 rb_hash_foreach now free from ANYARGS
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit adds function prototypes
for rb_hash_foreach / st_foreach_safe.  Also fixes some prototype
mismatches.
2019-08-27 15:52:26 +09:00
卜部昌平 b8fd2e83e7 decouple compile.c usage of imemo_ifunc
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit deletes ANYARGS from
struct vm_ifunc, but in doing so we also have to decouple the usage
of this struct in compile.c, which (I think) is an abuse of ANYARGS.
2019-08-27 15:52:26 +09:00
Yusuke Endoh d53b669948 compile.c: remove const from the first argument of dladdr
Unfortunately, dladdr accepts void*, not const void*, in Solaris.
2019-08-27 14:05:20 +09:00
Jeremy Evans 661927a4c5 Switch to using a VM stack argument instead of 2nd operand for getconstant
Some tooling depends on the current bytecode, and adding an operand
changes the bytecode.  While tooling can be updated for new bytecode,
this support doesn't warrant such a change.
2019-08-14 11:22:07 -07:00
Jeremy Evans 6ac6de84ac Use Qtrue/Qfalse instead of 1/0 for 2nd operand to getconstant
Fixes error when using -Werror,-Wshorten-64-to-32.
2019-08-14 09:59:27 -07:00
git d053a57014 * expand tabs. [ci skip] 2019-08-15 01:51:19 +09:00
Jeremy Evans fbcd065294 Remove support for nil::Constant
This was an intentional bug added in 1.9.

The approach taken here is to add a second operand to the
getconstant instruction for whether nil should be allowed and
treated as current scope.

Fixes [Bug #11718]
2019-08-14 09:50:14 -07:00
git 57288f5dbd * expand tabs. 2019-08-09 01:32:30 +09:00
Alan Wu 050b932152
Iseq#to_binary: Add support for NoMatchingPatternError and TypeError
Binary dumping the iseq for `case foo in []; end` used to crash as
there was no handling for these exception classes.

Pattern matching generates these classes as operands to `putobject`.

[Bug #16088]
Closes: https://github.com/ruby/ruby/pull/2325
2019-08-09 01:29:53 +09:00
Nobuyoshi Nakada 830fd04181
C99 allows trailing comma in enum 2019-08-09 01:27:52 +09:00
Yusuke Endoh 086ffe72c7 Revert "Revert "Add a specialized instruction for `.nil?` calls""
This reverts commit a0980f2446.

Retry for macOS Mojave.
2019-08-02 23:25:38 +09:00
Yusuke Endoh a0980f2446 Revert "Add a specialized instruction for `.nil?` calls"
This reverts commit 9faef3113f.

It seemed to cause a failure on macOS Mojave, though I'm unsure how.
https://rubyci.org/logs/rubyci.s3.amazonaws.com/osx1014/ruby-master/log/20190802T034503Z.fail.html.gz

This tentative revert is to check if the issue is actually caused by the
change or not.
2019-08-02 15:03:34 +09:00
git 714924fd34 * expand tabs. 2019-08-01 08:21:58 +09:00
Aaron Patterson 9faef3113f
Add a specialized instruction for `.nil?` calls
This commit adds a specialized instruction for called to `.nil?`.  It is
about 27% faster than master in the case where the object is nil or not
nil.  In the case where an object implements `nil?`, I think it may be
slightly slower.  Here is a benchmark:

```ruby
require "benchmark/ips"

class Niller
  def nil?; true; end
end

not_nil = Object.new
xnil = nil
niller = Niller.new

Benchmark.ips do |x|
  x.report("nil?")    { xnil.nil? }
  x.report("not nil") { not_nil.nil? }
  x.report("niller")   { niller.nil? }
end
```

On Ruby master:

```
[aaron@TC ~/g/ruby (master)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   429.195k i/100ms
             not nil   437.889k i/100ms
              niller   437.935k i/100ms
Calculating -------------------------------------
                nil?     20.166M (± 8.1%) i/s -    100.002M in   5.002794s
             not nil     20.046M (± 7.6%) i/s -     99.839M in   5.020086s
              niller     22.467M (± 6.1%) i/s -    112.111M in   5.013817s
[aaron@TC ~/g/ruby (master)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   449.660k i/100ms
             not nil   433.836k i/100ms
              niller   443.073k i/100ms
Calculating -------------------------------------
                nil?     19.997M (± 8.8%) i/s -     99.375M in   5.020458s
             not nil     20.529M (± 7.0%) i/s -    102.385M in   5.020689s
              niller     21.796M (± 8.0%) i/s -    108.110M in   5.002300s
[aaron@TC ~/g/ruby (master)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   402.119k i/100ms
             not nil   438.968k i/100ms
              niller   398.226k i/100ms
Calculating -------------------------------------
                nil?     20.050M (±12.2%) i/s -     98.519M in   5.008817s
             not nil     20.614M (± 8.0%) i/s -    102.280M in   5.004531s
              niller     22.223M (± 8.8%) i/s -    110.309M in   5.013106s

```

On this branch:

```
[aaron@TC ~/g/ruby (specialized-nilp)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   468.371k i/100ms
             not nil   456.517k i/100ms
              niller   454.981k i/100ms
Calculating -------------------------------------
                nil?     27.849M (± 7.8%) i/s -    138.169M in   5.001730s
             not nil     26.417M (± 8.7%) i/s -    131.020M in   5.011674s
              niller     21.561M (± 7.5%) i/s -    107.376M in   5.018113s
[aaron@TC ~/g/ruby (specialized-nilp)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   477.259k i/100ms
             not nil   428.712k i/100ms
              niller   446.109k i/100ms
Calculating -------------------------------------
                nil?     28.071M (± 7.3%) i/s -    139.837M in   5.016590s
             not nil     25.789M (±12.9%) i/s -    126.470M in   5.011144s
              niller     20.002M (±12.2%) i/s -     98.144M in   5.001737s
[aaron@TC ~/g/ruby (specialized-nilp)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   467.676k i/100ms
             not nil   445.791k i/100ms
              niller   415.024k i/100ms
Calculating -------------------------------------
                nil?     26.907M (± 8.0%) i/s -    133.755M in   5.013915s
             not nil     25.319M (± 7.9%) i/s -    125.713M in   5.007758s
              niller     19.569M (±11.8%) i/s -     96.286M in   5.008533s
```

Co-Authored-By: Ashe Connor <kivikakk@github.com>
2019-07-31 16:21:25 -07:00
Jeremy Evans aa97410b0a Warn if using return at top-level with an argument
Fixes [Bug #14062]
2019-07-29 09:01:23 -07:00
git bdec1ad9a9 * expand tabs. 2019-07-17 23:42:21 +09:00
Yusuke Endoh 416ead4cda compile.c: add NO_CHECK for the calls to COMPILE whose result is unused
to suppress many warnings of Coverity Scan
2019-07-17 23:41:58 +09:00
git a8e4b7b12f * expand tabs. 2019-07-16 07:19:52 +09:00
Yusuke Endoh c184a1c261 compile.c: add NO_CHECK for the calls to COMPILE whose result is unused
to suppress many warnings of Coverity Scan
2019-07-16 07:18:54 +09:00
Yusuke Endoh 6aab77a7a3 Add a /* fall through */ comment 2019-07-16 07:17:57 +09:00
git f103ed8b7d * expand tabs. 2019-07-15 14:43:39 +09:00
Yusuke Endoh 4b345f9d4b compile.c: ignore the result of COMPILE by marking with NO_CHECK
to suppress many warnings of Coverity Scan
2019-07-15 14:43:24 +09:00
Yusuke Endoh c9a59f491d Add a /* fall through */ comment 2019-07-15 07:59:11 +09:00
Yusuke Endoh 772dae8bef Add a /* fall through */ comment 2019-07-15 07:57:07 +09:00
Yusuke Endoh 3201062adf Add a /* fall through */ comment 2019-07-15 00:31:07 +09:00
Yusuke Endoh 970c12551e Add a /* fall through */ comment 2019-07-15 00:30:35 +09:00