Age | Commit message (Collapse) | Author |
|
|
|
|
|
This prevents early collection of the array. The GC doesn't see the
array on the stack when Ruby is compiled with optimizations enabled
[ruby-core:105099] [Bug #18140]
|
|
In vm_call_method_each_type, check for c_call and c_return events before
dispatching to vm_call_ivar and vm_call_attrset. With this approach, the
call cache will still dispatch directly to those functions, so this
change will only decrease performance for the first (uncached) call, and
even then, the performance decrease is very minimal.
This approach requires that we clear the call caches when tracing is
enabled or disabled. The approach currently switches all vm_call_ivar
and vm_call_attrset call caches to vm_call_general any time tracing is
enabled or disabled. So it could theoretically result in a slowdown for
code that constantly enables or disables tracing.
This approach does not handle targeted tracepoints, but from my testing,
c_call and c_return events are not supported for targeted tracepoints,
so that shouldn't matter.
This includes a benchmark showing the performance decrease is minimal
if detectable at all.
Fixes [Bug #16383]
Fixes [Bug #10470]
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Notes:
Merged: https://github.com/ruby/ruby/pull/4767
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4788
|
|
|
|
|
|
These were introduced in the test for tracing optimized methods
added in 48c8df9e0eb295af06d593ce37ce1933c0ee1d90.
|
|
Mashalling a closed IO object raised "closed stream (IOError)" before instead of TypeError.
This changes IO#(in|ex)ternal_encoding to still return the encoding even if the underlying FD is closed.
Fixes bug #18077
Notes:
Merged: https://github.com/ruby/ruby/pull/4758
|
|
This updates the trace instructions to directly dispatch to
opt_send_without_block. So this should cause no slowdown in
non-trace mode.
To enable the tracing of the optimized methods, RUBY_EVENT_C_CALL
and RUBY_EVENT_C_RETURN are added as events to the specialized
instructions.
Fixes [Bug #14870]
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Notes:
Merged: https://github.com/ruby/ruby/pull/4739
Merged-By: jeremyevans <code@jeremyevans.net>
|
|
... as per ko1's preference. He is preparing to extend this feature to
ISeq for his new debugger. He prefers "keep" to "save" for this wording.
This API is internal and not included in any released version, so I
change it in advance.
|
|
[ruby-core:86949] [Bug #14744]
Reported by Eregon (Benoit Daloze). Thanks!
|
|
|
|
|
|
The emoji data in emoji-variation-sequences.txt was not used for
in test/ruby/enc/test_emoji_breaks.rb, for unknown reasons.
It turned out that the format of each of the emoji data/test files
is slightly different, and that we didn't take into account that
empty fields after a semicolon, as present in
emoji-variation-sequences.txt, led to less fields than expected
when using split.
This addresses issue #18027.
|
|
[0] => [0, *, a]
#=> [0] length mismatch (given 1, expected 2+) (NoMatchingPatternError)
Ignore test failures of typeprof caused by this change for now.
|
|
events get enabled
|
|
|
|
|
|
|
|
`TracePoint.stat` returns the "to be deleted" TP numbers, and
http://rubyci.s3.amazonaws.com/graviton2/ruby-master/log/20210810T030003Z.fail.html.gz
shows there is a "to be deleted" TP.
This patch uses only :line event and add some lines to allow MRI
deletes "to be deleted" TPs.
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4727
|
|
ndigits higher than 14 can result in values that are slightly too
large due to floating point limitations. Converting to rational
for the calculation and then back to float fixes these issues.
Fixes [Bug #14635]
Fixes [Bug #17183]
Co-authored by: Yusuke Endoh <mame@ruby-lang.org>
Notes:
Merged: https://github.com/ruby/ruby/pull/4682
|
|
This fixes multiple bugs found in the partial backtrace
optimization added in 3b24b7914c16930bfadc89d6aff6326a51c54295.
These bugs occurs when passing a start argument to caller where
the start argument lands on a iseq frame without a pc.
Before this commit, the following code results in the same
line being printed twice, both for the #each method.
```ruby
def a; [1].group_by { b } end
def b; puts(caller(2, 1).first, caller(3, 1).first) end
a
```
After this commit and in Ruby 2.7, the lines are different,
with the first line being for each and the second for group_by.
Before this commit, the following code can either segfault or
result in an infinite loop:
```ruby
def foo
caller_locations(2, 1).inspect # segfault
caller_locations(2, 1)[0].path # infinite loop
end
1.times.map { 1.times.map { foo } }
```
After this commit, this code works correctly.
This commit completely refactors the backtrace handling.
Instead of processing the backtrace from the outermost
frame working in, process it from the innermost frame
working out. This is much faster for partial backtraces,
since you only access the control frames you need to in
order to construct the backtrace.
To handle cfunc frames in the new design, they start
out with no location information. We increment a counter
for each cfunc frame added. When an iseq frame with pc
is accessed, after adding the iseq backtrace location,
we use the location for the iseq backtrace location for
all of the directly preceding cfunc backtrace locations.
If the last backtrace line is a cfunc frame, we continue
scanning for iseq frames until the end control frame, and
use the location information from the first one for the
trailing cfunc frames in the backtrace.
As only rb_ec_partial_backtrace_object uses the new
backtrace implementation, remove all of the function
pointers and inline the functions. This makes the
process easier to understand.
Restore the Ruby 2.7 implementation of backtrace_each and
use it for all the other functions that called
backtrace_each other than rb_ec_partial_backtrace_object.
All other cases requested the entire backtrace, so there
is no advantage of using the new algorithm for those.
Additionally, there are implicit assumptions in the other
code that the backtrace processing works inward instead
of outward.
Remove the cfunc/iseq union in rb_backtrace_location_t,
and remove the prev_loc member for cfunc. Both cfunc and
iseq types can now have iseq and pc entries, so the
location information can be accessed the same way for each.
This avoids the need for a extra backtrace location entry
to store an iseq backtrace location if the final entry in
the backtrace is a cfunc. This is also what fixes the
segfault and infinite loop issues in the above bugs.
Here's Ruby pseudocode for the new algorithm, where start
and length are the arguments to caller or caller_locations:
```ruby
end_cf = VM.end_control_frame.next
cf = VM.start_control_frame
size = VM.num_control_frames - 2
bt = []
cfunc_counter = 0
if length.nil? || length > size
length = size
end
while cf != end_cf && bt.size != length
if cf.iseq?
if cf.instruction_pointer?
if start > 0
start -= 1
else
bt << cf.iseq_backtrace_entry
cf_counter.times do |i|
bt[-1 - i].loc = cf.loc
end
cfunc_counter = 0
end
end
elsif cf.cfunc?
if start > 0
start -= 1
else
bt << cf.cfunc_backtrace_entry
cfunc_counter += 1
end
end
cf = cf.prev
end
if cfunc_counter > 0
while cf != end_cf
if (cf.iseq? && cf.instruction_pointer?)
cf_counter.times do |i|
bt[-i].loc = cf.loc
end
end
cf = cf.prev
end
end
```
With the following benchmark, which uses a call depth of
around 100 (common in many Ruby applications):
```ruby
class T
def test(depth, &block)
if depth == 0
yield self
else
test(depth - 1, &block)
end
end
def array
Array.new
end
def first
caller_locations(1, 1)
end
def full
caller_locations
end
end
t = T.new
t.test((ARGV.first || 100).to_i) do
Benchmark.ips do |x|
x.report ('caller_loc(1, 1)') {t.first}
x.report ('caller_loc') {t.full}
x.report ('Array.new') {t.array}
x.compare!
end
end
```
Results before commit:
```
Calculating -------------------------------------
caller_loc(1, 1) 281.159k (_ 0.7%) i/s - 1.426M in 5.073055s
caller_loc 15.836k (_ 2.1%) i/s - 79.450k in 5.019426s
Array.new 1.852M (_ 2.5%) i/s - 9.296M in 5.022511s
Comparison:
Array.new: 1852297.5 i/s
caller_loc(1, 1): 281159.1 i/s - 6.59x (_ 0.00) slower
caller_loc: 15835.9 i/s - 116.97x (_ 0.00) slower
```
Results after commit:
```
Calculating -------------------------------------
caller_loc(1, 1) 562.286k (_ 0.8%) i/s - 2.858M in 5.083249s
caller_loc 16.402k (_ 1.0%) i/s - 83.200k in 5.072963s
Array.new 1.853M (_ 0.1%) i/s - 9.278M in 5.007523s
Comparison:
Array.new: 1852776.5 i/s
caller_loc(1, 1): 562285.6 i/s - 3.30x (_ 0.00) slower
caller_loc: 16402.3 i/s - 112.96x (_ 0.00) slower
```
This shows that the speed of caller_locations(1, 1) has roughly
doubled, and the speed of caller_locations with no arguments
has improved slightly. So this new algorithm is significant faster,
much simpler, and fixes bugs in the previous algorithm.
Fixes [Bug #18053]
Notes:
Merged: https://github.com/ruby/ruby/pull/4671
|
|
The test disables GC but never reenables it. Before this patch, running
all tests would have a peak RSS in the main process of >4GB. After this
patch, peak RSS in the main process is <500MB.
Notes:
Merged: https://github.com/ruby/ruby/pull/4707
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4705
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4697
|
|
This test appears to cause failures in some environments.
|
|
This speeds up performance by multiple orders of magnitude for
large integers.
Fixes [Bug #14391]
Co-authored-by: tompng (tomoya ishida) <tomoyapenguin@gmail.com>
Notes:
Merged: https://github.com/ruby/ruby/pull/4584
|
|
This changes Thread::Location::Backtrace#absolute_path to return
nil for methods/procs defined in eval. If the realpath of an iseq
is nil, that indicates it was defined in eval, in which case you
cannot use RubyVM::AbstractSyntaxTree.of.
Fixes [Bug #16983]
Co-authored-by: Koichi Sasada <ko1@atdot.net>
Notes:
Merged: https://github.com/ruby/ruby/pull/4519
|
|
This fixes cases where exceptions raised using Thread#raise are
swallowed by finalizers and not delivered to the running thread.
This could cause issues with finalizers that rely on pending interrupts,
but that case is expected to be rarer.
Fixes [Bug #13876]
Fixes [Bug #15507]
Co-authored-by: Koichi Sasada <ko1@atdot.net>
Notes:
Merged: https://github.com/ruby/ruby/pull/4366
|
|
`vm_opt_method_table` is me=>bop table to manage the optimized
methods (by specialized instruction). However, `me` can be invalidated
to invalidate the method cache entry.
[Bug #17725]
To solve the issue, use `me-def` instead of `me` which simply copied
at invalidation timing.
A test by @jeremyevans https://github.com/ruby/ruby/pull/4376
Notes:
Merged: https://github.com/ruby/ruby/pull/4493
|
|
Solaris 11 CI times out instead of raising NoMemoryError for large
allocations, so it cannot test ensure after NoMemoryError.
|
|
|
|
The previous implementation could result in a returned
float that is 1/(10**ndigits) too low. First try adding
one before dividing, and if that results in a value that is
greater than the initial number, then try the original
calculation.
Spec added for ciel, but the issue doesn't appear to affect
ciel, at least not for the same number. If the issue does
effect ciel, a similar fix could probably work for it.
Fixes [Bug #18018]
Notes:
Merged: https://github.com/ruby/ruby/pull/4681
|
|
VM patch from wanabe.
Test based on example from buzztaiki (Taiki Sugawara).
Test fails when compiles with -DRUBY_DEBUG, as that can
can use rb_bug instead of NoMemoryError, which doesn't
allow testing this case. Test also fails on MingW, as
RangeError is used instead of NoMemoryError. Skip the
test in either case.
Fixes [Bug #15779]
Notes:
Merged: https://github.com/ruby/ruby/pull/4577
|
|
Detect Unicode ranges and loop over them.
This fixes issue #18028.
|
|
Deal with the issue that the emoji files in emoji/13.1 have Unicode
Emoji version 13.1, but at the same time the files in 13.0.0/ucd/emoji
are still at Emoji version 13.0. Specifically:
- Add a version attribute to TestEmojiBreaks::BreakFile
- Take the version for emoji-variant-sequences.txt from the Unicode
version, removing the last two characters.
- Improve information in exceptions for file name and version mismatches.
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4685
Merged-By: nobu <nobu@ruby-lang.org>
|
|
|
|
|
|
Consume the VM stack more, to make the target object get GCed with
more probability during suppressing the warning.
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4256
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4670
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4670
|
|
This fixes https://bugs.ruby-lang.org/issues/18038. The provided
reproduction showed that this happens in heredocs with double
interpolation. In this case `DSTR` was getting returned but needs to be
convered to a `EVSTR` which is what is returned by the function. There
may be an additional bug here that we weren't able to produce. It seems
odd that `STR` returns `DSTR` while everything else should return
`EVSTR` since the function is `new_evstr`.
[Bug #18038][ruby-core:104597]
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
Notes:
Merged: https://github.com/ruby/ruby/pull/4664
|
|
https://github.com/ruby/dev-meeting-log/blob/master/DevelopersMeeting20210715Japan.md#feature-17724-make-the-pin-operator-support-instanceclassglobal-variables-jeremyevans0
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4654
|
|
This makes the compare_by_identity setting always copied
for the following methods:
* except
* merge
* reject
* select
* slice
* transform_values
Some of these methods did not copy the setting, or only
copied the setting if the receiver was not empty.
Fixes [Bug #17757]
Co-authored-by: Kenichi Kamiya <kachick1@gmail.com>
Notes:
Merged: https://github.com/ruby/ruby/pull/4616
Merged-By: jeremyevans <code@jeremyevans.net>
|
|
Pin matching for local variables and constants is already supported,
and it is fairly simple to add support for these variable types.
Note that pin matching for method calls is still not supported
without wrapping in parentheses (pin expressions). I think that's
for the best as method calls are far more complex (arguments/blocks).
Implements [Feature #17724]
Notes:
Merged: https://github.com/ruby/ruby/pull/4502
|