summaryrefslogtreecommitdiff
path: root/test/ruby
AgeCommit message (Collapse)Author
2024-08-03Extend timeout in test/ruby/test_file_exhaustive.rbYusuke Endoh
Notes: Merged: https://github.com/ruby/ruby/pull/11307
2024-08-03Reduce noise in object generation count testsYusuke Endoh
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
2024-08-03Show where objects were allocated on allocation count testsYusuke Endoh
Notes: Merged: https://github.com/ruby/ruby/pull/11297
2024-08-02Show what objects were actually allocated on allocation count testsYusuke Endoh
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
2024-07-30Move incorrectly placed testsPeter Zhu
The tests for Integer#ceil was accidentally placed in test_truncate.
2024-07-30Fix ceil when ndigits is largePeter Zhu
[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
2024-07-30Fix floor when ndigits is largePeter Zhu
[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
2024-07-30Fix wrong unreachable chunk remove when jump destination label is unremovabletomoya ishida
Notes: Merged: https://github.com/ruby/ruby/pull/11267 Merged-By: nobu <nobu@ruby-lang.org>
2024-07-30Add array test cases for `TestParse#test_define_singleton_error`yui-knk
Notes: Merged: https://github.com/ruby/ruby/pull/11276
2024-07-29Revert moving things to RubyAaron Patterson
This is slowing down benchmarks on x86, so lets revert it for now. Notes: Merged: https://github.com/ruby/ruby/pull/11275
2024-07-29Expand opt_newarray_send to support Array#pack with buffer keyword argRandy Stauner
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
2024-07-26Fix memory leak in String#start_with? when regexp times outPeter Zhu
[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
2024-07-25Fix test_kwarg_eval_memory_leakPeter Zhu
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
2024-07-25Fix memory leak in Regexp capture group when timeoutPeter Zhu
[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
2024-07-25Omit TestFile#test_stat when the machine is stupidly slowYusuke Endoh
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
2024-07-24[Bug #20647] Disallow `return` directly within a singleton classNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/11234
2024-07-23Implement UNLESS NODE keyword locationsyui-knk
Notes: Merged: https://github.com/ruby/ruby/pull/11227
2024-07-23[Feature #20624] Enhance `RubyVM::AbstractSyntaxTree::Node#locations`yui-knk
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
2024-07-21Fix a typo in setup of block-after-blockcall testsNobuyoshi Nakada
Unparenthesize the argument and make `command_call` when calling with `do`-block. Notes: Merged: https://github.com/ruby/ruby/pull/11216
2024-07-21Fix SEGV on method call with empty args and brace block for do block command ↵yui-knk
call Notes: Merged: https://github.com/ruby/ruby/pull/11215
2024-07-20Do not set Enumerator::Lazy#zip to use packed formatJeremy Evans
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
2024-07-18Avoid array allocation for f(*r2k_ary) when def f(x)Jeremy Evans
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
2024-07-18Avoid hash allocation for f(*r2k_ary) when def f(kw: 1)Jeremy Evans
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
2024-07-18Check for and remove duplicate checks in test_allocationJeremy Evans
Notes: Merged: https://github.com/ruby/ruby/pull/11161
2024-07-18Avoid array allocation for f(*empty_ary, **hash) when def f(x)Jeremy Evans
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
2024-07-18Avoid unnecessary array allocations for f(arg, *arg, **arg, **arg), f(*arg, ↵Jeremy Evans
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
2024-07-18[PRISM] Refactor parser support into its own moduleKevin Newton
Notes: Merged: https://github.com/ruby/ruby/pull/11201
2024-07-18Refactor RUBY_DESCRIPTION assertions in test_rubyoptionsKevin Newton
Notes: Merged: https://github.com/ruby/ruby/pull/11192
2024-07-17Report a TracePoint log when the TracePoint tests failYusuke Endoh
Notes: Merged: https://github.com/ruby/ruby/pull/11184
2024-07-16[PRISM] Omit two more ast tests that will not work without RubyVM::AstKevin Newton
2024-07-16Add MatchData#bytebegin and MatchData#byteendShugo Maeda
These methods return the byte-based offset of the beginning or end of the specified match. [Feature #20576]
2024-07-12Rename full_mark -> rgengc_allow_full_markMatt Valentine-House
2024-07-12Provide GC.config to disable major GC collectionsMatt Valentine-House
This feature provides a new method `GC.config` that configures internal GC configuration variables provided by an individual GC implementation. Implemented in this PR is the option `full_mark`: a boolean value that will determine whether the Ruby GC is allowed to run a major collection while the process is running. It has the following semantics This feature configures Ruby's GC to only run minor GC's. It's designed to give users relying on Out of Band GC complete control over when a major GC is run. Configuring `full_mark: false` does two main things: * Never runs a Major GC. When the heap runs out of space during a minor and when a major would traditionally be run, instead we allocate more heap pages, and mark objspace as needing a major GC. * Don't increment object ages. We don't promote objects during GC, this will cause every object to be scanned on every minor. This is an intentional trade-off between minor GC's doing more work every time, and potentially promoting objects that will then never be GC'd. The intention behind not aging objects is that users of this feature should use a preforking web server, or some other method of pre-warming the oldgen (like Nakayoshi fork)before disabling Majors. That way most objects that are going to be old will have already been promoted. This will interleave major and minor GC collections in exactly the same what that the Ruby GC runs in versions previously to this. This is the default behaviour. * This new method has the following extra semantics: - `GC.config` with no arguments returns a hash of the keys of the currently configured GC - `GC.config` with a key pair (eg. `GC.config(full_mark: true)` sets the matching config key to the corresponding value and returns the entire known config hash, including the new values. If the key does not exist, `nil` is returned * When a minor GC is run, Ruby sets an internal status flag to determine whether the next GC will be a major or a minor. When `full_mark: false` this flag is ignored and every GC will be a minor. This status flag can be accessed at `GC.latest_gc_info(:needs_major_by)`. Any value other than `nil` means that the next collection would have been a major. Thus it's possible to use this feature to check at a predetermined time, whether a major GC is necessary and run one if it is. eg. After a request has finished processing. ```ruby if GC.latest_gc_info(:needs_major_by) GC.start(full_mark: true) end ``` [Feature #20443]
2024-07-12Pend some tests because these are not working with macOS 15 beta and Xcode ↵Hiroshi SHIBATA
16 beta
2024-07-11IBM864 single-byte transcoding (#10518)Jeremy Daer
Include € euro sign from CCSID 864
2024-07-11Enumerable#all?: Stop optimizing when a given block is not optimizableYusuke Endoh
This is a follow up to 182822683f86c8f8d63b05765addf5a04d112aa2. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
2024-07-10Avoid a hash allocation when keyword splatting empty hash when calling ↵Jeremy Evans
ruby2_keywords method Treat this similar to keyword splatting nil, using goto ignore. However, keep previous behavior if the method accepts a keyword splat, to avoid double hash allocation. This also can avoid an array allocation when calling a method that doesn't have any splat parameters but supports literal keyword parameters, because ignore_keyword_hash_p was not ignoring the keyword hash in that case. This change doesn't remove the empty ruby2_keywords hash from the array, which caused an assertion failure if the method being called accepted keywords in some cases. Modify the assertion to handle this case. An alternative approach would add a flag to the args struct so the args_argc calculation could handle this case and report the correct argc, but such an approach would likely be slower.
2024-07-10Eliminate array allocations for single splat followed by mutable keywordsJeremy Evans
For calls such as: m(*ary, a: 2, **h) m(*ary, **h, **h, **h) Where m does not take a positional argument splat, there was previously an array allocation (splatarray true) to dup ary, even though it was not necessary to do so. This is because the elimination of the array allocation (splatarray false) was performed in the optimizer, and the optimizer didn't handle this case, because the instructions for the keywords can be of arbitrary length. Move part of the optimization from the optimizer to the compiler, detecting parse trees of the form: ARGS_PUSH: head: SPLAT tail: HASH (without brace) And using splatarray false instead of splatarray true for them. Unfortunately, moving part of the optimization to the compiler broke the hash allocation elimination optimization for calls of the form: m(*ary, a: 2) That's because the compiler had already set splatarray false, and the optimizer code was looking for splatarray true. Split the array allocation elimination and hash allocation elimination in the optimizer so that the hash allocation elimination will still apply if the compiler performs the splatarray false optimization.
2024-07-05Fix flaky test_stat_heap_allPeter Zhu
We only collect GC.stat_heap(nil, stat_heap_all) once, outside of the loop, but assert_equal could allocate objects which can cause a GC to run and cause stat_heap_all to be out-of-sync.
2024-07-04Fix the return value of `Integer#downto` called with a blockNobuyoshi Nakada
As the document states, it should return `self`, not `nil`. Fix up of f4b313f7338f5fbe37f73aae29f70aeb474f7f5b.
2024-07-03Move Array#map to RubyAaron Patterson
Improves activerecord by about 1% on the interpreter: ``` before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b8f3) [arm64-darwin23] after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4eb32) [arm64-darwin23] ------------ ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after activerecord 235.2 0.8 233.6 0.7 1.01 1.01 ------------ ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. ``` Improves YJIT by about 4%: ``` before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b8f3) +YJIT [arm64-darwin23] after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4eb32) +YJIT [arm64-darwin23] ------------ ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after activerecord 142.1 1.2 137.0 0.6 1.00 1.04 ------------ ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. ```
2024-07-03array.c: Remove outdated assertionsJean Boussier
Following [Feature #20589] it can happen that we change the capacity of a frozen array, so these assertions no longer make sense. Normally we don't hit them because `Array#freeze` shrinks the array, but if somehow the Array was frozen using `Object#freeze` then we may shrink it after it was frozen.
2024-07-03[Feature #20470] Split GC into gc_impl.cPeter Zhu
This commit splits gc.c into two files: - gc.c now only contains code not specific to Ruby GC. This includes code to mark objects (which the GC implementation may choose not to use) and wrappers for internal APIs that the implementation may need to use (e.g. locking the VM). - gc_impl.c now contains the implementation of Ruby's GC. This includes marking, sweeping, compaction, and statistics. Most importantly, gc_impl.c only uses public APIs in Ruby and a limited set of functions exposed in gc.c. This allows us to build gc_impl.c independently of Ruby and plug Ruby's GC into itself.
2024-07-02Add regression test for mutating pack's format stringAaron Patterson
It doesn't look like there was a test added for this bug, so I'm adding it. Code is from here: https://web.archive.org/web/20160908192307/http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/24445
2024-06-27Fix corruption of internal encoding stringPeter Zhu
[Bug #20598] Just like [Bug #20595], Encoding#name_list and Encoding#aliases can have their strings corrupted when Encoding.default_internal is set to nil. Co-authored-by: Matthew Valentine-House <matt@eightbitraptor.com>
2024-06-27Fix corruption of encoding name stringPeter Zhu
[Bug #20595] enc_set_default_encoding will free the C string if the encoding is nil, but the C string can be used by the encoding name string. This will cause the encoding name string to be corrupted. Consider the following code: Encoding.default_internal = Encoding::ASCII_8BIT names = Encoding.default_internal.names p names Encoding.default_internal = nil p names It outputs: ["ASCII-8BIT", "BINARY", "internal"] ["ASCII-8BIT", "BINARY", "\x00\x00\x00\x00\x00\x00\x00\x00"] Co-authored-by: Matthew Valentine-House <matt@eightbitraptor.com>
2024-06-25Move to test/.excludes-prismNobuyoshi Nakada
2024-06-25Pending `EVENT_RETURN` settracefunc tests with PrismNobuyoshi Nakada
2024-06-25[Bug #20457] Do not remove final `return` nodeNobuyoshi Nakada
This was an optimization for versions prior to 1.9 that traverse the AST at runtime.
2024-06-24Handle hash and splat nodes in defined?Jeremy Evans
This supports the nodes in both in the parse.y and prism compilers. Fixes [Bug #20043] Co-authored-by: Kevin Newton <kddnewton@gmail.com>