Age | Commit message (Collapse) | Author |
|
Related: ruby/prism#2935
Notes:
Merged: https://github.com/ruby/ruby/pull/11415
|
|
|
|
This test is checking what happens if you try and define a class in a C
extension where that constant is already not a class. It was doing this
by overriding ::Date and then trying to require 'date. The issue with
this is that if we ever add 'date' as a dependency for the test runner,
this test will break because the test runner files get implicitly
required in an `assert_separately` block.
Better use an explicit class for this purpose which can't be accidentally
required elsewhere.
Notes:
Merged: https://github.com/ruby/ruby/pull/11400
|
|
Notes:
Merged-By: ono-max <[email protected]>
|
|
Previously, proc calls such as:
```ruby
proc{|| }.(**empty_hash)
proc{|b: 1| }.(**r2k_array_with_empty_hash)
```
both allocated hashes unnecessarily, due to two separate code paths.
The first call goes through CALLER_SETUP_ARG/vm_caller_setup_keyword_hash,
and is simple to fix by not duping an empty keyword hash that will be
dropped.
The second case is more involved, in setup_parameters_complex, but is
fixed the exact same way as when the ruby2_keywords hash is not empty,
by flattening the rest array to the VM stack, ignoring the last
element (the empty keyword splat). Add a flatten_rest_array static
function to handle this case.
Update test_allocation.rb to automatically convert the method call
allocation tests to proc allocation tests, at least for the calls
that can be converted. With the code changes, all proc call
allocation tests pass, showing that proc calls and method calls
now allocate the same number of objects.
I've audited the allocation tests, and I believe that all of the low
hanging fruit has been collected. All remaining allocations are
either caller side:
* Positional splat + post argument
* Multiple positional splats
* Literal keywords + keyword splat
* Multiple keyword splats
Or callee side:
* Positional splat parameter
* Keyword splat parameter
* Keyword to positional argument conversion for methods that don't accept keywords
* ruby2_keywords method called with keywords
Reapplies abc04e898b627ab37fa9dd5e330f239768778d8b, which was reverted at
d56470a27c5a8a2e7aee7a76cea445c2d29c0c59, with the addition of a bug fix and
test.
Fixes [Bug #20679]
Notes:
Merged: https://github.com/ruby/ruby/pull/11409
Merged-By: jeremyevans <[email protected]>
|
|
When assertions are enabled, the following code triggers an assertion
error:
GC.disable
GC.start(immediate_mark: false, immediate_sweep: false)
10_000_000.times { Object.new }
This is because the GC.start ignores that the GC is disabled and will
start incremental marking and lazy sweeping. But the assertions in
gc_marks_continue and gc_sweep_continue assert that GC is not disabled.
This commit changes it for the assertion to pass if the GC was triggered
from a method.
Notes:
Merged: https://github.com/ruby/ruby/pull/11391
|
|
Make Range#step to consistently use + for iteration [Feature #18368]
Previously, non-numerics expected step to be integer,
and iterated with begin#succ, skipping over step value
steps. Since this commit, numeric and non-numeric iteration
behaves the same way, by using + operator.
Notes:
Merged-By: zverok <[email protected]>
|
|
This reverts commit abc04e898b627ab37fa9dd5e330f239768778d8b.
This caused problems in a Rails test.
Notes:
Merged: https://github.com/ruby/ruby/pull/11394
|
|
TracePoints with incompatible events (i.e. events not in ISEQ_TRACE_EVENTS)
with a method target will fail an assertion error because it does not
filter for the supported events. For example, the following lines will
cause an assertion error:
def foo; end
# No arguments passed into TracePoint.new enables all ISEQ_TRACE_EVENTS
TracePoint.new {}.enable(target: method(:foo))
# Raise is not supported with a target
TracePoint.new(:raise, :return) {}.enable(target: method(:foo))
foo
Crashes with:
Assertion Failed: vm_insnhelper.c:7026:vm_trace:(iseq_local_events & ~(0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010| 0x0020| 0x0040 | 0x0100 | 0x0200 | 0x4000 | 0x010000| 0x020000)) == 0
Notes:
Merged: https://github.com/ruby/ruby/pull/11390
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11368
|
|
Previous, proc calls such as:
```ruby
proc{|| }.(**empty_hash)
proc{|b: 1| }.(**r2k_array_with_empty_hash)
```
both allocated hashes unnecessarily, due to two separate code paths.
The first call goes through CALLER_SETUP_ARG/vm_caller_setup_keyword_hash,
and is simple to fix by not duping an empty keyword hash that will be
dropped.
The second case is more involved, in setup_parameters_complex, but is
fixed the exact same way as when the ruby2_keywords hash is not empty,
by flattening the rest array to the VM stack, ignoring the last
element (the empty keyword splat). Add a flatten_rest_array static
function to handle this case.
Update test_allocation.rb to automatically convert the method call
allocation tests to proc allocation tests, at least for the calls
that can be converted. With the code changes, all proc call
allocation tests pass, showing that proc calls and method calls
now allocate the same number of objects.
I've audited the allocation tests, and I believe that all of the low
hanging fruit has been collected. All remaining allocations are
either caller side:
* Positional splat + post argument
* Multiple positional splats
* Literal keywords + keyword splat
* Multiple keyword splats
Or callee side:
* Positional splat parameter
* Keyword splat parameter
* Keyword to positional argument conversion for methods that don't accept keywords
* ruby2_keywords method called with keywords
Notes:
Merged: https://github.com/ruby/ruby/pull/11258
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11386
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11386
|
|
The test is timing out on lpi4a so a longer timeout should fix it.
|
|
We need to remove from the finalizer_table after running all the
finalizers because GC could trigger during the finalizer which could
reclaim the finalizer table array.
The following code crashes:
1_000_000.times do
o = Object.new
ObjectSpace.define_finalizer(o, proc { })
end
Notes:
Merged: https://github.com/ruby/ruby/pull/11375
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11373
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11366
|
|
Some case it is difficult to know the calling method uses a block
or not with `send` on a general framework. So this patch stops
showing unused block warning on `send`.
example with test/unit:
```ruby
require 'test/unit'
class T < Test::Unit::TestCase
def setup
end
def test_foo = nil
end
```
=> /home/ko1/ruby/install/master/lib/ruby/gems/3.4.0+0/gems/test-unit-3.6.2/lib/test/unit/fixture.rb:284: warning: the block passed to 'priority_setup' defined at /home/ko1/ruby/install/master/lib/ruby/gems/3.4.0+0/gems/test-unit-3.6.2/lib/test/unit/priority.rb:183 may be ignored
because test/unit can call any setup method (`priority_setup` in this case) with a block.
Maybe we can show the warning again when we provide a way to recognize
the calling method uses a block or not.
Notes:
Merged: https://github.com/ruby/ruby/pull/11349
|
|
[Bug #20344]
Fix compile_next adding removable adjust label
Notes:
Merged: https://github.com/ruby/ruby/pull/11316
|
|
`RBOOL` is a macro to convert C boolean to Ruby boolean.
Notes:
Merged: https://github.com/ruby/ruby/pull/11351
|
|
The bug didn't impact master because this was largely refactored,
but it's still valuable to add the test for it to prevent future
regressions.
Notes:
Merged: https://github.com/ruby/ruby/pull/11359
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11348
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11307
|
|
The parallel testing framework may create strings in a separate thread.
```
1) Failure:
TestStringMemory#test_byteslice_prefix [D:/a/ruby/ruby/src/test/ruby/test_string_memory.rb:40]:
One object allocation is expected, but allocated: [["D:/a/ruby/ruby/src/tool/lib/test/unit/parallel.rb", 42, String, "2240\x00\x00\x00\x00...
```
https://github.com/ruby/ruby/actions/runs/10222885396/job/28288271190?pr=11271#step:23:1026
Notes:
Merged: https://github.com/ruby/ruby/pull/11306
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11297
|
|
According to Launchable, these tests fail randomly
```
Failure:
TestStringMemory#test_byteslice_prefix [D:/a/ruby/ruby/src/test/ruby/test_string_memory.rb:33]:
<1> expected but was
<2>.
```
https://app.launchableinc.com/organizations/ruby/workspaces/ruby/data/test-paths/file%3Dtest%2Fruby%2Ftest_string_memory.rb%23%23%23class%3DTestStringMemory%23%23%23testcase%3Dtest_byteslice_prefix?testSessionStatus=flake
Notes:
Merged: https://github.com/ruby/ruby/pull/11295
|
|
The tests for Integer#ceil was accidentally placed in test_truncate.
|
|
[Bug #20654]
This commit fixes Integer#ceil and Float#ceil when the number is
negative and ndigits is large such that 10**ndigits is a bignum.
Previously, it would return 0 in such cases. However, this would cause
unexpected behaviour such as:
puts 1.ceil(-5) # => 100000
puts 1.ceil(-10) # => 10000000000
puts 1.ceil(-20) # => 0
This commit changes the last result so that it will return
100000000000000000000.
Notes:
Merged: https://github.com/ruby/ruby/pull/11257
|
|
[Bug #20654]
This commit fixes Integer#floor and Float#floor when the number is
negative and ndigits is large such that 10**ndigits is a bignum.
Previously, it would return 0 in such cases. However, this would cause
unexpected behaviour such as:
puts -1.floor(-5) # => -100000
puts -1.floor(-10) # => -10000000000
puts -1.floor(-20) # => 0
This commit changes the last result so that it will return
-100000000000000000000.
Notes:
Merged: https://github.com/ruby/ruby/pull/11257
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11267
Merged-By: nobu <[email protected]>
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11276
|
|
This is slowing down benchmarks on x86, so lets revert it for now.
Notes:
Merged: https://github.com/ruby/ruby/pull/11275
|
|
Use an enum for the method arg instead of needing to add an id
that doesn't map to an actual method name.
$ ruby --dump=insns -e 'b = "x"; [v].pack("E*", buffer: b)'
before:
```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,34)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] b@0
0000 putchilledstring "x" ( 1)[Li]
0002 setlocal_WC_0 b@0
0004 putself
0005 opt_send_without_block <calldata!mid:v, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0007 newarray 1
0009 putchilledstring "E*"
0011 getlocal_WC_0 b@0
0013 opt_send_without_block <calldata!mid:pack, argc:2, kw:[#<Symbol:0x000000000023110c>], KWARG>
0015 leave
```
after:
```
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,34)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] b@0
0000 putchilledstring "x" ( 1)[Li]
0002 setlocal_WC_0 b@0
0004 putself
0005 opt_send_without_block <calldata!mid:v, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0007 putchilledstring "E*"
0009 getlocal b@0, 0
0012 opt_newarray_send 3, 5
0015 leave
```
Notes:
Merged: https://github.com/ruby/ruby/pull/11249
|
|
[Bug #20653]
This commit refactors how Onigmo handles timeout. Instead of raising a
timeout error, onig_search will return a ONIGERR_TIMEOUT which the
caller can free memory, and then raise a timeout error.
This fixes a memory leak in String#start_with when the regexp times out.
For example:
regex = Regexp.new("^#{"(a*)" * 10_000}x$", timeout: 0.000001)
str = "a" * 1000000 + "x"
10.times do
100.times do
str.start_with?(regex)
rescue
end
puts `ps -o rss= -p #{$$}`
end
Before:
33216
51936
71152
81728
97152
103248
120384
133392
133520
133616
After:
14912
15376
15824
15824
16128
16128
16144
16144
16160
16160
Notes:
Merged: https://github.com/ruby/ruby/pull/11247
|
|
Hash.new no longer takes keyword arguments except for capacity, so we
should just use a method that takes keyword arguments instead.
Notes:
Merged: https://github.com/ruby/ruby/pull/11246
|
|
[Bug #20650]
The capture group allocates memory that is leaked when it times out.
For example:
re = Regexp.new("^#{"(a*)" * 10_000}x$", timeout: 0.000001)
str = "a" * 1000000 + "x"
10.times do
100.times do
re =~ str
rescue Regexp::TimeoutError
end
puts `ps -o rss= -p #{$$}`
end
Before:
34688
56416
78288
100368
120784
140704
161904
183568
204320
224800
After:
16288
16288
16880
16896
16912
16928
16944
17184
17184
17200
Notes:
Merged: https://github.com/ruby/ruby/pull/11238
|
|
GitHub Actions macos-14 machine is stupid.
https://app.launchableinc.com/organizations/ruby/workspaces/ruby/data/test-paths/file%3Dtest%2Fruby%2Ftest_file.rb%23%23%23class%3DTestFile%23%23%23testcase%3Dtest_stat?organizationId=ruby&workspaceId=ruby&testPathId=file%3Dtest%2Fruby%2Ftest_file.rb%23%23%23class%3DTestFile%23%23%23testcase%3Dtest_stat&testSessionStatus=flake
Notes:
Merged: https://github.com/ruby/ruby/pull/11241
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11234
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11227
|
|
This commit introduce `RubyVM::AbstractSyntaxTree::Node#locations` method
and `RubyVM::AbstractSyntaxTree::Location` class.
Ruby AST node will hold multiple locations information.
`RubyVM::AbstractSyntaxTree::Node#locations` provides a way to access
these locations information.
`RubyVM::AbstractSyntaxTree::Location` is a class which holds these location information:
* `#first_lineno`
* `#first_column`
* `#last_lineno`
* `#last_column`
Notes:
Merged: https://github.com/ruby/ruby/pull/11226
|
|
Unparenthesize the argument and make `command_call` when calling with
`do`-block.
Notes:
Merged: https://github.com/ruby/ruby/pull/11216
|
|
call
Notes:
Merged: https://github.com/ruby/ruby/pull/11215
|
|
Enumerator#zip yields a single array, not multiple arguments,
so Enumerator::Lazy#zip should do the same.
Fixes [#20623]
Notes:
Merged: https://github.com/ruby/ruby/pull/11212
|
|
When calling a method that does not accept a positional splat
parameter with a splatted array with a ruby2_keywords flagged hash,
there is no need to duplicate the splatted array. Previously,
Ruby would duplicate the splatted array and potentially modify
it before flattening it to the VM stack
Use a similar approach as the f(*ary, **hash) optimization,
flattening the splatted array to the VM stack without modifying
it, and make any modifications needed to the VM stack.
Notes:
Merged: https://github.com/ruby/ruby/pull/11161
|
|
When calling a method that accepts keywords but not a keyword
splat with a splatted array with a ruby2_keywords flagged hash,
there is no need to duplicate the ruby2_keywords flagged hash,
since it will be accessed to get the keyword values, but it will
not be modified.
Notes:
Merged: https://github.com/ruby/ruby/pull/11161
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11161
|
|
This avoids an array allocation when calling a method that does
not accept a positional splat or keywords with both a positional
splat and keywords. Previously, Ruby would dup the positional
splat to append the keyword splat to it. Then it would flatten
the dupped positional splat array to the VM stack.
This flattens the given positional splat to the VM stack, then
adds the keyword splat hash after the last positional splat
element on the VM stack, avoiding the need to modify
the positional splat array.
Notes:
Merged: https://github.com/ruby/ruby/pull/11161
|
|
a: lvar), and other calls
The `f(arg, *arg, **arg, **arg)` case was previously not optimized.
The optimizer didn't optimize this case because of the multiple
keyword splats, and the compiler didn't optimize it because the
`f(*arg, **arg, **arg)` optimization added in
0ee3960685e283d8e75149a8777eb0109d41509a didn't apply.
I found it difficult to apply this optimization without changing
the `setup_args_core` API, since by the time you get to the ARGSCAT
case, you don't know whether you were called recursively or directly,
so I'm not sure if it was possible to know at that point whether the
array allocation could be avoided.
This changes the dup_rest argument in `setup_args_core` from an int
to a pointer to int. This allows us to track whether we have allocated
a caller side array for multiple splats or splat+post across
recursive calls. Check the pointed value (*dup_rest) to determine the
`splatarray` argument. If dup_rest is 1, then use `splatarray true`
(caller-side array allocation), then set *dup_rest back to 0, ensuring
only a single `splatarray true` per method call.
Before calling `setup_args_core`, check whether the array allocation
can be avoided safely using `splatarray false`. Optimizable cases are:
```
// f(*arg)
SPLAT
// f(1, *arg)
ARGSCAT
LIST
// f(*arg, **arg)
ARGSPUSH
SPLAT
HASH nd_brace=0
// f(1, *arg, **arg)
ARGSPUSH
ARGSCAT
LIST
HASH nd_brace=0
```
If so, dup_rest is set to 0 instead of 1 to avoid the allocation.
After calling `setup_args_core`, check the flag. If the flag
includes `VM_CALL_ARGS_SPLAT`, and the pointed value has changed,
indicating `splatarray true` was used, then also set
`VM_CALL_ARGS_SPLAT_MUT` in the flag.
My initial attempt at this broke the `f(*ary, &ary.pop)` test,
because we were not duplicating the ary in the splat even though
it was modified later (evaluation order issue). The initial attempt
would also break `f(*ary, **ary.pop)` or `f(*ary, kw: ary.pop)` cases
for the same reason. I added test cases for those evaluation
order issues.
Add setup_args_dup_rest_p static function that checks that a given
node is safe. Call that on the block pass node to determine if
the block pass node is safe. Also call it on each of the hash
key/value nodes to test that they are safe. If any are not safe,
then set dup_rest = 1 so that `splatarray true` will be used to
avoid the evaluation order issue.
This new approach has the affect of optimizing most cases of
literal keywords after positional splats. Previously, only
static keyword hashes after positional splats avoided array
allocation for the splat. Now, most dynamic keyword hashes
after positional splats also avoid array allocation.
Add allocation tests for dynamic keyword keyword hashes after
positional splats.
setup_args_dup_rest_p is currently fairly conservative. It
could definitely be expanded to handle additional node types
to reduce allocations in additional cases.
Notes:
Merged: https://github.com/ruby/ruby/pull/11161
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11201
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11192
|