summaryrefslogtreecommitdiff
path: root/test/ruby
AgeCommit message (Collapse)Author
2024-06-24Fix `--debug-frozen-string-literal` to not apply ↵Jean Boussier
`--disable-frozen-string-literal` [Feature #20205] This was an undesired side effect. Now that this value is a triplet, we can't assume it's disabled by default.
2024-06-24Introduce retry to the setup of test files with TestFile#test_statYusuke Endoh
GitHub Actions macos-arm-oss is often too slow and does not timestamp as expected.
2024-06-24Extend the timeout of TestVMDump#test_darwin_invalid_call, etc.Yusuke Endoh
2024-06-21Apply EnvUtil.apply_timeout_scale for TestFile#test_statYusuke Endoh
... to respect RUBY_TEST_TIMEOUT_SCALE. This test somehow fails frequently on macos-arm-oss with --repeat-count=2 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
2024-06-20[PRISM] Remove duplicated testsKevin Newton
These tests are flaky and are duplicative of other tests that are run in CI when parser=prism.
2024-06-18Fix flaky TestWeakMap#test_inspect_garbagePeter Zhu
If a GC is ran before the assert_match, then the WeakMap would be empty and would not have any objects, so the regular expression match would fail. This changes the regular expression to work even if the WeakMap is empty.
2024-06-18fix allocation assertionsAaron Patterson
2024-06-18Optimized forwarding callers and calleesAaron Patterson
This patch optimizes forwarding callers and callees. It only optimizes methods that only take `...` as their parameter, and then pass `...` to other calls. Calls it optimizes look like this: ```ruby def bar(a) = a def foo(...) = bar(...) # optimized foo(123) ``` ```ruby def bar(a) = a def foo(...) = bar(1, 2, ...) # optimized foo(123) ``` ```ruby def bar(*a) = a def foo(...) list = [1, 2] bar(*list, ...) # optimized end foo(123) ``` All variants of the above but using `super` are also optimized, including a bare super like this: ```ruby def foo(...) super end ``` This patch eliminates intermediate allocations made when calling methods that accept `...`. We can observe allocation elimination like this: ```ruby def m x = GC.stat(:total_allocated_objects) yield GC.stat(:total_allocated_objects) - x end def bar(a) = a def foo(...) = bar(...) def test m { foo(123) } end test p test # allocates 1 object on master, but 0 objects with this patch ``` ```ruby def bar(a, b:) = a + b def foo(...) = bar(...) def test m { foo(1, b: 2) } end test p test # allocates 2 objects on master, but 0 objects with this patch ``` How does it work? ----------------- This patch works by using a dynamic stack size when passing forwarded parameters to callees. The caller's info object (known as the "CI") contains the stack size of the parameters, so we pass the CI object itself as a parameter to the callee. When forwarding parameters, the forwarding ISeq uses the caller's CI to determine how much stack to copy, then copies the caller's stack before calling the callee. The CI at the forwarded call site is adjusted using information from the caller's CI. I think this description is kind of confusing, so let's walk through an example with code. ```ruby def delegatee(a, b) = a + b def delegator(...) delegatee(...) # CI2 (FORWARDING) end def caller delegator(1, 2) # CI1 (argc: 2) end ``` Before we call the delegator method, the stack looks like this: ``` Executing Line | Code | Stack ---------------+---------------------------------------+-------- 1| def delegatee(a, b) = a + b | self 2| | 1 3| def delegator(...) | 2 4| # | 5| delegatee(...) # CI2 (FORWARDING) | 6| end | 7| | 8| def caller | -> 9| delegator(1, 2) # CI1 (argc: 2) | 10| end | ``` The ISeq for `delegator` is tagged as "forwardable", so when `caller` calls in to `delegator`, it writes `CI1` on to the stack as a local variable for the `delegator` method. The `delegator` method has a special local called `...` that holds the caller's CI object. Here is the ISeq disasm fo `delegator`: ``` == disasm: #<ISeq:delegator@-e:1 (1,0)-(1,39)> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] "..."@0 0000 putself ( 1)[LiCa] 0001 getlocal_WC_0 "..."@0 0003 send <calldata!mid:delegatee, argc:0, FCALL|FORWARDING>, nil 0006 leave [Re] ``` The local called `...` will contain the caller's CI: CI1. Here is the stack when we enter `delegator`: ``` Executing Line | Code | Stack ---------------+---------------------------------------+-------- 1| def delegatee(a, b) = a + b | self 2| | 1 3| def delegator(...) | 2 -> 4| # | CI1 (argc: 2) 5| delegatee(...) # CI2 (FORWARDING) | cref_or_me 6| end | specval 7| | type 8| def caller | 9| delegator(1, 2) # CI1 (argc: 2) | 10| end | ``` The CI at `delegatee` on line 5 is tagged as "FORWARDING", so it knows to memcopy the caller's stack before calling `delegatee`. In this case, it will memcopy self, 1, and 2 to the stack before calling `delegatee`. It knows how much memory to copy from the caller because `CI1` contains stack size information (argc: 2). Before executing the `send` instruction, we push `...` on the stack. The `send` instruction pops `...`, and because it is tagged with `FORWARDING`, it knows to memcopy (using the information in the CI it just popped): ``` == disasm: #<ISeq:delegator@-e:1 (1,0)-(1,39)> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] "..."@0 0000 putself ( 1)[LiCa] 0001 getlocal_WC_0 "..."@0 0003 send <calldata!mid:delegatee, argc:0, FCALL|FORWARDING>, nil 0006 leave [Re] ``` Instruction 001 puts the caller's CI on the stack. `send` is tagged with FORWARDING, so it reads the CI and _copies_ the callers stack to this stack: ``` Executing Line | Code | Stack ---------------+---------------------------------------+-------- 1| def delegatee(a, b) = a + b | self 2| | 1 3| def delegator(...) | 2 4| # | CI1 (argc: 2) -> 5| delegatee(...) # CI2 (FORWARDING) | cref_or_me 6| end | specval 7| | type 8| def caller | self 9| delegator(1, 2) # CI1 (argc: 2) | 1 10| end | 2 ``` The "FORWARDING" call site combines information from CI1 with CI2 in order to support passing other values in addition to the `...` value, as well as perfectly forward splat args, kwargs, etc. Since we're able to copy the stack from `caller` in to `delegator`'s stack, we can avoid allocating objects. I want to do this to eliminate object allocations for delegate methods. My long term goal is to implement `Class#new` in Ruby and it uses `...`. I was able to implement `Class#new` in Ruby [here](https://github.com/ruby/ruby/pull/9289). If we adopt the technique in this patch, then we can optimize allocating objects that take keyword parameters for `initialize`. For example, this code will allocate 2 objects: one for `SomeObject`, and one for the kwargs: ```ruby SomeObject.new(foo: 1) ``` If we combine this technique, plus implement `Class#new` in Ruby, then we can reduce allocations for this common operation. Co-Authored-By: John Hawthorn <john@hawthorn.email> Co-Authored-By: Alan Wu <XrXr@users.noreply.github.com>
2024-06-13clear `kw_flag` if given hash is nilKoichi Sasada
https://bugs.ruby-lang.org/issues/20570 is caused I missed to clear the `kw_flag` even if `keyword_hash` is nil.
2024-06-12Add regression test for Bug #20573Aaron Patterson
Just a regression test to ensure behavior remains the same
2024-06-12[Bug #20572] Abandon if replacing destination is the sameNobuyoshi Nakada
2024-06-11compile.c: use putspecialobject for RubyVM::FrozenCoreJean Boussier
[Bug #20569] `putobject RubyVM::FrozenCore`, is not serializable, we have to use `putspecialobject VM_SPECIAL_OBJECT_VMCORE`.
2024-06-10Don't skip test_inspect_under_gc_compact_stressPeter Zhu
Commit 1471a16 seems to have fixed this flaky test, so we don't need to skip it for YJIT or RJIT anymore.
2024-06-07Remove prism compiler warningKevin Newton
2024-06-07Don't use SEGV signal when timeout in test_gc_compactPeter Zhu
Using a SEGV signal for timeout makes it difficult to tell if it's a real SEGV or if it timed out, so we should just use the default signals.
2024-06-07TestRequire#test_loading_fifo_threading_success: Extend the timeout limitYusuke Endoh
2024-06-07TestRegexp#test_match_cache_positive_look_behind: Extend the timeout limitYusuke Endoh
2024-06-07TestRegexp#test_timeout_shorter_than_global: Extend the timeout limitYusuke Endoh
2024-06-07TestRequire#test_loading_fifo_fd_leak: Extend the timeout limitYusuke Endoh
2024-06-07TestGc#test_thrashing_for_young_objects: extend the timeout limitYusuke Endoh
2024-06-07TestRegexp#test_s_timeout: accept timeout errors more tolerantlyYusuke Endoh
This test seems flaky on macOS GitHub Actions
2024-06-07Extend timeout of TestGCCompect#test_moving_objects_between_size_poolsYusuke Endoh
It is too flaky on macOS GitHub Actions
2024-06-06Fix Module#define_method to change visibility when passed existing method bodyJeremy Evans
Fixes [Bug #19749]
2024-06-06Remove circular parameter syntax errorKevin Newton
https://bugs.ruby-lang.org/issues/20478
2024-06-05Don't add `+YJIT` to `RUBY_DESCRIPTION` until it's actually enabledJean Boussier
If you start Ruby with `--yjit-disable`, the `+YJIT` shouldn't be added until `RubyVM::YJIT.enable` is actually called. Otherwise it's confusing in crash reports etc.
2024-06-04Remove dependency on fiddle from test/rubyHiroshi SHIBATA
Co-authored-by: "Nobuyoshi Nakada" <nobu@ruby-lang.org>
2024-05-31Make error messages clear blocks/keywords are disallowed in index assignmentJeremy Evans
Blocks and keywords are allowed in regular index. Also update NEWS to make this more clear. Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2024-05-30test_bignum: defined? returns String (#10880)Sorah Fukumori
didn't verify the test is working properly due to mistaken auto-merge… [Bug #20515] bug: https://bugs.ruby-lang.org/issues/20515 follow-up: 22e4eeda6561693367fc7a00b92b90f46b09cabd follow-up: https://github.com/ruby/ruby/pull/10875
2024-05-30ci: Test whether GMP is working in compilers.yml (#10875)Sorah Fukumori
Avoid reoccurence of [Bug #20515] Requires https://github.com/ruby/ruby/pull/10876 since 18eaf0be905e3e251423b42d6f4e56b7cae1bc3b bug: https://bugs.ruby-lang.org/issues/20515
2024-05-28Make ensure first lineno the first line of the ensureKevin Newton
Previously, ensure ISEQs took their first line number from the line number coming from the AST. However, if this is coming from an empty `begin`..`end` inside of a method, this can be all of the way back to the method declaration. Instead, this commit changes it to be the first line number of the ensure block itself. The first_lineno field is only accessible through manual ISEQ compilation or through tracepoint. Either way, this will be more accurate for targeting going forward.
2024-05-29[Bug #20438] Disallow "%\n" and "%\0"Nobuyoshi Nakada
2024-05-28Stop marking chilled strings as frozenÉtienne Barrié
They were initially made frozen to avoid false positives for cases such as: str = str.dup if str.frozen? But this may cause bugs and is generally confusing for users. [Feature #20205] Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2024-05-27Add a debug print for a random failureYusuke Endoh
``` 1) Error: TestRubyLiteral#test_float: ArgumentError: SyntaxError#path changed: "(eval at /home/chkbuild/chkbuild/tmp/build/20240527T050036Z/ruby/test/ruby/test_literal.rb:642)"->"(eval at /home/chkbuild/chkbuild/tmp/build/20240527T050036Z/ruby/test/ruby/test_literal.rb:642)" ``` https://rubyci.s3.amazonaws.com/s390x/ruby-master/log/20240527T050036Z.fail.html.gz
2024-05-26Debug unexpectedly changed pathNobuyoshi Nakada
2024-05-25[Bug #20510] Do not count optional hash argument for `IO.new`Nobuyoshi Nakada
Since `IO.new` accepts one or two positional arguments except for the optional hash argument, exclude the optional hash argument from the check for delegation to `IO.new`.
2024-05-24Update duplicated when clause warning messageKevin Newton
2024-05-23Introduce a specialize instruction for Array#packNobuyoshi Nakada
Instructions for this code: ```ruby # frozen_string_literal: true [a].pack("C") ``` Before this commit: ``` == disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)> 0000 putself ( 3)[Li] 0001 opt_send_without_block <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 newarray 1 0005 putobject "C" 0007 opt_send_without_block <calldata!mid:pack, argc:1, ARGS_SIMPLE> 0009 leave ``` After this commit: ``` == disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)> 0000 putself ( 3)[Li] 0001 opt_send_without_block <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0003 putobject "C" 0005 opt_newarray_send 2, :pack 0008 leave ``` Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2024-05-22[PRISM] Properly support 'it'Kevin Newton
2024-05-21Avoid array allocation for empty ruby2_keywords flagged keyword hashJeremy Evans
If the method being called does not have a positional splat parameter, there is no point in allocating the array, as decrementing given_argc is sufficient to ensure the empty keyword hash is not considered an argument, assuming that we are calling a method/lambda and not a regular proc.
2024-05-21Avoid hash allocation for empty ruby2_keywords flagged keyword hashJeremy Evans
If the method being called does not have a keyword splat parameter, there is no point in allocating the hash, because the hash will be unused (as empty keyword hashes are ignored).
2024-05-21Add allocation tests for ruby2_keywordsJeremy Evans
This tests ruby2_keywords flagged methods, as well as passing ruby2_keywords flagged hashes to other methods. Some of the behavior here is questionable, such as allocating different numbers of objects depending on whether a block is passed or whether YJIT is enabled. I think there are likely ways to eliminate allocations in certain cases. However, this gives us a baseline and shows us where it is possible to make improvements.
2024-05-20[PRISM] Enable TestSyntax#test_warn_balancedKevin Newton
2024-05-16[PRISM] Enable TestParse#test_truncated_source_lineKevin Newton
2024-05-16[PRISM] Enable TestParse#test_stringKevin Newton
2024-05-16[PRISM] Enable TestISeq#test_syntax_error_messageKevin Newton
2024-05-16[PRISM] Enable TestSyntax#test_syntax_error_at_newlineKevin Newton
2024-05-16[Bug #20468] Fix safe navigation in `for` variableNobuyoshi Nakada
2024-05-15[PRISM] Enable TestParse#test_global_variableKevin Newton
2024-05-15[PRISM] Enable test_location_of_invalid_tokenKevin Newton
2024-05-15[PRISM] Enable TestParse#test_unexpected_eofKevin Newton