Age | Commit message (Collapse) | Author |
|
|
|
and add some comments.
(I confirm that `foo(**{})` allocates no hash object.)
|
|
This is a similar refactoring to 8c908c989077c74eed26e02912b98362e509b8a3,
but the target is compile_hash.
|
|
|
|
|
|
NODE_ZLIST case is handled in compile_hash, so iseq_compile_each0
doesn't have to do the same check redundantly.
|
|
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.
|
|
The array is just for a temporal buffer to create a hash, not stored in
the final iseq.
|
|
|
|
|
|
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)
|
|
The same refactoring as to b601b13c7267889bf394146353c5f2b0eb488278.
|
|
"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.
|
|
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.
|
|
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].
|
|
`[{}, {}, {}, ..., {}, *{}]` 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.
|
|
from array to list.
Follow up to ac50ac03aeb210763730cdc45f230e236519223d
|
|
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.
|
|
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
```
Notes:
Merged: https://github.com/ruby/ruby/pull/2428
|
|
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.
|
|
Ignore empty keyword splats in arrays
Notes:
Merged: https://github.com/ruby/ruby/pull/2418
Merged-By: jeremyevans <code@jeremyevans.net>
|
|
This seems to have been broken since 4e15be8bade.
|
|
----
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
Notes:
Merged: https://github.com/ruby/ruby/pull/1959
|
|
|
|
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.
Notes:
Merged: https://github.com/ruby/ruby/pull/2395
|
|
And, allow non-symbol keys as a keyword arugment
Notes:
Merged: https://github.com/ruby/ruby/pull/2395
|
|
After 5e86b005c0f2ef30df2f9906c7e2f3abefe286a2, 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.
|
|
After 5e86b005c0f2ef30df2f9906c7e2f3abefe286a2, 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.
|
|
Unfortunately, dladdr accepts void*, not const void*, in Solaris.
|
|
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.
|
|
Fixes error when using -Werror,-Wshorten-64-to-32.
|
|
|
|
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]
|
|
|
|
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
|
|
|
|
This reverts commit a0980f2446c0db735b8ffeb37e241370c458a626.
Retry for macOS Mojave.
|
|
This reverts commit 9faef3113fb4331524b81ba73005ba13fa0ef6c6.
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.
|
|
|
|
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>
|
|
Fixes [Bug #14062]
|
|
|
|
to suppress many warnings of Coverity Scan
|
|
|
|
to suppress many warnings of Coverity Scan
|
|
|
|
|
|
to suppress many warnings of Coverity Scan
|
|
|
|
|