| Age | Commit message (Collapse) | Author |
|
|
|
|
|
`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
|
|
|
|
|
|
For a73f13c9070a5189947641638398cbffb8d012d8.
|
|
- Add UNICODE_VERSION,... to deal with new location of some
of the emoji-related data files.
- Introduce class BreakFile to handle various file properties.
- Adapt main code to use BreakFile.
|
|
|
|
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4617
|
|
In ISO-2022-JP, the bytes use to code are the same as those for "<>".
This adds regression tests to make sure that these bytes, when representing
湿, are NOT escaped with encode("ISO-2022-JP, xml: :text) or similar.
These are additional regression tests for #12052.
|
|
|
|
|
|
Before this commit, const_get with inherit=true and constant lookup
expressions searched the ancestors of the starting point in an order
different from `starting_point.ancestors`.
Items in the ancestry list introduced through prepend were searched
after searching the module they were prepended into. This oddity allowed
for situations where constant lookups gave different results even though
`starting_point.ancestors` is the same.
Do the lookup in the same order as `starting_point.ancestors` by
skipping classes and modules that have an origin iclass. The origin
iclass is in the super chain after the prepended modules.
Note that just like before this commit, the starting point of the
constant lookup is always the first item that we search, regardless of
the presence of any prepended modules.
[Bug #17887]
Notes:
Merged: https://github.com/ruby/ruby/pull/4585
|
|
```
$ ./local/bin/ruby -e '1.time {}'
-e:1:in `<main>': undefined method `time' for 1:Integer (NoMethodError)
1.time {}
^^^^^
Did you mean? times
```
https://bugs.ruby-lang.org/issues/17930
Notes:
Merged: https://github.com/ruby/ruby/pull/4586
|
|
|
|
|
|
xml escaping
When using a non-ASCII compatible source and destination encoding
and xml escaping (the :xml option to String#encode), the resulting
string was broken, as it used the correct non-ASCII compatible
encoding, but contained data that was ASCII-compatible instead of
compatible with the string's encoding.
Work around this issue by detecting the case where both the
source and destination encoding are non-ASCII compatible, and
transcoding the source string from the non-ASCII compatible
encoding to UTF-8. The xml escaping code will correctly handle
the UTF-8 source string and the return the correctly encoded
and escaped value.
Fixes [Bug #12052]
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Notes:
Merged: https://github.com/ruby/ruby/pull/4605
Merged-By: jeremyevans <code@jeremyevans.net>
|
|
The shift was causing far fewer unique values of hash than expected.
Fix pointed out by xtkoba (Tee KOBAYASHI)
Fixes [Bug #17951]
Notes:
Merged: https://github.com/ruby/ruby/pull/4574
|
|
This was already documented as being ignored, but it wasn't being
ignored, causing an issue in a particular case where a UTF-8
pattern was provided and a filename was tested that wasn't valid
UTF-8.
Fixes [Bug #14456]
Notes:
Merged: https://github.com/ruby/ruby/pull/4583
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4592
|